我有一些建议。你可以试试 LibreCAD,它有一个求解两个椭圆公共切线的解算器,但我对 API 一无所知。求解器求解四次方程,如果您天真地尝试找到两个椭圆的公切线,就会得到。
如果您想自己动手:借助一点理论(“圆锥曲线的范围”),您所要求的可以用线性代数(即求 3x3 矩阵的逆)加上求解二次方程和一个三次方程。它是这样的:
你可以用矩阵方程的形式表达任何圆锥(比如椭圆)
[m00 m01 m02] [x]
[x,y,z] [m10 m11 m12] [y] = 0
[m20 m21 m22] [z]
其中矩阵M 是对称的,[x,y,z] 是齐次坐标;想想z=1。我们可以将该等式简写为X M X^T = 0,其中X^T 是X 的转置。
平面中的线可以写成lx+my+nz=0 的形式,因此具有“线坐标”(l,m,n)。
上述圆锥的切线集可以用这种符号非常简单地表示。让A 是矩阵M 的逆矩阵。那么圆锥的切线集是
[a00 a01 a02] (l)
(l,m,n) [a10 a11 a12] (m) = 0
[a20 a21 a22] (n)
现在假设我们有第二个带有矩阵N 的圆锥曲线,而N 有逆矩阵B。公切线将满足上述方程和方程
[b00 b01 b02] (l)
(l,m,n) [b10 b11 b12] (m) = 0
[b20 b21 b22] (n)
事实上,我们可以将后一个方程中的矩阵乘以t,它仍然成立:
[b00 b01 b02] (l)
(l,m,n) t [b10 b11 b12] (m) = 0
[b20 b21 b22] (n)
将第一个二次曲线的切线方程添加到第二个二次曲线的上述方程中,我们得到矩阵方程L (A + tB) L^T = 0。因此,两个圆锥曲线的任何公切线都是“范围”A + tB 中每个圆锥曲线的公切线。
现在是大简化的想法:我们可以在该范围内找到一些非常特殊的圆锥曲线,“退化”圆锥曲线,它们只是点对。由于公切线必须通过所有二次曲线,因此它们必须通过简并二次曲线。但是很容易找到通过退化圆锥曲线的线,因为这样的圆锥曲线只是点对!
您可以通过求解三次方程 det(A + tB) = 0 来找到简并圆锥曲线,其中 det() 是 3x3 矩阵的行列式。三次可以通过卡尔达诺公式或变体以封闭形式求解,或者如果您需要,也可以通过数值求解。一旦你找到产生退化圆锥曲线的t 的值,你可以将方程L (A + tB) L^T = 0 分解为两个线性因子。每个线性因子xl + ym + zn = 0 定义齐次坐标[x,y,z] 或笛卡尔坐标(x/z,y/z) 中的一个点。您应该以这种方式获得三个点对(六分)。通过这些点对中的某些线将得到您的四个(最多)切线。
这是一个简单的例子(两个椭圆的中心都在原点):找到x^2+2y^2=3 和x^2+14y^2=7 的公共切线。矩阵形式的圆锥是
[1 0 0] [x] [1 0 0] [x]
[x,y,z] [0 2 0] [y] = 0, [x,y,z] [0 14 0] [y] = 0
[0 0 -3] [z] [0 0 -7] [z]
切线由下式给出
[6 0 0] (l) [14 0 0] (l)
(l,m,n) [0 3 0] (m) = 0, (l,m,n) [ 0 1 0] (m) = 0
[0 0 -2] (n) [ 0 0 -2] (n)
注意我将逆矩阵乘以一个标量只是为了使条目成为整数而不是有理数。您不必这样做,但它使手工计算更容易。将第二个矩阵乘以一个额外的标量 t 得到
[6+14t 0 0 ] (l)
(l,m,n) [0 3+t 0 ] (m) = 0
[0 0 -2-2t] (n)
当(6+14t)(3+t)(-2-2t)=0,即t=-3/7, -3, -1,圆锥是退化的。当t=-3/7 我们得到 p>
18/7 m^2 - 8/7 n^2 = 2/7 (9 m^2 - 4 n^2) = 2/7 (3m - 2n)(3m + 2n) = 0
这对应于齐次坐标[x,y,z] = [0,3,-2]和[0,3,2]的点,即笛卡尔坐标(0,-3/2)和(0,3/2)的点。
当t=-3 时,我们得到-36l^2 + 4n^2 = (6l+2n)(-6l+2n) = 0,点[6,0,2] 和[-6,0,2] 或在笛卡尔坐标中(3,0) 和(-3,0)。最后,当t=1 时,我们得到-8l^2 + 2m^2 = 2(2l+m)(-2l+m) = 0 对应于点[2,1,0] 和[-2,1,0],它们是无穷远处的点。
暂时避开无穷远点,只是因为它们更难处理,我们通过以下点对得到四行:
{(0,-3/2),(-3,0)}, {(0,-3/2),(3,0)}, {(0,3/2),(-3,0)}, {(0,3/2),(3,0)}
这给了我们两个椭圆的四个公切线。
从图中可以看出,公切线也通过无穷远点[2,1,0]和[-2,1,0],即平行线对有斜率1/2和-1/2。
是不是很漂亮?