我有几个建议。您可以尝试使用LibreCAD,它具有用于两个椭圆公切线的求解器,但我不了解API。该求解器解决四次方程,这是如果您天真地尝试找到两个椭圆的公切线所获得的结果。
如果您想自己编写代码:通过一些理论(“锥体范围”),您可以使用线性代数(即查找3x3矩阵的逆)以及解决二次和一个三次方程来完成您所需的内容。步骤如下:
您可以将任何锥体(例如椭圆)表示为矩阵方程的形式。
[m00 m01 m02] [x]
[x,y,z] [m10 m11 m12] [y] = 0
[m20 m21 m22] [z]
矩阵M
对称,[x,y,z]
是齐次坐标,可以将方程简写为X M X^T = 0
,其中X^T
是X
的转置。请将z=1
视为常数。
平面上的直线可以写成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矩阵的行列式。可以通过Cardano公式或其变形来解决这个三次方程,也可以进行数值求解。一旦找到使圆锥曲线退化的
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
时,我们得到
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)}
这给我们提供了两个椭圆的四条常见切线。
![common tangents to two ellipses](https://istack.dev59.com/C2VyC.webp)
你可以从图片中看出,共切线也经过无穷远点
[2,1,0]
和
[-2,1,0]
,即平行线对具有斜率
1/2
和
-1/2
。
这不是很美吗?