數學-幾何-離散點外接凸多邊形

 加殼工具類

public class ConvexHull {

    //排序 排序規則看Point類
    public static List<Point> makeHull(List<Point> points) {
        List<Point> newPoints = new ArrayList<>(points);
        Collections.sort(newPoints);
        return makeHullPresorted(newPoints);
    }

    //已排序 時間複雜度 O(n)
    public static List<Point> makeHullPresorted(List<Point> points) {
        if (points.size() <= 1)
            return new ArrayList<>(points);

        /*上半部分殼*/
        List<Point> upperHull = new ArrayList<>();
        for (Point p : points) {
            while (upperHull.size() >= 2) {
                Point q = upperHull.get(upperHull.size() - 1);
                Point r = upperHull.get(upperHull.size() - 2);
                if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x))
                    upperHull.remove(upperHull.size() - 1);
                else
                    break;
            }
            upperHull.add(p);
        }
        //去除和下半部分殼重複的點
        upperHull.remove(upperHull.size() - 1);

        /*下半部分殼*/
        List<Point> lowerHull = new ArrayList<>();
        for (int i = points.size() - 1; i >= 0; i--) {
            Point p = points.get(i);
            while (lowerHull.size() >= 2) {
                Point q = lowerHull.get(lowerHull.size() - 1);
                Point r = lowerHull.get(lowerHull.size() - 2);
                if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x))
                    lowerHull.remove(lowerHull.size() - 1);
                else
                    break;
            }
            lowerHull.add(p);
        }
        //去除和上半部分殼重複的點
        lowerHull.remove(lowerHull.size() - 1);

        if (!(upperHull.size() == 1 && upperHull.equals(lowerHull)))
            upperHull.addAll(lowerHull);
        return upperHull;
    }
}

Point類

public class Point implements Comparable<Point> {

    public final double x;
    public final double y;

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public String toString() {
        return String.format("Point(%g, %g)", x, y);
    }

    public boolean equals(Object obj) {
        if (!(obj instanceof Point))
            return false;
        else {
            Point other = (Point)obj;
            return x == other.x && y == other.y;
        }
    }

    public int hashCode() {
        return Objects.hash(x, y);
    }

    public int compareTo(Point other) {
        if (x != other.x)
            return Double.compare(x, other.x);
        else
            return Double.compare(y, other.y);
    }
}

Convex hull algorithm

離散點最小(凸)包圍邊界查找

C# 地圖離散點找外接凸多邊形

度度熊保護村莊 (凸包,floyd最小環)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章