C#多段线是自相交的

C#多段线是自相交的,c#,geometry,C#,Geometry,我有一项任务要检查一条多段线在任何时候是否自交。这个检查必须非常快,因为我的多段线很长(大约有50个点),而且我有一个超时。以下是我写的: public bool IsSelfCrossing() { if (size <= 5) return false; Point first = body.Points.ElementAt(size - 1); Point second = body.Points

我有一项任务要检查一条多段线在任何时候是否自交。这个检查必须非常快,因为我的多段线很长(大约有50个点),而且我有一个超时。以下是我写的:

    public bool IsSelfCrossing()
    {
        if (size <= 5)
            return false;
        Point first = body.Points.ElementAt(size - 1);
        Point second = body.Points.ElementAt(size - 2);
        for (int i = 0; i < size - 3; i++)
        {
            if (Intersect(first, second, body.Points.ElementAt(i),
                body.Points.ElementAt(i + 1)))
            {
                return true;
            }
        }
        return false;
    }

    private double Orientation(Point p1, Point p2, Point p3)
    {
        double dx1 = p2.X - p1.X;
        double dy1 = p2.Y - p1.Y;
        double dx2 = p3.X - p1.X;
        double dy2 = p3.Y - p1.Y;
        return dx1 * dy2 - dy1 * dx2;
    }


    bool Intersect(Point p1, Point p2, Point p3, Point p4)
    {
        return
              Orientation(p1, p3, p4) * Orientation(p2, p3, p4) < 0 &&
              Orientation(p3, p1, p2) * Orientation(p4, p1, p2) < 0;
    }
public bool IsSelfCrossing()
{

if(size本文描述了在线段集合中寻找交点的扫描线算法。它的预期运行时间为O(n+k),其中n是线段数,k是交点数


这是一个更好的“方向”函数实现,避免了舍入错误问题。这可能对您的情况有所帮助。如果p0位于p1和p2之间的直线上,则返回0

    public static int Clockwise (Point p0, Point p1, Point p2)
    {
        const double epsilon = 1e-13;

        double dx1 = p1.X - p0.X;
        double dy1 = p1.Y - p0.Y;
        double dx2 = p2.X - p0.X;
        double dy2 = p2.Y - p0.Y;
        double d = dx1 * dy2 - dy1 * dx2;
        if(d > epsilon) return 1;
        if(d < -epsilon) return -1;
        if((dx1*dx2 < -epsilon) || (dy1*dy2 < -epsilon)) return -1;
        if((dx1*dx1+dy1*dy1) < (dx2*dx2+dy2*dy2)+epsilon) return 1;
        return 0;
    }
public static int顺时针方向(点p0、点p1、点p2)
{
常数双ε=1e-13;
双dx1=p1.X-p0.X;
双dy1=p1.Y-p0.Y;
双dx2=p2.X-p0.X;
双dy2=p2.Y-p0.Y;
双d=dx1*dy2-dy1*dx2;
如果(d>epsilon)返回1;
如果(d<-epsilon)返回-1;
if((dx1*dx2<-epsilon)| |(dy1*dy2<-epsilon))返回-1;
if((dx1*dx1+dy1*dy1)<(dx2*dx2+dy2*dy2)+ε)返回1;
返回0;
}
这是我的“相交”函数:

    public static bool LineIntersects(Point p1,Point p2, Point q1,Point q2)
    {
        return (Clockwise(p1,p2,q1) * Clockwise(p1,p2,q2) <=0) &&
            (Clockwise(q1,q2,p1) * Clockwise(q1,q2,p2) <=0);
    }
公共静态布尔线相交(点p1、点p2、点q1、点q2)
{

返回(顺时针方向(p1,p2,q1)*顺时针方向(p1,p2,q2)您只是在与所有其他行一起检查最后一行?