subroutine aptcirt (r1, r2, r3, tol, r4, r5, nerr) c. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTCIRT c c call aptcirt (r1, r2, r3, tol, r4, r5, nerr) c c Version: aptcirt Updated 2001 May 29 15:00. c aptcirt Originated 1998 December 4 16:40. c c Author: Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123. c c c Purpose: For the three coplanar and mutually tangent circles with radii c r1, r2 and r3, find the radius r4 of the circle tangent to those c three, in the space between them, and the radius r5 of an c additional circle tangent to the first three, and not in the c space between them. c Flag nerr indicates any input error, if not zero. c c Method: Defining b = 1 / r, negative if the tangency is on the inside c of the circle: c s = b1 + b2 + b3 > 0 c q = b1 * b2 + b2 * b3 + b3 * b1 => 0 c sq = b1**2 + b2**2 + b3**2 > 0 c g = sq - 2.0 * q = b4 * b5 c c If s > 0 c b4 = s + sqrt (q) c b5 = g / b4 c If s < 0 (probably impossible): c b5 = s - sqrt (q) c b4 = g / b5 c c r4 = 1 / b4 (1.e99 if b4 = 0) c r5 = 1 / b5 (1.e99 if b5 = 0). c c Input: r1, r2, r3, tol. c c Output: r4, r5, nerr. c c Calls: none c c Glossary: c c nerr Output Indicates an input error, if not 0. c 1 if b1*b2 + b2*b3 + b3*b4 is negative, which means c radii r1, r2 and r3 are physically impossible. c 2 if any of the radii are zero. c 3 if r1 + r2 = 0. c c r1,r2,r3 Input The radii of three mutually tangent circles, all in c the same plane. A negative radius indicates a circle c that surrounds the other two circles. A very large c radius, relative to the other two, indicates a c straight line. c c r4 Output The radius of the circle coplanar with and tangent to c the first three circles, in the space between them. c E.g., r1 = 1, r2 = 2, r3 = 3, r4 = 0.2608695652174. c Returned as -1.e99 if nerr = 1. c c r5 Output The radius of the circle coplanar with and tangent to c the first three circles, but not in the space between c them. A negative value of r5 means that circle c surrounds the first four circles. E.g., r1 = 1, c r2 = 2, r3 = 3, = 0.2608695652174..., r5 = -6. c A value of r5 near 1.e99 indicates the circumference c of that circle is a straight line. E.g., r1 = 1, c r2 = 1, r3 = 0.25, r4 = 0.08333333333333, r5 = 1.e99. c Returned as -1.e99 if nerr = 1. 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. cbugc***DEBUG begins. cbug 9901 format (/ 'aptcirt finding radii of circles tangent to', cbug & ' circles with radii:' / cbug & ' r1, r2, r3 =',1p3e22.14 / cbug & ' tol =',1pe22.14 ) cbug write ( 3, 9901) r1, r2, r3, tol cbug g = -1.e99 cbug q = -1.e99 cbug s = -1.e99 cbug b4 = -1.e99 cbug b5 = -1.e99 cbugc***DEBUG ends. c.... Initialize. nerr = 0 r4 = -1.e99 r5 = -1.e99 c.... Test for input errors. if (((r1 .lt. 0.0) .and. (-r1 .lt. (r2 + r3))) .or. & ((r2 .lt. 0.0) .and. (-r2 .lt. (r3 + r1))) .or. & ((r3 .lt. 0.0) .and. (-r3 .lt. (r1 + r2)))) then nerr = 1 ! Impossible fit. go to 210 endif if (r1 * r2 * r3 .eq. 0.0) then nerr = 2 ! A radius is zero. go to 210 endif s12 = r1 + r2 if (abs (s12) .le. tol * (abs (r1) + abs (r2))) s12 = 0.0 if (s12 .eq. 0.0) then nerr = 3 go to 210 endif c.... Find the curvatures of circles 1, 2 and 3. b1 = 1.0 / r1 b2 = 1.0 / r2 b3 = 1.0 / r3 cbugcbugc***DEBUG begins. cbugcbug 9801 format (' b1, b2, b3 =',1p3e22.14) cbugcbug write (3, 9801) b1, b2, b3 cbugcbugc***DEBUG ends. c.... See if a solution is possible. q = b1 * b2 + b2 * b3 + b3 * b1 cbugcbugc***DEBUG begins. cbugcbug 9701 format (' q =',1pe22.14 ) cbugcbug write ( 3, 9701) q cbugcbugc***DEBUG ends. errq = 2.0 * tol * (abs (b1*b2) + abs (b2*b3) + abs (b3*b1)) if (abs (q) .le. errq) q = 0.0 if (q .lt. 0.0) then nerr = 1 go to 210 endif c.... See if there are one or two solutions. s = b1 + b2 + b3 errs = tol * (abs (b1) + abs (b2) + abs (b3)) if (abs (s) .le. errs) s = 0.0 sq = b1**2 + b2**2 + b3**2 cbugcbugc***DEBUG begins. cbugcbug 9702 format (' s =',1pe22.14 ) cbugcbug write ( 3, 9702) s cbugcbugc***DEBUG ends. errs = tol * (abs (b1) + abs (b2) + abs (b3)) if (abs (s) .le. errs) s = 0.0 if (q .eq. 0.0) then b4 = s b5 = s go to 180 endif c.... Find the differences between radii. d12 = r2 - r1 err12 = tol * (abs (r1) + abs (r2)) if (abs (d12) .le. err12) d12 = 0.0 d23 = r3 - r2 err23 = tol * (abs (r2) + abs (r3)) if (abs (d23) .le. err23) d23 = 0.0 d31 = r1 - r3 err31 = tol * (abs (r1) + abs (r3)) if (abs (d31) .le. err31) d31 = 0.0 c.... Find g = b4 * b5, by the most accurate equations. if ((d12 .eq. 0.0) .and. (d23 .eq. 0.0)) then g = -3.0 * b1**2 errg = 0.0 elseif (d12 .eq. 0.0) then g = b3 * (b3 - 4.0 * b1) errg = 2.0 * tol * abs (b3) * (abs (b3) + 4.0 * abs (b1)) elseif (d23 .eq. 0.0) then g = b1 * (b1 - 4.0 * b2) errg = 2.0 * tol * abs (b1) * (abs (b1) + 4.0 * abs (b2)) elseif (d31 .eq. 0.0) then g = b2 * (b2 - 4.0 * b3) errg = 2.0 * tol * abs (b2) * (abs (b2) + 4.0 * abs (b3)) else ! Radii r1, r2 and r3 different. g = sq - 2.0 * q errg = 2.0 * tol * sq + 2.0 * errq endif ! Tested for equal radii. cbugcbugc***DEBUG begins. cbugcbug 9802 format (' g =',1pe22.14) cbugcbug write (3, 9802) g cbugcbugc***DEBUG ends. if (abs (g) .le. errg) g = 0.0 c.... Find the curvatures b4 and b5. if (s .lt. 0.0) then ! This may be impossible. b5 = s - 2.0 * sqrt (q) b4 = g / b5 elseif (s .eq. 0.0) then b4 = 2.0 * sqrt (q) b5 = -2.0 * sqrt (q) elseif (s .gt. 0.0) then b4 = s + 2.0 * sqrt (q) b5 = g / b4 endif ! Tested sign of s. c.... Find the radii r4 and r5. 180 if (b4 .eq. 0.0) then r4 = 1.e99 elseif (abs (b4) .ge. 1.e99) then r4 = 0.0 else r4 = 1.0 / b4 endif if (b5 .eq. 0.0) then r5 = 1.e99 elseif (abs (b5) .ge. 1.e99) then r5 = 0.0 else r5 = 1.0 / b5 endif c.... Put radii r4 and r5 in increasing order of absolute value. if (abs (r5) .lt. abs (r4)) then rx = r4 r4 = r5 r5 = rx endif 210 continue cbugc***DEBUG begins. cbug 9902 format (/ 'aptcirt results: nerr=',i3 / cbug & ' q, s, g =',1p3e22.14 / cbug & ' b4, b5 =',1p2e22.14 / cbug & ' r4, r5 =',1p2e22.14 ) cbug write ( 3, 9902) nerr, q, s, g, b4, b5, r4, r5 cbugc***DEBUG ends. return c.... End of subroutine aptcirt. (+1 line.) end UCRL-WEB-209832