线段和圆交点

Val*_*sca 7 c# math trigonometry

我有一个与半径为r的圆相交的线段(x1,y1,x2,y2).如何确定哪个交点最接近(x1,y1)?

圆线

小智 11

要做到这一点,首先找到圆的交点,然后将最接近的点与线起点

所以检查这段代码

// cx,cy是圆的中心点

//cx,cy is center point of the circle 
public PointF ClosestIntersection(float cx, float cy, float radius,
                                  PointF lineStart, PointF lineEnd)
{
    PointF intersection1;
    PointF intersection2;
    int intersections = FindLineCircleIntersections(cx, cy, radius, lineStart, lineEnd, out intersection1, out intersection2);

    if (intersections == 1)
        return intersection1; // one intersection

    if (intersections == 2)
    {
        double dist1 = Distance(intersection1, lineStart);
        double dist2 = Distance(intersection2, lineStart);

        if (dist1 < dist2)
            return intersection1;
        else
            return intersection2;
    }

    return PointF.Empty; // no intersections at all
}

private double Distance(PointF p1, PointF p2)
{
    return Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
}

// Find the points of intersection.
private int FindLineCircleIntersections(float cx, float cy, float radius,
                                        PointF point1, PointF point2, out               
                                        PointF intersection1, out PointF intersection2)
{
    float dx, dy, A, B, C, det, t;

    dx = point2.X - point1.X;
    dy = point2.Y - point1.Y;

    A = dx * dx + dy * dy;
    B = 2 * (dx * (point1.X - cx) + dy * (point1.Y - cy));
    C = (point1.X - cx) * (point1.X - cx) + (point1.Y - cy) * (point1.Y - cy) - radius * radius;

    det = B * B - 4 * A * C;
    if ((A <= 0.0000001) || (det < 0))
    {
        // No real solutions.
        intersection1 = new PointF(float.NaN, float.NaN);
        intersection2 = new PointF(float.NaN, float.NaN);
        return 0;
    }
    else if (det == 0)
    {
        // One solution.
        t = -B / (2 * A);
        intersection1 = new PointF(point1.X + t * dx, point1.Y + t * dy);
        intersection2 = new PointF(float.NaN, float.NaN);
        return 1;
    }
    else
    {
        // Two solutions.
        t = (float)((-B + Math.Sqrt(det)) / (2 * A));
        intersection1 = new PointF(point1.X + t * dx, point1.Y + t * dy);
        t = (float)((-B - Math.Sqrt(det)) / (2 * A));
        intersection2 = new PointF(point1.X + t * dx, point1.Y + t * dy);
        return 2;
    }
}
Run Code Online (Sandbox Code Playgroud)

交叉码在这里形成LINK

  • 距离的顺序不随sqrt改变,因此最好将它们平方成平方以提高速度。 (3认同)