davidpage Posted March 30, 2008 Share Posted March 30, 2008 Is there a quick function to find the points of contact between a circle and its common external tangent(s) with another (if any)? i.e. inputs: the coordinates of the centres of two circles and their radii (O, P, r1 and r2 in the figure below) outputs: the coordinates of the points of contact between the common external tangents and the circles (A, B, C, D in the figure below). If no such points exist, simply return empty/null/false values. It's not that hard to compute them manually on paper, but I just can't find a way to translate that to php language... Thanks! Quote Link to comment Share on other sites More sharing options...
davidpage Posted April 1, 2008 Author Share Posted April 1, 2008 I've solved the problem using the following code. Please suggest if you have an improved version and thanks! <?php //Two circles, find external tangents - return the points of intersection b/w tangents and circles function tangent($pt1, $pt2, $r1, $r2, &$result){ //Default is r1 > r2 if ($r1 < $r2){ $temp = $r1;$r1 = $r2;$r2 = $temp; $cen1x = $pt2[0]; $cen1y = $pt2[1]; $cen2x = $pt1[0]; $cen2y = $pt1[1]; } else { $cen1x = $pt1[0]; $cen1y = $pt1[1]; $cen2x = $pt2[0]; $cen2y = $pt2[1]; } //Distance between two centres $cendistance = sqrt(($cen1x-$cen2x)*($cen1x-$cen2x) + ($cen1y-$cen2y)*($cen1y-$cen2y)); $a = $cendistance*$r2/max($r1-$r2,0.0000001); //Coordinates at the vertex $vx = $cen2x + ($cen2x - $cen1x)/$cendistance*$a; $vy = $cen2y + ($cen2y - $cen1y)/$cendistance*$a; //Angle between line joining two centres and the x-axis $pheta = atan2($cen1y-$cen2y,$cen1x-$cen2x); //Angle between line joining two centres and the common tangent $phi = asin($r2/$a); //One tangent is at the angle (pheta-phi) with x-axis; the other is (pheta+phi) $tan1angle = $pheta - $phi; $tan2angle = $pheta + $phi; //Find the length of tangents (to C1 and C2) $criterion = $a*$a-$r2*$r2; if ($criterion < 0){ $result = array("NA","NA","NA","NA","NA","NA","NA","NA"); return; } $t1 = sqrt($criterion); $t2 = sqrt(($cendistance+$a)*($cendistance+$a)-$r1*$r1); //Find the points of contact; this sequence is used to form a polygon $poc1x = $vx + cos($tan1angle)*$t1; $poc1y = $vy + sin($tan1angle)*$t1; $poc2x = $vx + cos($tan1angle)*$t2; $poc2y = $vy + sin($tan1angle)*$t2; $poc3x = $vx + cos($tan2angle)*$t2; $poc3y = $vy + sin($tan2angle)*$t2; $poc4x = $vx + cos($tan2angle)*$t1; $poc4y = $vy + sin($tan2angle)*$t1; $result = array($poc1x,$poc1y,$poc2x,$poc2y,$poc3x,$poc3y,$poc4x,$poc4y); } //tangent(array(3,10),array(11,4),6,4,$result); tangent(array(712,462),array(810,520),28,16,$result); var_dump($result); ?> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.