java march groub,凸包的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");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值