产生新的面的一切多边(2D)
-
21-09-2019 - |
题
我被卡住了这个小小的问题和我的算法来解决这个不保持对所有情况。没有任何人拥有一个想法怎么解决这个吗?
这里有一个例子面:
例http://img148.imageshack.us/img148/8804/poly.png
正式说明
我们有一个列表中的点CW以限定的多边形。我们也可以查询是否有一点是一个尖点 is_cut(p)
, ,哪里 p
是的给定点。现在我们要计算新面由此引起的"切"。
算法应该这样做:
输入: {a, c1, b, c4, c, c5, d, c6, e, c3, f, c2}
输出: {a, c1, c2}
, {b, c4, c3, f, c2, c1}
, {d, c6, c5}
, {e, c3, c4, c, c5, c6}
在这里,我的前算法:
follow your points, CW
if the point is a cut point
-> go back trough the list looking for cut points
--- if next cut point is connected to the current cut point
and not part of the current poly, follow it
--- else keep searching
else
-> continue until you hit your starting point.
that's a poly
do this for every non-cut-point
这个算法并不持有,如果你想开始 c
或 f
.
解决方案
首先你应该计算一段切割线属于内部的你的原始面。这是一个典型的问题,其解决方案是简单的。鉴于你的观点 c1, c2, c3 ... c6
奠定了沿线的正是这一秩序,那么分段 c1-c2
, c3-c4
等将始终属于多边内部(*).
现在我们可以建造简单的递归算法用于切割面。给你巨大的输入阵列,{,c1、b、c4、c、c5、d、c6,e,c3,f,c2},开始从任何多边点,例如, b
;它添加到阵列 result
.遍历输入阵前进。如果你遇到
- 通常的面点,把它推到一阵
result
. ck
节点,在这里k
是奇怪, ,你看c(k+1)
并保持历从其位置。ck
节点,在这里k
甚至是, ,你看c(k-1)
, 跳到其位置并保留尽管如此穿越前进。
对于最后两个情况下,添加这些节点,在命令你遇到他们 result
阵列。添加 ck
节点的设置 cut
, 并添加另一个节点(c(k+1)
或 c(k-1)
, ,无论你已经得到了)成为一个全球组 done
.
如果你必须超越最后的元件,电路的第一个元素在输入阵列。
你迟早会遇到的初始节点你是穿越。现在 result
阵你有一个多边你已经削减。记住它。重复的程序递归,从位置的每个节点,属于 cut
设置并不属于全球 done
设置。
这就是解决方案,因为我看到它。但它的计算geomentry,所以它可能会变成一个比较复杂,它似乎。
例如,开始从 b
:
done={}
, ,开始从b
.之后第一次通过,你会得到result=[b,c4,c3,f,c2,c1]
,cut={c4,c2}
,done={c3,c1}
;Recurse到c4
和c2
节点。done={c3;c1}
, ,开始从c4
(递归从1).在此之后通过,你会得到result=[c4,c,c5,c6,e,c3,c4]
,cut={c5,c3}
,done+={c6,c4}
;Recurse到c5
.done={c3;c1;c4;c6}
, ,开始从c2
(递归从1).在此之后通过,你会得到result=[c2,a,c1]
,cut={c1}
,done+={c2}
;不recurse到c1
, ,因为它是在done
集;done={c3;c1;c4;c6;c2}
, ,开始从c5
(递归2).在此之后通过,你会得到result=[c5,d,c6]
,cut={c5}
,done+={c6}
;不recurse到c5
, ,因为它是在done
集;
瞧-你得到的4面你需要的。
(*)注意到需要更多的"数学"表示线。例如,如果一个多边形的顶点是在线的顶点应该是增加了一倍,即如果 c
点点接近右侧和在红线,线会 [c1, c2, c3, c, c, c6]
点上,它和多边形阵列会 [a, c1, b, c, c, c, d, c6, e, c3, f, c2]
.
有时候(不在此例),它可能导致削"空的"多边形,例如 [a, a, a]
.如果你不需要他们,可以消除他们在后期阶段。无论如何,它的计算几何与一个巨大的数边界的情况。我不能包括他们都在同一个答案...
其他提示
您可以申请韦勒阿瑟顿剪辑(实际上什么帕维尔是在暗示),但有一个巨大的警告。
由于浮点错误,W / A裁剪算法是极难得到运作良好 - 在诸如穿过顶点限幅线,或精确地沿着所述多边形的边,该算法可以变得困惑其中“路径”围绕多边形的perimiter它应该遵循并然后输出不正确的结果。
<强> 1查找侧的每个点是强>
挑选一个蓬不是上切割(一个例如),并设置它是在左侧(它不actaly梅特)
当你去了就砍分,点的一侧到达变化。所以,你会发现左/右点。
问题是,你也应该考虑点的顺序应该是predifined方式。 (顺时针例如)
<强> 2开始在CX的每个中间部分和去一次顺时针和逆时针强>
有关每个多边形你打中段在一个方向上只有一次。
如果你“溢出” C意味着你到达外多项式。 如果你定义C0和Cmax其位于polgon你可能会解决这个问题,你有比
input = {a, c1, c0 ,c1, b, c4, c, c5, d, c6, c7, c6, e, c3, f, c2}
要实现是萨瑟兰-Hodgman 的最简单的。的一个问题是,它让上线的一侧连接的多边形小面积为零条子。在你的榜样,这将给你是这样的:
{一个C2 C3ëC6 C5 C 1 -C 4 Cl}和{B C1 C2 C3˚FC6ðC5 C4}
如果你能与此居住或弄清楚如何将它们分开成你想要的作品,那么你会发现,它确实实际裁剪代码将大约尽可能简单。
在实现只需要两个栈和单次通过您的多边形的顶点。在每个顶点你检查,看看是否你已经在上次顶点冲过终点线。如果是这样,计算交叉点,并推动它的堆栈之一。然后按新的顶点到栈之一。很容易。