如何在简单的非凸多边形中排序顶点

时间:2011-04-04 01:44:55

标签: geometry polygon vertex-array non-convex

我有一个问题,我有一系列简单的非凸多边形的点(我希望我的术语正确)。但这些点不一定是有序的(即顺时针或逆时针)。对于Flash的绘图API来正确绘制填充区域,我需要让这些点按顺序在边缘上进行(最后连接起点)。

有没有什么方法可以顺时针或逆时针方向对笛卡尔坐标列表进行排序,这样我可以在不“拔笔”的情况下从一点到另一点画出我的形状?

我看到一个用于排序多边形4点的帖子,但我认为这只是4点的特殊情况。我的形状至少有6个点。在列表中,保证每个条目与其邻居中的至少一个(前一点或后一点)相邻(以顺时针或逆时针顺序)。例如:A,B,D,C ......或B,A,D,C ...但 A,C,B,D ...(我需要排序所以我得到A,B,C,D或D,C,B,A)。我找到了这篇文章,但似乎没有答案:Sort point list into polygon

CPU性能是个问题。但即使是一个“慢”的解决方案,如果我能够轻松实现和理解(对于下一个程序员),如果我能想出一个有效的缓存机制,也可以。

我想附上一张图片,展示我需要做的一个例子,但还没有10个声望点。无论如何,如果我有一个方法来排序这个多边形列表中第三个例子的顶点,那将是完美的:http://upload.wikimedia.org/wikipedia/commons/1/1f/Assorted_polygons.svg

我非常感谢所有人的帮助,谢谢!

编辑: 我确实可以保证坐标系的中心点 - 它将是屏幕的中心。所有点都在0和屏幕宽度/高度之间(原点显然是宽度/高度/ 2)。我不能保证多边形将在其内部包含原点。这是一个罕见的案例例外,但我需要考虑它。

顺便说一下,我的片段不一定按顺序的原因是因为它们是使用Conrec生成的:http://paulbourke.net/papers/conrec/(它们是轮廓线)。我使用以下命令对Conrec生成的轮廓线段进行排序:How to assemble an array(s) of continuous points for a contour line using Conrec现在的问题是地图上的外轮廓线。那些将与地图的边缘相交(即,不形成闭合的多边形)。在这种情况下,我画了地图边界的边缘,直到我重新连接线开始的地方(在地图的边缘)或兄弟线进入地图(重复直到我最终回到我的开始点)。然后我可以绘制一个区域并使填充API工作。希望这些信息有所帮助我认为最好的办法是生成一个有序的多边形顶点列表,但也许需要另一种方法。

4 个答案:

答案 0 :(得分:1)

我正在考虑O(n^2)算法:
由于您有绘制它们的点(希望如此),因此您知道每条边的端点。
选择一个开始点,然后继续直到与另一个边相交。
然后标记该点,继续在新边缘上,直到到达另一个边缘或端点。每当到达更改边缘的点时,请列出它。一旦达到起点,就完成了。

答案 1 :(得分:0)

嗯,你不会喜欢它,但这是不可能的。如果你考虑删除演示多边形中的所有线条,你可以用不同的方式连接它们并且仍然有一个有效的非凸多边形,那么如何知道要走哪条路呢?这就是非凸多边形的缺点。

答案 2 :(得分:0)

也许你的意思是多边形 是凸的(即它是非凹的)。否则我不认为你在做什么实际上是可能的(可能有多种方法来“加入点”并形成一个多边形)。

在这种情况下我能想到的一种技巧: 首先,列表中的前两项必须按照您给出的规则形成边缘。 然后尝试按列表顺序添加顶点;在每种情况下,如果结果只能是凹的,则从结果列表中删除前一个元素并暂时忽略它。一旦浏览了源列表,如果仍然是跳过的顶点,请继续查看跳过的顶点。

编辑:好的,只是从维基百科看了你的例子,你意味着非凸。不幸的是,我认为不可能。

答案 3 :(得分:0)

一个简单的例子表明问题不是唯一可溶的是点a =(0,0),b =(2,0),c =(1,1),d =(1,2);每个订单(a,b,c,d,a),(a,b,d,c,a)(a,c,b,d,a)都是简单的多边形。