java 凸包_凸包的JarvisMarch算法——Java语言 | 学步园

public class JarvisMarch{

private List points;

private List hull;

private static int MAX_ANGLE = 4;

private double currentMinAngle = 0;

public JarvisMarch(List points) {

this.points = points;

this.hull = new ArrayList();

this.calculate();

}

private void calculate() {

int firstIndex = getFirstPointIndex(this.points);

this.hull.clear();

this.hull.add(this.points.get(firstIndex));//向list(hull)中添加第一个点

currentMinAngle = 0;

for (int i = nextIndex(firstIndex, this.points); i != firstIndex; i = nextIndex(

i, this.points)) {

this.hull.add(this.points.get(i));

}//向list(hull)中添加其他的点,这些点将构成一个convex hull

}

public void remove(T item) {

if (!hull.contains(item)) {

points.remove(item);

return;

}

points.remove(item);

// TODO

calculate();

}

public void remove(List items){

points.removeAll(items);

calculate();

}

public void add(T item) {

points.add(item);

List tmplist = new ArrayList();

tmplist.addAll(hull);

tmplist.add(item);

List tmphull = new ArrayList();

int firstIndex = getFirstPointIndex(tmplist);

tmphull.add(tmplist.get(firstIndex));

currentMinAngle = 0;

for (int i = nextIndex(firstIndex, tmplist); i != firstIndex; i = nextIndex(

i, tmplist)) {

tmphull.add(tmplist.get(i));

}

this.hull = tmphull;

}

public void add(List items) {

points.addAll(items);

List tmplist = new ArrayList();

tmplist.addAll(hull);

tmplist.addAll(items);

List tmphull = new ArrayList();

int firstIndex = getFirstPointIndex(tmplist);

tmphull.add(tmplist.get(firstIndex));

currentMinAngle = 0;

for (int i = nextIndex(firstIndex, tmplist); i != firstIndex; i = nextIndex(

i, tmplist)) {

tmphull.add(tmplist.get(i));

}

this.hull = tmphull;

}

public List getHull() {

return this.hull;

}

private int nextIndex(int currentIndex, List points) {

double minAngle = MAX_ANGLE;

double pseudoAngle;

int minIndex = 0;

for (int i = 0; i < points.size(); i++) {

if (i != currentIndex) {

pseudoAngle = getPseudoAngle(

points.get(i).x() - points.get(currentIndex).x(),

points.get(i).y() - points.get(currentIndex).y());

if (pseudoAngle >= currentMinAngle && pseudoAngle < minAngle) {

minAngle = pseudoAngle;

minIndex = i;

} else if (pseudoAngle == minAngle) {

if ((Math.abs(points.get(i).x()

- points.get(currentIndex).x()) > Math.abs(points

.get(minIndex).x() - points.get(currentIndex).x()))

|| (Math.abs(points.get(i).y()

- points.get(currentIndex).y()) > Math

.abs(points.get(minIndex).y()

- points.get(currentIndex).y()))) {

minIndex = i;

}

}

}

}

currentMinAngle = minAngle;

return minIndex;

}

//获得起始点

private int getFirstPointIndex(List points) {

int minIndex = 0;

for (int i = 1; i < points.size(); i++) {

if (points.get(i).y() < points.get(minIndex).y()) {

minIndex = i;

} else if ((points.get(i).y() == points.get(minIndex).y())

&& (points.get(i).x() < points.get(minIndex).x())) {

minIndex = i;

}

}

return minIndex;

}

private double getPseudoAngle(double dx, double dy) {

if (dx > 0 && dy >= 0)

return dy / (dx + dy);

if (dx <= 0 && dy > 0)

return 1 + (Math.abs(dx) / (Math.abs(dx) + dy));

if (dx < 0 && dy <= 0)

return 2 + (dy / (dx + dy));

if (dx >= 0 && dy < 0)

return 3 + (dx / (dx + Math.abs(dy)));

throw new Error("Impossible");

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java语言中实现凸包算法可以使用 Graham 扫描算法。以下是一个简单的示例代码: ```java import java.util.*; public class ConvexHull { public static List<Point> convexHull(List<Point> points) { // 如果点的数量小于等于1,则返回点列表 if (points.size() <= 1) { return points; } // 对点按照x坐标进行排序 Collections.sort(points); // 创建一个栈来保存凸包上的点 Stack<Point> stack = new Stack<>(); // 将前两个点加入栈中 stack.push(points.get(0)); stack.push(points.get(1)); // 从第三个点开始,依次判断是否为凸包上的点 for (int i = 2; i < points.size(); i++) { Point top = stack.pop(); while (!stack.isEmpty() && orientation(stack.peek(), top, points.get(i)) <= 0) { top = stack.pop(); } stack.push(top); stack.push(points.get(i)); } // 将栈中的点转换成列表 List<Point> hull = new ArrayList<>(stack); Collections.reverse(hull); return hull; } // 判断点a、b、c的方向 public static int orientation(Point a, Point b, Point c) { return (b.y - a.y) * (c.x - b.x) - (b.x - a.x) * (c.y - b.y); } public static void main(String[] args) { List<Point> points = new ArrayList<>(); points.add(new Point(0, 0)); points.add(new Point(1, 1)); points.add(new Point(2, 2)); points.add(new Point(3, 3)); points.add(new Point(0, 3)); List<Point> hull = convexHull(points); System.out.println("Convex Hull:"); for (Point p : hull) { System.out.println(p); } } } class Point implements Comparable<Point> { int x, y; public Point(int x, int y) { this.x = x; this.y = y; } @Override public int compareTo(Point other) { if (this.x == other.x) { return Integer.compare(this.y, other.y); } return Integer.compare(this.x, other.x); } @Override public String toString() { return "(" + x + ", " + y + ")"; } } ``` 在上面的代码中,我们定义了一个 `Point` 类来表示一个二维点,然后实现了 `convexHull` 方法来计算给定点集的凸包。最后,我们在 `main` 方法中测试了这个算法,并输出了计算结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值