pongfactory

DP paper (Journal of RESGAT) coding (v1_8august2016)

Aug 7th, 2016
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.45 KB | None | 0 0
  1. import ij.gui.Line;
  2.  
  3. import java.awt.Point;
  4. import java.util.*;
  5.  
  6. //douglas peucker algorithm for using to reduce vertex
  7. public class DouglasPeucker{
  8.  
  9.     static final double PI_HALF = Math.PI / 2;
  10.    
  11.     public static Double euclideanDist(Point p1, Point p2) {
  12.         return Math.sqrt(Math.pow(p1.getX() - p2.getX(), 2)
  13.                 + Math.pow(p1.getY() - p2.getY(), 2));
  14.     }
  15.    
  16.     private static double getDistance(Point p, Point s, Point e) {
  17.         // Calculate the side lenghts of the triangle that is given by the three
  18.         // points.
  19.         double a = euclideanDist(p, s);
  20.         double b = euclideanDist(p, e);
  21.         double c = euclideanDist(s, e);
  22.  
  23.         // Calculate the angles of that triangle
  24.         // Due to rounding errors this values could become 1.00000004 or
  25.         // -1.0000004
  26.         // Which would lead to NaN passing them into acos
  27.         double betaCos = (b * b - a * a - c * c) / (-2 * a * c);
  28.         betaCos = Math.max(-1., Math.min(1., betaCos));
  29.         double alphaCos = (a * a - b * b - c * c) / (-2 * b * c);
  30.         alphaCos = Math.max(-1, Math.min(1., alphaCos));
  31.  
  32.         // Alpha and beta are the angles between the line base from either one
  33.         // of the line endpoints and the point whose distance should be found
  34.         double alpha = Math.acos(alphaCos);
  35.         double beta = Math.acos(betaCos);
  36.  
  37.         // Calculate the (signed) distance to a straight
  38.         double numerator = (e.getX() - s.getX())
  39.                 * (s.getY() - p.getY()) - (s.getX() - p.getX())
  40.                 * (e.getY() - s.getY());
  41.         double denominator = Math.sqrt(Math.pow(e.getX()
  42.                 - s.getX(), 2)
  43.                 + Math.pow(e.getY() - s.getY(), 2));
  44.         double signedDistance = numerator / denominator;
  45.  
  46.         if (alpha > PI_HALF || beta > PI_HALF) {
  47.             // One of the angles is bigger than 90 deg, so the distance is not
  48.             // the distance to the straight but the minimum of the distances to
  49.             // either one of the line endpoints.
  50.             // SignedDistance had to be calculated anyway to keep the correct
  51.             // sign in the result.
  52.             return signedDistance > 0 ? Math.min(a, b) : -1 * Math.min(a, b);
  53.         } else {
  54.             // None of the angles is bigger than 90 deg, so the distance is just
  55.             // the distance to a straight.
  56.             return signedDistance;
  57.         }
  58.     }
  59.    
  60.     /**
  61.      * See en.wikipedia.org/wiki/Douglas-Peucker_algorithm
  62.      * @param points
  63.      *            If less than 3 points, the algorithm cannot reduce anything.
  64.      * @param epsilon
  65.      *            Must be >= 0
  66.      * @return
  67.      */
  68.     public static ArrayList<Point> reduce(ArrayList<Point> points, double epsilon) {
  69.         int n = points.size();
  70.         if (epsilon <= 0 || n < 3) {
  71.             return points;
  72.         }
  73.  
  74.         boolean[] marked = new boolean[n];
  75.         marked[0] = marked[n - 1] = true;
  76.  
  77.         reduceRec(points, marked, epsilon, 0, n - 1);
  78.  
  79.         ArrayList<Point> result = new ArrayList<Point>(n);
  80.         for (int i = 0; i < n; i++) {
  81.             if (marked[i]) {
  82.                 result.add(points.get(i));
  83.             }
  84.         }
  85.         return result;
  86.     }
  87.  
  88.     private static void reduceRec(ArrayList<Point> points, boolean[] marked,
  89.             double epsilon, int first, int last) {
  90.         if (last <= first + 1) {
  91.             return;
  92.         }
  93.  
  94.         double maxDistance = -1.;
  95.         int maxIndex = 0;
  96.  
  97.         for (int i = first + 1; i < last; i++) {
  98.             Point current = points.get(i);
  99.             double distance = Math.abs(getDistance(current, points.get(first), points.get(last)));
  100.             if (distance > maxDistance) {
  101.                 maxDistance = distance;
  102.                 maxIndex = i;
  103.             }
  104.         }
  105.  
  106.         if (maxDistance > epsilon) {
  107.             marked[maxIndex] = true;
  108.             reduceRec(points, marked, epsilon, first, maxIndex);
  109.             reduceRec(points, marked, epsilon, maxIndex, last);
  110.         }
  111.     }
  112. }
Add Comment
Please, Sign In to add comment