subroutine aptripr (ab, bc, ca, tol, elen, da, db, dc, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTRIPR c c call aptripr (ab, bc, ca, tol, elen, da, db, dc, nerr) c c Version: aptripr Updated 2001 April 10 14:45. c aptripr Originated 2001 April 2 15:30. c c Author: Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123. c c Source: On the Compass Cluster EAST machine, in ~edwards/work/apt. c c Purpose: Given the edge lengths ab, bc and ca of triangle abc, c to find the edge length elen of an equilateral triangle with c vertices projected from vertices a, b and c, in the direction c normal to the plane of triangle abc, and to find the distances c da, db and dc of those vertices from vertices a, b and c. c Flag nerr indicates any input errors. c c Input: ab, bc, ca, tol. c c Output: elen, da, db, dc, nerr. c c Calls: aptrich c c Glossary: c c ab Input The length of edge ab of triangle abc. c c bc Input The length of edge bc of triangle abc. c c ca Input The length of edge ca of triangle abc. c c da Output The distance from vertex A to the corresponding vertex c of the equilateral triangle. c c db Output The distance from vertex B to the corresponding vertex c of the equilateral triangle c (arbitrarily set at zero). c c dc Output The distance from vertex C to the corresponding vertex c of the equilateral triangle. c c elen Output The length of the edges of the equilateral triangle. c c nerr Output Indicates an input error, if not 0. c 1 if an edge length is not greater than c emin = tol * (abs (ab) + abs (bc) + abs (ca)). c One or more edges are too short, or negative. c 2 if an edge length is not less than c emax = 0.5 * (ab + bc + ca) * (1.0 - tol). c One edge is too long. c c tol Input Numerical tolerance limit. c On computers with 64-bit floating point numbers, c recommend 1.e-5 to 1.e-11. c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccend. c.... Specifications. implicit none intrinsic max intrinsic min c.... Arguments. integer nerr ! Error indicator. real ab, bc, ca ! Length of edges ab, bc, ca of triangle. real da, db, dc ! Distance vertices a, b, c projected. real elen ! Length of edges of equilateral triangle. real tol ! Numerical tolerence limit. c.... Local variables. real arg1, arg2 ! Intermediate. real dab, dbc, dca ! Equal db - da, dc - db, da - cd. real elen2 ! Square of elen. real err2 ! Estimated error in arg2. real edab, edbc, edca ! Estimated errors in dab, dbc, dca. real shift ! Equals min (da, db, dc). real sum1 ! Equals dab + dbc - dca. real sum2 ! Equals dab - dbc + dca. real sum3 ! Equals dab - dbc - dca. cbugc***DEBUG begins. cbug 9901 format (/ 'aptripr finding equilateral projection triangle.', cbug & ' tol=',1pe22.14 / cbug & ' ab,bc,ca = ',1p3e22.14 ) cbug write ( 3, 9901) tol, ab, bc, ca cbugc***DEBUG ends. c.... Initialize. nerr = 0 elen = -1.e99 da = -1.e99 db = -1.e99 dc = -1.e99 c.... Test for impossible triangle (an edge too short or long). call aptrich (ab, bc, ca, tol, nerr) if (nerr .ne. 0) go to 410 c.... Find the equilateral triangle edge length elen. arg1 = ab**2 + bc**2 + ca**2 arg2 = ab**4 + bc**4 + ca**4 - & ab**2 * bc**2 - bc**2 * ca**2 - ca**2 * ab**2 err2 = tol * (ab**4 + bc**4 + ca**4 + & ab**2 * bc**2 + bc**2 * ca**2 + ca**2 * ab**2) if (abs (arg2) .le. err2) arg2 = 0.0 elen2 = (arg1 + 2.0 * sqrt (arg2)) / 3.0 elen = sqrt (elen2) c.... Find the distances between the original and projected vertices. dab = elen2 - ab**2 edab = tol * (elen2 + ab**2) if (abs (dab) .le. edab) dab = 0.0 dab = sqrt (dab) dbc = elen2 - bc**2 edbc = tol * (elen2 + bc**2) if (abs (dbc) .le. edbc) dbc = 0.0 dbc = sqrt (dbc) dca = elen2 - ca**2 edca = tol * (elen2 + ca**2) if (abs (dca) .le. edca) dca = 0.0 dca = sqrt (dca) sum1 = abs (dab + dbc - dca) sum2 = abs (dab - dbc + dca) sum3 = abs (dab - dbc - dca) cbugc***DEBUG begins. cbug 9914 format (' sum1,2,3 = '1p3e22.14 / cbug & ' dab,bc,ca= '1p3e22.14 ) cbug write ( 3, 9914) sum1, sum2, sum3, dab, dbc, dca cbugc***DEBUG ends. c.... Find the correct signs, so that dca + dab + dbc = 0. if ((sum1 .le. sum2) .and. (sum1 .le. sum3)) then dca = -dca elseif ((sum2 .le. sum3) .and. (sum2 .le. sum1)) then dbc = -dbc elseif ((sum3 .le. sum1) .and. (sum3 .le. sum2)) then dbc = -dbc dca = -dca endif cbugc***DEBUG begins. cbug write ( 3, 9914) sum1, sum2, sum3, dab, dbc, dca cbugc***DEBUG ends. da = 0.0 db = dab dc = -dca c.... Make all distances non-negative, with one zero. shift = min (da, db, dc) da = da - shift db = db - shift dc = dc - shift 410 continue cbugc***DEBUG begins. cbug 9916 format (/ 'aptripr results. nerr = ',i2 / cbug & ' elen = '1pe22.14 / cbug & ' da,db,dc = '1p3e22.14 ) cbug write ( 3, 9916) nerr, elen, da, db, dc cbugc***DEBUG ends. return c.... End of subroutine aptripr. (+1 line.) end UCRL-WEB-209832