Tim*_*sov 5 math geometry ellipse computational-geometry
给定轴向对齐的,原点居中的椭圆E外部的点p,找到通过p的E的(最多)四个唯一法线.
这不是Mathematica的问题.直接计算太慢; 我愿意为速度牺牲精度和准确性.
我在网上搜索过,但我发现所有涉及过于复杂的计算,如果直接实现,似乎缺乏我需要的性能.有没有更"程序化"的方法来做到这一点,比如使用矩阵或将椭圆缩放成圆形?
假设椭圆E位于"标准位置",中心位于原点,轴平行于坐标轴:
(x/a)^2 + (y/b)^2 = 1 where a > b > 0
Run Code Online (Sandbox Code Playgroud)
边界情况a=b是圆形,其中法线简单地穿过中心(原点)并因此容易找到.所以我们省略了对这些案例的讨论.
任何点处椭圆的切线斜率(x,y)可以通过隐式微分找到:
dy/dx = -(b^2 x)/(a^2 y)
Run Code Online (Sandbox Code Playgroud)
对于穿过(x,y)的线和p = (u,v) 不在椭圆上的指定点,E当椭圆的斜率为负倒数时,这与椭圆是垂直的dy/dx:
(y-v)/(x-u) * (-b^2 x)/(a^2 y) = -1 (N)
Run Code Online (Sandbox Code Playgroud)
这简化为:
(x - (1+g)u) * (y + gv) = -g(1+g)uv where g = b^2/(a^2 - b^2)
Run Code Online (Sandbox Code Playgroud)
在这种形式中,我们认识到它是一个正确的矩形双曲线的等式.根据路口的多少分有椭圆形和双曲线(2,3,4)之间,我们有很多法线E穿过p.
通过反射对称性,如果p假设在外部E,我们可能需要p处于第一象限:
(u/a)^2 + (v/b)^2 > 1 (exterior to E)
u,v > 0 (1'st quadrant)
Run Code Online (Sandbox Code Playgroud)
我们可以有边界情况,u=0或者v=0,即点p位于轴上E,但是这些情况可以简化为求解二次方,因为两个法线是通过该轴的端点的(重合)线.我们暂时推迟对这些特殊情况的进一步讨论.
这是一个插图,a=u=5,b=v=3其中只有双曲线的一个分支相交E,并且只有两个法线:

如果将两个未知数中的两个方程的系统(x,y)简化为一个未知的一个方程,则最简单的编码寻根方法是二分法,但了解根/交叉点的可能位置将加速我们的搜索.在第一象限的交点是的最近点E到p,并且同样地在第三象限的交点是的最远点E从p.如果该点p更接近于短轴的上端点,则双曲线的分支将足够移动以在第四象限中创建多达两个交叉点.
一种方法是E通过与x轴的交点进行参数化.从p法线到椭圆的线必须与长轴相交,长轴是有限间隔[-a,+a].我们能够同时测试交叉点的上点和下点q=(x,y)穿过线p=(u,v)和(z,0)作为z从扫描-a到+a,寻找其中椭圆和双曲线相交的地方.
更详细:
1. Find the upper and lower points `q` of intersection of E with the
line through `p` and `(z,0)` (amounts to solving a quadratic)
3. Check the sign of a^2 y(x-u) - b^2 x(y-v) at `q=(x,y)`, because it
is zero if and only `q` is a point of normal intersection
Run Code Online (Sandbox Code Playgroud)
一旦检测到符号变化的子区间(上部或下部),就可以对其进行细化以获得所需的精度.如果只需要适度的准确性,则可能不需要使用更快的根查找方法,但即使需要它们,使用隔离根(或第四象限中的根对)的短子区间也是有用的.
**更多比较各种方法的收敛**
| 归档时间: |
|
| 查看次数: |
1649 次 |
| 最近记录: |