Algorithm 以旋转木马顺序生成点的凸包算法?

Algorithm 以旋转木马顺序生成点的凸包算法?,algorithm,convex-hull,Algorithm,Convex Hull,我采用了安德森的单调链算法来寻找凸包,但在这样做之后,我发现结果点是x顺序的,而不是旋转木马顺序的。是否有一种凸包算法,可以按旋转木马的顺序生成点,也就是说围绕外壳周长的顺序 这是我的单调链实现,它不能满足我的问题: // monotone chain public static ComparablePoint[] convex_hull( ComparablePoint[] points ){ if( points.length > 1 ){ int ctPoin

我采用了安德森的单调链算法来寻找凸包,但在这样做之后,我发现结果点是x顺序的,而不是旋转木马顺序的。是否有一种凸包算法,可以按旋转木马的顺序生成点,也就是说围绕外壳周长的顺序

这是我的单调链实现,它不能满足我的问题:

// monotone chain
public static ComparablePoint[] convex_hull( ComparablePoint[] points ){
    if( points.length > 1 ){
        int ctPoints = points.length;
        int k = 0;
        ComparablePoint[] hull = new ComparablePoint[ 2 * ctPoints ];
        java.util.Arrays.sort( points );

        // Build lower hull
        for (int i = 0; i < ctPoints; ++i) {
            while (k >= 2 && crossProduct(hull[k - 2], hull[k - 1], points[i]) <= 0)
                k--;
            hull[k++] = points[i];
        }

        // Build upper hull
        for (int i = ctPoints - 2, t = k + 1; i >= 0; i--) {
            while (k >= t && crossProduct(hull[k - 2], hull[k - 1], points[i]) <= 0)
                k--;
            hull[k++] = points[i];
        }
        if (k > 1) {
            hull = java.util.Arrays.copyOfRange(hull, 0, k - 1); // remove non-hull vertices after k; remove k - 1 which is a duplicate
        }
        return hull;
    } else if( points.length <= 1 ){
        return points;
    } else{
        return null;
    }
}
//单调链
公共静态可比点[]凸包(可比点[]点){
如果(点长度>1){
int ctPoints=points.length;
int k=0;
可比点[]外壳=新的可比点[2*ctPoints];
java.util.array.sort(点);
//建造下船体
对于(int i=0;i=2&&crossProduct(壳[k-2],壳[k-1],点[i])=0;i--){
而(k>=t&叉积(壳[k-2],壳[k-1],点[i])1){
hull=java.util.Arrays.copyOfRange(hull,0,k-1);//删除k之后的非hull顶点;删除k-1,它是一个副本
}
返回船体;

}否则,如果(points.length只需将以下算法添加到您的算法中,该算法将以递增的X顺序输出点

我们将根据算法的输出生成凸包的上半部分和下半部分

让我们取凸包上的极值点。将它们命名为L和R。[L是具有最小X坐标的点,R是具有最大X坐标的点]

现在,对于所有其他点,我们将检查该点是否位于上半部分或下半部分。通过检查某点K是否位于连接L和R的线上方,或位于连接L和R的线下方,可以很容易地做到这一点

因此,我们可以在下半部分或上半部分对所有点进行分类

最后的答案是:点L[左端,即最小X]+上_部分的点以递增的X顺序,点R[右端,即最大X]+下_部分的点以递减的X顺序


注意:上述算法的复杂度为O(n),因此不会影响算法的运行时复杂度,解决方案的复杂度仍为O(n log n)添加后。

以下算法按照您的描述对外壳上的点进行排序。它类似于@AyushMishra提供的答案,但另外解决了两点具有相同X(或Y)值的情况


如何定义旋转木马的顺序而不使用一些既定的axel?正常的Graham扫描可以做到这一点。它给出了“底部”和“顶部”船体的一部分按X坐标顺序排列,因此只需反转其中一个并连接。如果您感兴趣,这里有一个java实现:@user2864740凸多边形的美妙之处在于任何内部点都可以。我想OP只是说顺时针或逆时针(多边形)命令。有人试过运行他的代码吗?!它正在以旋转木马的顺序给船体排序。-\uuuuu-这是解决问题的合理方法。如果这解决了问题,你能接受解决方案吗?
/**
 * Sorts the given array according to "merry-go-round" order. The array is
 * sorted in-place. The ordering is clockwise ending with the bottom-most
 * point.
 * 
 * @param points
 *            An array of points on a convex hull.
 */
public static void sortPoints(Point[] points) {

    // Ensure the input array is sorted by x-value
    Arrays.sort(points, (o1, o2) -> Double.compare(o1.getX(), o2.getX()));

    // get the index of the point with the smallest Y-value
    int bottomMost = 0;
    for (int i = 0; i < points.length; i++) {
        if (points[i].getY() < points[bottomMost].getY())
            bottomMost = i;
    }

    final Comparator<Point> hullComp = new Comparator<Point>() {

        @Override
        public int compare(Point o1, Point o2) {
            // handle case when Y's are the same.
            if (o1.getY() == o2.getY())
                return Double.compare(o1.getX(), o2.getX());

            // otherwise, just compare Y values
            return Double.compare(o1.getY(), o2.getY());
        }
    };

    // Sort the left side of the hull from smallest Y to largest Y
    Arrays.sort(points, 0, bottomMost, hullComp);

    // Sort the right side of the hull from largest Y to smallest Y
    Arrays.sort(points, bottomMost, points.length,
            (o1, o2) -> hullComp.compare(o2, o1));

}
jarvis(S)
   pointOnHull = leftmost point in S
   i = 0
   repeat
      P[i] = pointOnHull
      endpoint = S[0]         // initial endpoint for a candidate edge on the hull
      for j from 1 to |S|
         if (endpoint == pointOnHull) or (S[j] is on left of line from P[i] to endpoint)
            endpoint = S[j]   // found greater left turn, update endpoint
      i = i+1
      pointOnHull = endpoint
   until endpoint == P[0]      // wrapped around to first hull point