Jump to content

Common tangents of two circles


davidpage

Recommended Posts

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!

 

tangent.png

 

Link to comment
https://forums.phpfreaks.com/topic/98615-common-tangents-of-two-circles/
Share on other sites

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);
?>

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.