呵呵,有点儿像当年看着没信号的电视。。。下一步要把它用在ArcGIS Server上。
代码
源码一: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. " );
}
}
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. " );
}
}