给定一个S段和一个多边形P,是否有一个快速算法返回S跨越多边形P的子段的总长度?
注意:P由闭合的LineString定义(即:第一个和最后一个相等的点数组)。 P没有任何“孔”,但可以是凹的和/或自相交的。
注意:最终目标是所有相交子段的总长度,如果可以更快地完成此操作而不检索所有这些子段的显式数组,那就更好了。
奖励点:所述算法的Java实现。使用像JTS这样的库是可以的,只要得到的解决方案很快。
使用JTS的简单解决方案已经存在但不支持自相交多边形,而且我认为并不是最快的。此解决方案涉及创建一个Polygon对象(对于P),一个2点LineString对象(对于S),并获得所得交集的长度。
以下是执行此操作的代码:
GeometryFactory fact = new GeometryFactory();
WKTReader wktRdr = new WKTReader(fact);
String wktP = "POLYGON((40 100, 40 20, 120 20, 120 100, 60 40, 40 100))";
String wktS = "LINESTRING(20 60, 160 60)";
Geometry pl = wktRdr.read(wktP);
Geometry ls = wktRdr.read(wktS);
Geometry in = pl.intersection(ls);
System.out.println("P = " + pl);
System.out.println("S = " + ls);
System.out.println("P intersection S = " + in);
System.out.println("S length = " + ls.getLength());
System.out.println("P intersection S length = " + in.getLength());
编辑:对自相交多边形的考虑:虽然可能不是最快的解决方案,但可能涉及通过将自相交多边形分成多个非自相交多边形来预处理。
关于此事的一些解释和一些伪代码在这里: Algorithm to split self-intersected Path2D into several not self-intersected paths?
答案 0 :(得分:2)
在O(n * log n)中查找非自相交多边形的交点长度。
的伪代码:
function intersecting_segment_length(set P, segment S):
let starting_point = the bottom-most, left-most point in P.
let E1, E2 = the edges of starting_point
let intersections = new array.
do:
while E1 != E2 and E1 does not cross S:
E1++ //move E1 "clockwise" around P
while E2 != E1 and E2 does not cross S:
E2-- //move E2 "counterclockwise" around P
if E1 != E2:
p1 = the intersection of E1 and S
p2 = the intersection of E2 and S
intersections.add(new line segment from p1 and p2)
until E1 == E2.
return sweepline(intersections)
Sweepline伪代码:
function sweepline(array segments):
let points = start and end points of all segments
sort points as they intersect S
let last_point = points.first()
let num_segments = 0 //num segments intersected by sweepline
let length = 0
for each point p in points - last_point:
if p is the leading point in p.owning_segment:
num_segments++
else: //trailing point
num_segments--
if num_segments % 2 == 0: //I think
length += distance between p and last_point
last_point = p
return length
复杂度:
O(n)
中的行走边缘,其中n
是P中的边/顶点数。O(m*log m)
,其中m
是P与S的交点数。O(m)
。O(n)
交叉点的“梳形多边形”,因此在最坏的情况下总复杂度为O(n*log n)
。注意:
O(n*log n)
。