【发布时间】:2014-04-06 16:00:46
【问题描述】:
我想找出以无序方式给出的多边形中一组顶点的正确顺序。对于这个问题,我开发了一种基于计算几何概念的算法。首先,我得到按逆时针方向排序的顶点集的凸包。然后,我保留按其极角排序的剩余顶点,从作为具有最低 X 坐标的顶点的枢轴开始,然后我将使用要添加的顶点之间的叉积计算的绝对值插入以及凸包中边的两个端点。有了这些信息,我将在叉积上绝对值最低的两点之间插入相应的顶点,就像我上面解释的那样。
这是我的问题,这种启发式方法并不总是正确的,我在获取多边形顶点的排序序列时遇到了问题。重要的是要记住,多边形可能是一个复杂的多边形。我想知道是否有任何算法可以让我以更一致的方式做到这一点,或者有人可以帮助我改进上面解释的算法。
这里是我的代码的 sn-p,如果还不够,请询问我更多信息,并使用 c# 和 .NET 4.5:
var CH = JarvisMarch(P); // P is the set of unsorted vertex of the polygon
var V = (from v in P where !CH.Contains(v) select v).ToArray();
var pivot = (from v in V orderby v.Y, v.X select v).FirstOrDefault();
if (CH.Count < P.Length)
{
QuickSortPolar(ref V, 0, V.Length - 1, pivot);
foreach (var rm in V)
{
var C = CH.ToArray();
var T = new RedBlackTree(); // this is not entirely necessary
var wlk = new List<IComparable>();
var min = float.MaxValue;
var succ = default(GeometryVertex); // this structure have the X and Y coordenate of the vertex
QuickSortCoorX(ref C, 0, C.Length - 1); // for the sweep plane algorithm
for (int i = 0; i < C.Length; i++) // this is just to build the segments in a appropriate way
{
var j = CH.IndexOf(C[i]) == CH.Count - 1 ?
0 : CH.IndexOf(C[i]) + 1;
var sgm = new GeometrySegment()
{
Start = CH[j == 0 ? CH.Count - 1 : j - 1],
End = CH[j]
};
var find = T.Search(sgm);
if (find == null || find == RedBlackTree.sentinel)
T.Insert(sgm);
}
T.Inorder(T.root, ref wlk);
foreach (var sgm in wlk) // Here is the key of the algorithm
{
var s = (GeometrySegment)sgm;
var curr = (float)Math.Abs(cw(s.Start, rm, s.End));
if (curr < min || (curr == min && s.End < succ))
{
min = curr;
succ = s.End;
}
}
CH.Insert(CH.IndexOf(succ), rm);
}
提前致谢!!
PD:如果上述算法的任何步骤不清楚,并且需要更多信息来帮助我解决问题,请随时提问。
【问题讨论】:
-
你有一组分散的点,想找到一个最小长度的环,连接所有这些点?
-
确实如此,可能是出现问题的一种方式,但仍然需要以排序方式的顶点
-
你的问题会是这样的吗? en.wikipedia.org/wiki/Hamiltonian_cycle 这看起来更像是一个几何问题,而不仅仅是一个编程问题。
-
看这里stackoverflow.com/q/21816562/2521214 我的部分答案包含多边形化(找到正确的顶点顺序),您必须稍微调整一下(反转地图使用),因为该代码会找到孔并且您想找到区域相反...