C++ 确定分段直线的交点
/我需要确定由多条线段定义的一对直线是否相交,例如由C++ 确定分段直线的交点,c++,math,geometry,line-intersection,C++,Math,Geometry,Line Intersection,/我需要确定由多条线段定义的一对直线是否相交,例如由(0,0)、(1,2)、(3,1)定义的一条直线和由(0,2)、(2,-1)、(4,1)定义的另一条直线 我不需要确定交点的位置,但我需要一种有效的方法,因为我可以有大量的边。我使用下面的代码来确定两个线段是否相交,但对于长度较大的直线来说,这是无效的。此外,这些线是图中的边,它们被约束到已知的最大长度 static bool IsOnSegment(float xi, float yi, float xj, float yj,
(0,0)、(1,2)、(3,1)
定义的一条直线和由(0,2)、(2,-1)、(4,1)
定义的另一条直线
我不需要确定交点的位置,但我需要一种有效的方法,因为我可以有大量的边。我使用下面的代码来确定两个线段是否相交,但对于长度较大的直线来说,这是无效的。此外,这些线是图中的边,它们被约束到已知的最大长度
static bool IsOnSegment(float xi, float yi, float xj, float yj,
float xk, float yk) {
return (xi <= xk || xj <= xk) && (xk <= xi || xk <= xj) &&
(yi <= yk || yj <= yk) && (yk <= yi || yk <= yj);
}
static char ComputeDirection(float xi, float yi, float xj, float yj,
float xk, float yk) {
float a = (xk - xi) * (yj - yi);
float b = (xj - xi) * (yk - yi);
return a < b ? -1 : a > b ? 1 : 0;
}
// Do line segments (x1, y1)--(x2, y2) and (x3, y3)--(x4, y4) intersect? /
bool DoLineSegmentsIntersect(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4) {
char d1 = ComputeDirection(x3, y3, x4, y4, x1, y1);
char d2 = ComputeDirection(x3, y3, x4, y4, x2, y2);
char d3 = ComputeDirection(x1, y1, x2, y2, x3, y3);
char d4 = ComputeDirection(x1, y1, x2, y2, x4, y4);
return (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&
((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))) ||
(d1 == 0 && IsOnSegment(x3, y3, x4, y4, x1, y1)) ||
(d2 == 0 && IsOnSegment(x3, y3, x4, y4, x2, y2)) ||
(d3 == 0 && IsOnSegment(x1, y1, x2, y2, x3, y3)) ||
(d4 == 0 && IsOnSegment(x1, y1, x2, y2, x4, y4));
}
<代码>静态BoL ISONFATE(浮动席,浮法,浮法XJ,浮法YJ,
浮动xk,浮动yk){
return(xi您将稍微更改计算O((n+k)logn)
时间和O(n+k)
空间中所有k
交点的值
建议的修改-Bentley-Ottmann算法获取线段集并报告所有交点。您可以将分段线拆分为线段集,并将此集合作为算法的输入。当发现某些交点时,只需检查相交线段是否属于同一分段线。如果不是,则表示您已找到分段线的交点
请注意,在最坏的情况下,当交叉点的数量非常大时,复杂性将是O(n^2)
。最坏的情况是两条看起来像缠绕的蛇的分段线。请记住,至少有O(n)
伪交叉点-每条分段线将产生O(长度)
pseudo intersections,当lenght1+lenght2=N时,其中N是段的总数,则存在O(N)个pseudo intersection。pseudo intersection是由Bentley-Ottmann算法检测到但不应考虑的交叉点
实现提示-基于扫描线算法的Bentley-Ottmann算法,该算法基于排序点(X,Y)对。现在您应该只对三元组(X,Y,segmentsLineID)进行排序。在您的情况下,所有三元组都将是(X,Y,1)或(X,Y,2)这个问题的可能副本给了我确定两个单段是否相交的函数,但是我需要考虑一个段的路径并找到与另一条路径的交点。由(0,0)、(1.2)和(3,1)定义的一条线;这是2条线段或三角形的结合吗?这是一条路径(线段的结合)。这是顺序中的各点。