获得2个圆圈的交点

Ric*_*lho 3 c# geometry intersection

我需要能够计算2个圆圈之间的交点.我确信总会有2个交叉点.不是1,不是0,不是无限,总是2.这是我想要做的图表:

这是我目前的尝试:

public static List<Vector2> intersect(Vector3 c1, Vector3 c2, float rad1, float rad2)
{
    List<Vector2> rLp = new List<Vector2>();
    float d = Vector2.Distance(c1, c2);

    if (d > (rad1 + rad2))
        return rLp;
    else if (d == 0 && rad1 == rad2)
        return rLp;
    else if ((d + Mathf.Min(rad1, rad2)) < Mathf.Max(rad1, rad2))
        return rLp;
    else
    {
        float a = (rad1 * rad1 - rad2 * rad2 + d * d) / (2 * d);
        float h = Mathf.Sqrt(rad1 * rad1 - a * a);

        Vector2 p2 = new Vector2((float)(c1.x + (a * (c2.x - c1.x)) / d), (float)(c1.y + (a * c2.y - c1.y) / d));

        Vector2 i1 = new Vector2((float)(p2.x + (h * (c2.y - c1.y)) / d), (float)(p2.y - (h * (c2.x - c1.x)) / d));
        Vector2 i2 = new Vector2((float)(p2.x - (h * (c2.y - c1.y)) / d), (float)(p2.y + (h * (c2.x - c1.x)) / d));

        if (d == (rad1 + rad2))
            rLp.Add(i1);
        else
        {
            rLp.Add(i1);
            rLp.Add(i2);
        }

        return rLp;
    }
}
Run Code Online (Sandbox Code Playgroud)

它给了我以下结果:

如您所见,表示两个圆圈之间截取点的白色方块位于错误的位置.我真的可以在这个领域使用一些帮助.任何人都可以看到什么是错的?

Pet*_*der 5

数学代码的复制和粘贴对我来说几乎总是出错(例如,在定义中翻转signes等).从其他人调试这样的代码只是纯粹的恐怖(当我深入数学时,调试我自己很难).您应该尝试自己进行计算并将其转换为代码.如果出错,您可以使用调试器逐步调试它,并使用袖珍计算器进行交叉检查.

你真的应该尝试自己.拿一张纸然后算好数学.但这是我将使用的方法:

private void intersectionTwoCircles(double c1x, double c1y, double r1, double c2x, double c2y, double r2,
        out double a1x, out double a1y, out double a2x, out double a2y)
    {
        /* error handling is missing complettely - left as an exercise 

              A1
             /| \
         r1 / |  \ r2
           /  |   \
          /   |h   \
         /g1  |     \          (g1 means angle gamma1)
        C1----P-----C2
           d1   d2
        */
        double dx = c1x - c2x;
        double dy = c1y - c2y;
        double d = Math.Sqrt(dx*dx + dy*dy); // d = |C1-C2|
        double gamma1 = Math.Acos((r2*r2 + d*d - r1*r1)/(2*r2*d)); // law of cosines
        double d1 = r1*Math.Cos(gamma1); // basic math in right triangle
        double h = r1*Math.Sin(gamma1);
        double px = c1x + (c2x - c1x) / d*d1;
        double py = c1y + (c2y - c1y) / d*d1;
        // (-dy, dx)/d is (C2-C1) normalized and rotated by 90 degrees
        a1x = px + (-dy)/d*h;      
        a1y = py + (+dx) / d * h;
        a2x = px - (-dy) / d * h;
        a2y = py - (+dx) / d * h;
    }
Run Code Online (Sandbox Code Playgroud)

提供代码后更新:

你的方法与我的(a=r1 cos(gamma_1)h=r1 sin(gamma_1))非常相似.你只是避免gamma直接计算.它的速度更快(只是一个sqrt替代cos,sinacos).但我认为,我的更具可读性;)考虑重载载体类的操作数(+, - ,*,...)......你的代码将变得更容易阅读.

而且我认为我发现了你的错误....

// before
Vector2 p2 = new Vector2((float)(c1.x + (a * (c2.x - c1.x)) / d), (float)(c1.y + (a * c2.y - c1.y) / d));

// after
Vector2 p2 = new Vector2((float)(c1.x + (a * (c2.x - c1.x)) / d), (float)(c1.y + a * (c2.y - c1.y) / d));
Run Code Online (Sandbox Code Playgroud)