我正在尝试实现一种算法,该算法找到以下形状给出的外多边形的每个单独边缘的相应区域。也就是说,1,2边缘的相应区域是[1,6,7,8,2],边缘2,3的区域是[2,8,3],依此类推,CCW或CW在这里不是问题。这里详细说明黑色粗体线是外部多边形,内部虚线蓝色线是给定外部多边形的直骨架,我无法控制内部节点编号方案,这意味着从左到右节点它可以是8,7 ,6或6,8,7或7,6,8等。
经过几天的谷歌搜索后,我发现了最小周期基础,Floyd Warshall算法的组合被命名为这种技术并可用于提取所需的最小周期图,我认为我至少在正确的道路上,请确认?
我按照“Ferreira Manuel J. Fonseca Joaquim A. Jorge的一系列线Alfredo的多边形检测”中的说明进行操作。
以下伪代码用于提取最小循环路径
***MINIMUM-CYCLE-BASIS(G)***
1 Γ ← empty set
2 Π ← ALL-PAIRS-SHORTEST-PATHS(G)
3 for each v in VERTICES(G)
4 do for each (x, y) in EDGES(G)
5 do if Π x,v ∩ Π v,y = {v}
6 then C ← Π x,v ∪ Π v,y ∪ (x, y)
7 add C to Γ
8 ORDER-BY-LENGTH(Γ)
9 return SELECT-CYCLES(Γ)
由于
答案 0 :(得分:1)
我建议采用一种更简单的方法。从任何外边缘开始,比如P1-> P2。然后检查连接到P2的每个节点PX,并选择角度(P1,P2,PX)具有最小正值的那个节点。该节点PX是多边形中的下一个节点。然后继续找到连接到PX的节点PY,其中角度(P2,PX,PY)具有最小的正值。
有几种可能的方法来计算角度。一个是:
c = inner_product( P1-P2, PX-P2 ) / ( abs(P1-P2) * abs(PX-P2) ) # cosine of the angle
s = cross_product( P1-P2, PX-P2 ) / ( abs(P1-P2) * abs(PX-P2) ) # sine of the angle
angle = atan2( s, c ) # arc tangent with correct sign
使用:
def cross_product( a, b ):
return a.x*b.y - a.y * b.x
def inner_product( a, b ):
return a.x*b.x + a.y*b.y
注意标志,这取决于CW vs CCW。当然,你可以省略标准化术语(abs...
),因为它们相互抵消
如果允许凹多边形,则必须重新规范化反正切的结果,以确保角度始终为正:
def atan2_normalized( y, x ):
angle = atan2( y, x )
if angle < 0:
return angle + 2 * Pi
else:
return angle