我有一张多边形地图,例如:
alt text http://img13.imageshack.us/img13/2808/output.png
(对不起,图像不是那么好,我会试着稍后变得更好)
绿线是连接形状之间的最短路径。我需要做的是找到形成外边缘的绿线以及我需要走向它的方向以圈出CCW。
多边形将始终是凸的,线条永远不会交叉。这些线是根据X,Y端点定义的。我有一个从多边形到相关线的索引,它被标记为附加了哪一端。
我需要这个的原因是因为我需要找到形成每个内部部分和我的墙壁的边缘,因为外部部分解决方案失败/崩溃。
答案 0 :(得分:1)
<强> 0。澄清:我不确定凸多边形之间的绿色连接是否作为输入的一部分提供,或者程序是否必须将适当的绿色连接确定为多边形本身之间的最短路径。我刚刚注意到你的图像在右上角缺少绿色边缘(如果允许的话,它将成为外边框的一部分)。
<强> 1。解决方案:始终选择下一个边缘。如果您的输入指定允许哪些绿线,哪些不允许,那么您只需通过找到一个起点(例如,通过采用最低x的多边形角来遍历外部组件的边界) -coordinate),按逆时针顺序排序偏离当前点的多边形的绿色边缘,并选择紧跟CCW顺序当前点的边缘 。现在,将该边缘的另一端作为“当前点”并重复相同的方法以找到下一条边...直到返回第一个多边形。
<强> 2。解决方案:从凸包开始。如果允许所有可能的绿线,则不需要它们作为输入。所有多边形边缘的凸包是您解决方案的第一个近似值(查找详情---请参见下文):凸包含实际多边形边缘(让我们将它们视为“黑色”:它们是您最终解决方案的一部分,已经是正确的顺序)和连接多边形的边缘(让我们把它们想象成红色:它们需要被绿色边缘和其他多边形的部分取代)。
完成第二个解决方案:分而治之:现在,我们需要通过绿色和黑色边缘的组合来替换每个红色边缘。我们一次只关注一条红线(并对我们可能拥有的每条红线应用相同的方法)。
所以我们有一条红线包含两个多边形,它们有一条绿线(它们之间的最短连接)---这两条线的四条边定义了一个四边形。如果此四边形中没有其他多边形角,则完成:用绿色边缘替换红色边缘,将多边形上的任何黑色边缘替换为连接点。
但是如果在四边形中找到多边形,请从中选择最接近红色边缘的多边形。将红色边缘移向该点---这样新点将红色边缘切割成两个红色边缘。这两个新的红色边缘取代了一个旧的红色边缘:递归地将这个方法应用于它们。它们相应的四边形要小得多,并且包含较少的多边形边缘。
当你继续应用这种分而治之的方法时,你最终会没有剩余的红色边缘(因为每当你找到一个空的四边形时你会松开一条红色边缘)。
凸壳:这是n维难题,但在二维方面很容易:如果您搜索网络或浏览SO,您肯定会找到比我现在想象的更好的解决方案,但是这里有一个想到的(再次:分而治之):找到一个具有最大x坐标的点A和一个具有最小x坐标的点B,通过两个定向的“蓝色”边缘连接它们:A-> B和B-> A。将您的点分为两组:边缘A-> B的右侧和左侧的那些(实际上是B-> A的右侧)。我们反复更换每个蓝色边缘,直到找到凸包:
取一个蓝色边缘A-> B并查看其右侧的点。如果没有,那么这个蓝色边缘真的是黑色(解决方案的一部分)。否则,取最蓝色边缘右侧的C点,并用两个蓝色边缘A-> C和C-> B替换边缘A-> B.将A-> B右侧的点分为A-> C右侧的点,C-> B右侧的点和那些位于C-> B的右侧的点。两者都没有(他们被忽略了)。重复,直到更换所有蓝色边缘。