我正在寻找一种算法来测试多边形是否“严格”简单。通常,测试涉及检查任何多边形段之间的交叉。但是在这里,因为我想检查并不总是属于边缘交叉点的情况,我不太确定要寻找什么。
在上图中,B C和D不是简单的多边形,但只有D会使交叉点测试失败。我的术语(在严格简单方面)也可能有点偏差,但我认为图片说明了我的意思。
答案 0 :(得分:1)
如果两条线至少有一个公共点,则说两条线相交。
取一条边并计算任何其他边的交点。如果有
所以在我看来,你的担忧没有根据:
但是在这里,因为我想检查并不总是属于边缘交叉点的情况[...]
这种方法也适用于此。
答案 1 :(得分:0)
必须独立检查这三类无效多边形。
案例B:
检查以确保多边形中没有重复的顶点。
案例C:
检查以确保没有顶点落在任何边缘上。假设您使用浮点数,这可能会变得棘手,因为浮点数必须评估为完全相等。这可以通过说它们不能在彼此的EPS
范围内来规避,但这可能使一些其他几乎无效的多边形无效。我本人会亲自使用EPS
,除非我真的需要最高精度(此时我不知道我会做什么)。
案例D:
正如你所说,可以通过检查是否有任何边相交来找到它。
案例E: 两条边重叠(在无限多点处相交),它们的顶点不重叠。
我不确定这是否需要是一个单独的案例,但是这种情况可能不会被案例D的检查所捕获(我认为你最终除以零)。因此,您还必须检查两条边是否与完全相同的线对应。
目前我无法想到任何其他案例
答案 2 :(得分:0)
情况F:顶点形成闭环,并以CCW顺序给出。这可以通过循环遍历所有顶点并总结关节角度来完成。我选择革命作为我的角度单位:(伪代码)
vertex_n_minus1 = [x,y]
vertex_n = ..
vertex_n_plus1 = ..
DirectionVector incomingDir = new DirectionVector(vertex_n_minus1,vertex_n)
DirectionVector outgoingDir = new DirectionVector(vertex_n,vertex_n_plus1)
DirectionVector dirChange = [outgoingDir•incomingDir,outgoingDir•rot90CW(incomingDir)]
double jointTurnAmountRevs = dirChange.toAngle()/(2 * PI)(转换dirVec - > angle_radians - > revs)
如果总结变量jointTurnAmountRevs,则CCW,完全闭合的多边形路径将等于1.0(+ - EPSILON)。如果它完全关闭但CW,你将获得-1.0。