线段和圆交点

时间:2014-04-11 15:25:29

标签: c# math trigonometry

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

circle-line

1 个答案:

答案 0 :(得分:10)

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

所以检查此代码

// cx,cy是圆圈的中心点

        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;
        }
    }

此处的交叉点代码表单LINK