设(xP, yP)
为切线的交点,(xC,yY)
为圆的中心,你需要找到切点(xT,yT)
的坐标。此外,让T
成为切线向量,R
成为半径向量。由于它们是垂直的,因此有R . T = 0
。
这给我们带来了
(xT-xC,yT-yC) . (xT-xP, yT-yP) = 0
设r
为圆的半径,令x:=xT-xC, y:=yT-yC, xp:=xP-xC, yp:=yP-yC
(基本上,我们将圆移动到(0,0)
)。
切点在圆上,因此有x²+y²=r²
,因此也有y=sqrt(r²-x²)
。
对上述方程进行变量替换得:
(x,y) . (x-xp, y-yp) = 0
x²-xp*x + y²-yp*y = 0
利用我们拥有的圆形信息:
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
这是一个带有0、1或2个解的二次方程。如果P在圆内,则为0;如果P在圆上,则为1;如果P在圆外,则为2。
我不会在这里放置显式解,因为它是一个非常复杂的公式,如果您将此处引入的变量映射到代码中的变量,则更容易编写。
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];
祝你好运,因为我对微积分非常不擅长,而且现在已经凌晨四点了,所以可以肯定,在某个地方会有错误,但这应该能让你朝正确的方向前进 ;)