JAVA凸包算法

2010062409444768.jpg

 

呵呵,有点儿像当年看着没信号的电视。。。下一步要把它用在ArcGIS Server上。

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
源码一:JarvisMarch.java

package mtn.uis.xaltin.convex;

import static java.lang.Math.abs;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class JarvisMarch {

private int count;

public int getCount() {
return count;
}

public void setCount( int count) {
this .count = count;
}

private static int MAX_ANGLE = 4 ;
private double currentMinAngle = 0 ;
private List < Point > hullPointList;
private List < Integer > indexList;
private PointFactory pf;
private Point[] ps;

public Point[] getPs() {
return ps;
}

private int firstIndex;

public int getFirstIndex() {
return firstIndex;
}

public JarvisMarch() {
this ( 10 );
}

public JarvisMarch( int count) {
pf
= PointFactory.getInstance(count);
initialize();
}

public JarvisMarch( int [] x, int [] y) {
pf
= PointFactory.getInstance(x, y);
initialize();
}

private void initialize() {
hullPointList
= new LinkedList < Point > ();
indexList
= new LinkedList < Integer > ();
firstIndex
= pf.getFirstIndex();
ps
= pf.getPoints();
addToHull(firstIndex);
}

private void addToHull( int index) {
indexList.add(index);
hullPointList.add(ps[index]);
}

public int calculateHull() {
for ( int i = getNextIndex(firstIndex); i != firstIndex; i = getNextIndex(i)) {
addToHull(i);
}
showHullPoints();
return 0 ;
}

private void showHullPoints() {
Iterator
< Point > itPoint = hullPointList.iterator();
Iterator
< Integer > itIndex = indexList.iterator();
Point p;
int i;
int index = 0 ;
System.out.println(
" The hull points is: -> " );
while (itPoint.hasNext()) {
i
= itIndex.next();
p
= itPoint.next();
System.out.print(i
+ " :( " + p.getX() + " , " + p.getY() + " ) " );
index
++ ;
if (index % 10 == 0 )
System.out.println();
}
System.out.println();
System.out.println(
" **************************************************************** " );
System.out.println(
" The count of all hull points is " + index);
}

public int getNextIndex( int currentIndex) {
double minAngle = MAX_ANGLE;
double pseudoAngle;
int minIndex = 0 ;
for ( int i = 0 ; i < ps.length; i ++ ) {
if (i != currentIndex) {
pseudoAngle
= getPseudoAngle(ps[i].getX() - ps[currentIndex].getX(),
ps[i].getY()
- ps[currentIndex].getY());
if (pseudoAngle >= currentMinAngle && pseudoAngle < minAngle) {
minAngle
= pseudoAngle;
minIndex
= i;
}
else if (pseudoAngle == minAngle){
if ((abs(ps[i].getX() - ps[currentIndex].getX()) >
abs(ps[minIndex].getX()
- ps[currentIndex].getX()))
|| (abs(ps[i].getY() - ps[currentIndex].getY()) >
abs(ps[minIndex].getY()
- ps[currentIndex].getY()))){
minIndex
= i;
}
}
}

}
currentMinAngle
= minAngle;
return minIndex;
}

public double getPseudoAngle( double dx, double dy) {
if (dx > 0 && dy >= 0 )
return dy / (dx + dy);
if (dx <= 0 && dy > 0 )
return 1 + (abs(dx) / (abs(dx) + dy));
if (dx < 0 && dy <= 0 )
return 2 + (dy / (dx + dy));
if (dx >= 0 && dy < 0 )
return 3 + (dx / (dx + abs(dy)));
throw new Error( " Impossible " );
}

}


源码二:Point.java
package mtn.uis.xaltin.convex;

public class Point {

// 定义点的x,y坐标,之所以是int类型,是为了日后可以在计算机屏幕上进行可视化。
private int x;
private int y;

// x,y的get方法
public int getX() {
return x;
}

public int getY() {
return y;
}
// 定义点到屏幕边缘的距离
private static double PADDING = 20 ;
// 点在屏幕中的范围
private static double POINT_RANGE = ( 800 - PADDING * 2 );

// 默认构造方法,产生随机点
public Point() {
this .x = ( int ) ((Math.random() * POINT_RANGE) + PADDING);
this .y = ( int ) ((Math.random() * POINT_RANGE) + PADDING);
}

// 带参构造方法,可以实现手动输入固定点
public Point( int x, int y) {
this .x = x;
this .y = y;
}

// 覆写hashCode()和equals()方法,实现比较和Hash
@Override
public int hashCode() {
final int prime = 31 ;
int result = 1 ;
result
= prime * result + x;
result
= prime * result + y;
return result;
}

@Override
public boolean equals(Object obj) {
Point other
= (Point) obj;
if ((x == other.x) && (y == other.y))
return true ;

return false ;
}


}

源码三:PointFactory.java
package mtn.uis.xaltin.convex;


public class PointFactory {
/**
* 单例模式,大批量产生Point,也可以手动产生Point
*/
private Point[] points = null ;
private int newIndex;
private int firstIndex = 0 ;

public Point[] getPoints() {
return points;
}

public int getFirstIndex() {
return firstIndex;
}

public static PointFactory getInstance() {
return new PointFactory();
}

public static PointFactory getInstance( int count) {
return new PointFactory(count);
}

public static PointFactory getInstance( int [] x, int [] y) {
return new PointFactory(x, y);
}

private PointFactory() {
this ( 10 );
}

private PointFactory( int count) {
points
= new Point[count];
for ( int i = 0 ; i < count; i ++ ) {
points[i]
= new Point();
newIndex
= i;
validatePoints();
}
firstIndex
= getFirstPoint();
}

public PointFactory( int [] x, int [] y) {
points
= new Point[y.length];
for ( int i = 0 ; i < y.length; i ++ ) {
points[i]
= new Point(x[i], y[i]);
}
firstIndex
= getFirstPoint();
}

private void validatePoints() {
for ( int i = 0 ; i < newIndex; i ++ ) {
if (points[i].equals(points[newIndex])) {
points[newIndex]
= new Point();
validatePoints();
}
}
}

public int getFirstPoint() {
int minIndex = 0 ;
for ( int i = 1 ; i < points.length; i ++ ) {
if (points[i].getY() < points[minIndex].getY()) {
minIndex
= i;
}
else if ((points[i].getY() == points[minIndex].getY())
&& (points[i].getX() < points[minIndex].getX())) {
minIndex
= i;
}
}
return minIndex;
}

}

源码四:Test.java(主函数)

package mtn.uis.xaltin.convex;


public class Test {
public static void main(String[] args) {
long start = System.currentTimeMillis();
JarvisMarch j
= new JarvisMarch( 100000 );
Point[] points
= j.getPs();
int firstIndex = j.getFirstIndex();

// for (int i = 0; i < points.length; i++) {
// System.out.print(i + ":(" + points[i].getX() + "," + points[i].getY() + ") ");
// if((i+1) % 10 == 0) {
// System.out.println();
// }
// }
// System.out.println();
// System.out.println("*****************************************************************");
System.out.println( " the first point is: " + firstIndex + " :( " +
points[firstIndex].getX()
+ " , " + points[firstIndex].getY() + " ) " );

System.out.println(
" ***************************************************************** " );
j.calculateHull();
System.out.println(
" The total running time is " + (System.currentTimeMillis() - start) + " millis. " );
}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值