Let (xP, yP) be the intersection of the tangents, (xC,yY) center of the circle, where you look for the coordinates (xT,yT) tangent points. Next, let T be the tangent vector and R the radius vector. Since they are perpendicular, you are R . T = 0 R . T = 0 .
It gives us
(xT-xC,yT-yC) . (xT-xP, yT-yP) = 0
Let R be the radius of the circle and x:=xT-xC, y:=yT-yC, xp:=xP-xC, yp:=yP-yC (basically, we move the circle to (0,0) ). The tangent point is on the circle, so you have x²+y²=r² and therefore also y=sqrt(r²-x²) .
Variable substitution applied to the above equation gives us:
(x,y) . (x-xp, y-yp) = 0 x²-xp*x + y²-yp*y = 0
Using the information about the circle, we have:
r² -xp*x - yp*sqrt(r²-x²) = 0 r² -xp*x = yp*sqrt(r²-x²) r^4 - 2*r²*xp*x + xp²*x² = yp²*(r²-x²) (yp²+xp²)*x² - 2*r²*xp*x + r^4-yp²*r² = 0 now let a:=yp²+xp², b:=2*r²*xp, c:= (r²-yp²)*r² => ax² + bx + c = 0
This is a quadratic equation with 0, 1 or 2 solutions. 0 if P is in a circle, 1 if P is on a circle and 2 if P is out of a circle.
I won’t get an explicit solution here, since it’s a hellish formula, and it’s much easier to write if you map the variables entered here to variables in your code like:
var sq:Function = function (f:Number) { return f*f; }, sqrt:Function = Math.sqrt; var xp:Number = xP-xC, yp:Number = yP-yC, a:Number = sq(xp)+sq(yp), b:Number = 2*sq(r)*xp, c:Number = sq(r)*(sq(r)-sq(yp)); var x1:Number = (-b+sqrt(sq(b)-4*a*c)) / (2 * a), x2:Number = (-b+sqrt(sq(b)-4*a*c)) / (2 * a); if (isNan(x1)) return []; var p1:Point = new Point(x1+cX, sqrt(sq(r)-sq(x1))+cY),//calculate y and undo shift p2:Point = new Point(x2+cX, sqrt(sq(r)-sq(x2))+cY); return p1.equals(p2) ? [p1] : [p1, p2];
Good luck with this, because I am very poor at calculus, plus it's 04:00 here, so you can bet there is a mistake somewhere, but it should help you in the right direction;)