[英]C# Polyline is self crossing
I've got a task to check if one polyline is self-crossing at any time. 我有一项任务可以随时检查一条折线是否自交。 This check must be very fast because my polyline is long (have about 50 points) and I've got a timeout.
此检查必须非常快,因为我的折线很长(大约有50点)并且我有超时。 Here is what I wrote:
这是我写的:
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;
}
The problem of these methods is that sometimes it fails (the methods are telling me that the polyline is self-crossing but it's not). 这些方法的问题是有时会失败(这些方法告诉我折线是自交叉的,但不是)。 Can you help me with better solution, please?
您能帮我提供更好的解决方案吗?
This paper describes sweep-line algorithm for finding intersections in set of line segments. 本文介绍了用于在线段集中查找相交的扫线算法。 It has expected running time of O(n + k) where n is number of segments and k is number of intersections.
它的预期运行时间为O(n + k),其中n是路段数,k是路口数。
http://www.cs.tufts.edu/comp/163/notes05/seg_intersection_handout.pdf http://www.cs.tufts.edu/comp/163/notes05/seg_intersection_handout.pdf
Here is a better implementation of your "Orientation" function, avoiding problems with rounding errors. 这是“方向”功能的更好实现,避免了舍入错误的问题。 Perhaps this helps in your case.
也许这对您有帮助。 It returns 0 if p0 is on a straight line between p1 and p2.
如果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;
}
And here is my "Intersect" function: 这是我的“相交”功能:
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.