从点到椭圆弧的最短距离算法

时间:2016-03-28 10:51:25

标签: math graphics geometry 2d

我试图找到一种计算任意点和弧之间最短距离的通用方法,其中弧是椭圆边界的90度部分,椭圆的轴都与笛卡尔坐标轴对齐。我在2D工作,所以点和椭圆都是共面的。如果该点与弧相同的象限,相对于椭圆的中心,那么我相信问题与计算整个椭圆边界上​​从一个点到任意点的距离是相同的,为此它相当简单方法(例如http://www.geometrictools.com/Documentation/DistancePointEllipseEllipsoid.pdf)。

在图中,如果点位于x1的左侧或x2的右侧或y1的下方,则问题是直接的。

但是,如果点P如图所示,我无法弄清楚该做什么。

Click here for diagram

2 个答案:

答案 0 :(得分:2)

我通常使用省略号:

  1. N

    对弧进行采样

    90度块使用N>=8所以你不会错过任何东西

  2. 找到最近点

  3. N

    围绕该点的样本弧

    从上一点到下一点的覆盖范围

  4. 递归循环到#2

    每次迭代/递归都会提高准确性。如果达到所需的精度范围(采样区域足够小)或可变精度限制(以避免 FPU下溢),则停止。

  5. example

    <强> [注释]

    这适用于任何椭圆弧,而不仅仅是轴对齐。

    [Edit1] C ++示例

    double x0,y0,rx,ry,a0,a1;   // elliptic arc center,semi-axises,start/end angles CW
    void ellarc_closest_point(double &x_out,double &y_out,double x_in,double y_in)
        {
        int e,i;
        double ll,l,aa,a,da,x,y,b0,b1;
        while (a0>=a1) a0-=pi2;                 // just make sure a0<a1
        b0=a0; b1=a1; da=(b1-b0)/25.0;          // 25 sample points in first iteration
        ll=-1; aa=a0;                           // no best solution yet
        for (i=0;i<3;i++)                       // recursions more means more accurate result
            {
            // sample arc a=<b0,b1> with step da
            for (e=1,a=b0;e;a+=da)
                {
                if (a>=b1) { a=b1; e=0; }
                // elliptic arc sampled point
                x=x0+rx*cos(a);
                y=y0-ry*sin(a);                 // mine y axis is in reverse order therefore -
                // distance^2 to x_in,y_in
                x-=x_in; x*=x;
                y-=y_in; y*=y; l=x+y;
                // remember best solution
                if ((ll<0.0)||(ll>l)) { aa=a; ll=l; }
                }
            // use just area near found solution aa
            b0=aa-da; if (b0<a0) b0=a0;
            b1=aa+da; if (b1>a1) b1=a1;
            // 10 points per area stop if too small area already
            da=0.1*(b1-b0); if (da<1e-6) break;
            }
        x_out=x0+rx*cos(aa);
        y_out=y0-ry*sin(aa);    // mine y axis is in reverse order therefore -
        }
    

    视觉输出:

    ellarc closest point test

答案 1 :(得分:0)

所以整个弧形的东西都是红鲱鱼。它是一个回到单位圆的线性比例。所以你只需要找到从一个点到单位圆的最短距离。 (https://math.stackexchange.com/questions/103453/closest-point-to-a-unit-circle-from-a-point-inside-it)然后只需撤消比例并测量距离。

[Spektre编辑]这显然是错误的!

如果你找到一个圆的最近点(在缩放空间中)并不意味着重新缩放后(到椭圆空间)这个点仍然是最接近的!见例:

example