• JAVA凸包算法


    呵呵,有点儿像当年看着没信号的电视。。。下一步要把它用在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.");
    }
    }
  • 相关阅读:
    python中函数的定义,调用,全局变量,局部变量,函数的嵌套使用初级篇
    逐行解释和整体解释的理解
    python中函数参数的详解,可变参数,关键字参数等
    python中is和==的区别
    python中的模块,以及包的导入的总结
    Python当中的a += a 与 a = a + a 的区别,可变类型与不可变类型的数据类型,引用传参
    学习Java的第七天
    学习Java的第八天
    学习java的第六天
    学习java第二天
  • 原文地址:https://www.cnblogs.com/frostbelt/p/1764192.html
Copyright © 2020-2023  润新知