在凸面内插入一组顶点

本文关键字:一组 顶点 插入 | 更新日期: 2023-09-27 17:57:11

我想找出以无序方式给出的多边形中一组顶点的正确顺序。对于这个问题,我开发了一种基于计算几何概念的算法。首先,我得到逆时针排序的顶点集的凸包。然后,我保留按其极角排序的其余顶点,从枢轴开始,该枢轴是具有最低 X 坐标的顶点,然后我将插入然后使用我要添加的顶点和凸包中边的两个端点之间的交叉积计算的绝对值。有了这些信息,我将在其叉积上绝对值最低的两个点之间插入相应的顶点,与我上面解释的相同。

这是我的问题,这种启发式并不总是正确的,我在获取多边形顶点的排序序列时遇到问题。请务必记住,多边形可以是复杂的多边形。我想知道是否有任何算法允许我以更一致的方式做到这一点,或者有人可以帮助我改进上面解释的算法。

在这里,我的代码片段,如果还不够,请问我更多,并使用 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:如果上面解释的算法的任何步骤不清楚,并且需要更多信息来帮助我解决问题,请随时询问。

在凸面内插入一组顶点

如果你只有没有孔的2D凸区域,那么你可以很容易地做到这一点

  • (类似于您当前的方法)
  • 如果不是这种情况,请使用不同的方法,例如我的评论或链接中的
  • 链接
  • 某种多边形/三角测量算法...

1.计算面积中心(您的枢轴)

  • 只需计算平均点坐标(您的枢轴)

    x0 = (p1.x+p2.x+...pn.x)  / n
    y0 = (p1.y+p2.y+...pn.y)  / n
    

2.计算所有点的极坐标

a = atan2(p(i).x-x0,p(i).y-y0)
r = sqrt ((p(i).x-x0)^2,(p(i).y-y0)^2) // ^ is power not xor !!!
  • 对于速度,您不需要 R 平方,您可以以相同的方式使用 R^2

3.按角度对所有顶点进行排序

  • 升序或降序将决定多边形缠绕 CW/CCW
  • 根据您的坐标系配置

4.如果同一角度有多个点

  • 使用一个具有最高 R
  • 删除其余部分

5.现在您已经对顶点进行了排序

  • 这就是你想要的
如果保证顶

点形成凸多边形,则此替代方法将节省角度计算:

    在 X 上排序;
  • 检查两个极端的可能联系,并在 Y 上对它们进行排序;

  • 绘制穿过两个极点的线,并将点划分为两个子集,位于其两侧; 您将分离上轮廓部分和下轮廓部分;

  • 将线下方的点保持相同的顺序,并反转其他点。大功告成。

请注意,如果您的多边形不是凸的,则对两个子序列进行词典排序和格雷厄姆扫描的相同过程将计算凸包。