subroutine aptcinc (ra, au, av, rb, bu, bv, np, tol, & cu, cv, du, dv, nint, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTCINC c c call aptcinc (ra, au, av, rb, bu, bv, np, tol, c & cu, cv, du, dv, nint, nerr) c c Version: aptcinc Updated 1990 November 27 14:00. c aptcinc Originated 1990 March 20 14:40. c c Author: Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123. c c c Purpose: To find, for each of np sets of input data, the points of c intersection c = (cu, cv) and d = (du, dv) of the circle c of radius ra at point a = (au, av) and the circle of radius c rb at point b = (bu, bv), if an intersection occurs. c Flag nint indicates the number of intersection points. c Flag nerr indicates any input error. c c Input: ra, au, av, rb, bu, bv, np, tol. c c Output: cu, cv, du, dv, nint, nerr. c c Calls: aptvdic, aptvadc, aptvplc, aptvuac c c c Glossary: c c au, av Input The u and v coordinates of point "a" at the center c of the circle with radius ra, in the uv plane (2-D). c Size np. c c bu, bv Input The u and v coordinates of point "b" at the center c of the circle with radius rb, in the uv plane (2-D). c Size np. c c cu, cv Output The u and v coordinates of point "c" at an intersection c of the two circles centered at points "a" and "b", if c an intersection occurs (nint = 1 or 2). Size np. c Same as "d" if nint = 1. c Meaningless, but set to "a" if nint = 0 or 3. c c du, dv Output The u and v coordinates of point "d" at an intersection c of the two circles centered at points "a" and "b", if c an intersection occurs (nint = 1 or 2). Size np. c Same as "c" if nint = 1. c Meaningless, but set to "a" if nint = 0 or 3. c c nerr Output Indicates an input error, if not 0. c 1 if np is not positive. c c nint Output Indicates the number of intersection points: c 0 if no intersection occurs. Ignore points "c", "d". c 1 if the circles are tangent at the single point c "c" = "d". c 2 if the circles overlap, intersecting at the two c points "c" and "d". c 3 if the circles are congruent. The intersection c includes each circle. Ignore points "c", "d". c Size np. c c np Input Size of arrays. c c ra Input The radius of the circle centered at point "a". c Size np. The absolute value is used. c c rb Input The radius of the circle centered at point "b". c Size np. The absolute value is used. c c tol Input Numerical tolerance limit. c On Cray computers, recommend 1.e-5 to 1.e-11. c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccend. c.... Dimensioned arguments. c---- Coordinate u of point "a". dimension au (1) c---- Coordinate v of point "a". dimension av (1) c---- Coordinate u of point "b". dimension bu (1) c---- Coordinate v of point "b". dimension bv (1) c---- Coordinate u of point "c". dimension cu (1) c---- Coordinate v of point "c". dimension cv (1) c---- Coordinate u of point "d". dimension du (1) c---- Coordinate v of point "d". dimension dv (1) c---- Number of intersection points. dimension nint (1) c---- Radius of circle at point "a". dimension ra (1) c---- Radius of circle at point "b". dimension rb (1) c.... Local variables. c---- Component u of unit vector along "ab". common /laptcinc/ abu (64) c---- Component v of unit vector along "ab". common /laptcinc/ abv (64) c---- Factor fact1*fact2*fact3*fact4. common /laptcinc/ arg c---- Distance from point "c" to point "d". common /laptcinc/ cd (64) c---- Magnitude of vector "ab". common /laptcinc/ dab (64) c---- Fractional distance of "e" along "ab". common /laptcinc/ dae (64) c---- Estimated error in factor of dae. common /laptcinc/ daerr c---- Coordinate u of midpoint of line "cd". common /laptcinc/ eu (64) c---- Coordinate v of midpoint of line "cd". common /laptcinc/ ev (64) c---- Factor dab + rpr. common /laptcinc/ fact1 c---- Factor dab - rmr. common /laptcinc/ fact2 c---- Factor rpr - dab common /laptcinc/ fact3 c---- Factor rmr + dab. common /laptcinc/ fact4 c---- Estimated error in fact2, 3, 4. common /laptcinc/ ferr c---- A very small number. common /laptcinc/ fuz c---- Component u of vector normal to "ab". common /laptcinc/ hnu (64) c---- Component v of vector normal to "ab". common /laptcinc/ hnv (64) c---- Index in arrays. common /laptcinc/ n c---- First index of subset of data. common /laptcinc/ n1 c---- Last index of subset of data. common /laptcinc/ n2 c---- Index in external array. common /laptcinc/ nn c---- Size of current subset of data. common /laptcinc/ ns c---- Difference abs(rb) - abs(ra). common /laptcinc/ rmr c---- Sum abs(rb) + abs(ra). common /laptcinc/ rpr c---- Length of a vector. common /laptcinc/ vlen (64) cbugc***DEBUG begins. cbug 9901 format (/ 'aptcinc finding the intersections of circles.' / cbug & ' tol=',1pe13.5) cbug 9902 format (' ra,au,av=',1p3e22.14 / ' rb,bu,bv=',1p3e22.14) cbug write (3, 9901) tol cbug write (3, 9902) (ra(n), au(n), av(n), rb(n), bu(n), bv(n), cbug & n = 1, np) cbugc***DEBUG ends. c.... Initialize. c---- A very small number. fuz = 1.e-99 nerr = 0 c.... Test for input errors. if (np .le. 0) then nerr = 1 go to 210 endif n1 = 1 n2 = min (np, 64) 110 ns = n2 - n1 + 1 c.... Find the unit vector "ab" from point "a" to point "b". c.... The magnitude dab may be truncated to zero. call aptvdic (au(n1), av(n1), bu(n1), bv(n1), ns, & tol, abu, abv, dab, nerr) call aptvuac (abu, abv, ns, tol, dab, nerr) c.... Find the unit vector in the uv plane perpendicular to the line "ab". call aptvplc (au(n1), av(n1), bu(n1), bv(n1), ns, tol, & hnu, hnv, vlen, nerr) call aptvuac (hnu, hnv, ns, tol, vlen, nerr) c.... Find the distance between points "c" and "d", and the distance of the c.... midpoint of the line "cd" from point "a". c---- No truncation tests. if (tol .le. 0.0) then c---- Loop over subset of data. do 120 n = 1, ns nn = n + n1 - 1 rpr = abs (rb(nn)) + abs (ra(nn)) rmr = abs (rb(nn)) - abs (ra(nn)) fact1 = dab(n) + rpr fact2 = dab(n) - rmr fact3 = rpr - dab(n) fact4 = rmr + dab(n) arg = fact1 * fact2 * fact3 * fact4 cd(n) = sqrt (amax1 (0.0, arg)) / (dab(n) + fuz) dae(n) = 0.5 * (dab(n)**2 - rpr * rmr) / (dab(n) + fuz) if (arg .gt. 0.0) then nint(nn) = 2 else nint(nn) = 0 endif if (arg .eq. 0.0) then nint(nn) = 1 endif if ((dab(n) .eq. 0.0) .and. & (rmr .le. 0.0) ) then nint(nn) = 3 endif if (nint(nn) .eq. 0) then dae(n) = 0.0 endif c---- End of loop over subset of data. 120 continue c---- Test for truncation. else c---- Loop over subset of data. do 130 n = 1, ns nn = n + n1 - 1 rpr = abs (rb(nn)) + abs (ra(nn)) rmr = abs (rb(nn)) - abs (ra(nn)) if (abs (rmr) .lt. tol * rpr) then rmr = 0.0 endif fact1 = dab(n) + rpr ferr = tol * fact1 fact2 = dab(n) - rmr if (abs (fact2) .lt. ferr) then fact2 = 0.0 endif fact3 = rpr - dab(n) if (abs (fact3) .lt. ferr) then fact3 = 0.0 endif fact4 = rmr + dab(n) if (abs (fact4) .lt. ferr) then fact4 = 0.0 endif arg = fact1 * fact2 * fact3 * fact4 cd(n) = sqrt (amax1 (0.0, arg)) / (dab(n) + fuz) if (arg .gt. 0.0) then nint(nn) = 2 else nint(nn) = 0 endif if (arg .eq. 0.0) then nint(nn) = 1 endif if ((dab(n) .le. tol) .and. & (abs (rmr) .le. tol) ) then nint(nn) = 3 endif dae(n) = dab(n)**2 - rpr * rmr daerr = tol * (dab(n)**2 + rpr * abs (rmr)) if (abs (dae(n)) .lt. daerr) then dae(n) = 0.0 endif dae(n) = 0.5 * dae(n) / (dab(n) + fuz) if (nint(nn) .eq. 0) then dae(n) = 0.0 endif c---- End of loop over subset of data. 130 continue c---- Tested tol. endif c.... Find the coordinates of point "e", the center of the "line" c.... of intersection. e = a + dae * ab. call aptvadc (au(n1), av(n1), 1., dae, abu, abv, ns, tol, & eu, ev, vlen, nerr) c.... Find the coordinates of the two points of intersection, "c" and "d". call aptvadc (eu, ev, 0.5, cd, hnu, hnv, ns, tol, & cu(n1), cv(n1), vlen, nerr) call aptvadc (eu, ev, -0.5, cd, hnu, hnv, ns, tol, & du(n1), dv(n1), vlen, nerr) c.... See if all data subsets are done. c---- Do another subset of data. if (n2 .lt. np) then n1 = n2 + 1 n2 = min (np, n1 + 63) go to 110 endif 210 continue cbugc***DEBUG begins. cbug 9903 format (/ 'aptcinc results. nerr =',i3) cbug 9904 format (' n =',i5,' nint =',i2 / cbug & ' cu,cv=',1p2e22.14 / ' du,dv=',1p2e22.14) cbug write (3, 9903) nerr cbug write (3, 9904) (n, nint(n), cu(n), cv(n), du(n), dv(n), cbug & n = 1, np) cbugc***DEBUG ends. return c.... End of subroutine aptcinc. (+1 line.) end UCRL-WEB-209832