teichmann@4259: package de.intevation.flys.artifacts.math;
teichmann@4259: 
teichmann@4259: 
teichmann@4259: public final class Utils {
teichmann@4259: 
teichmann@4259:     public static final double EPSILON = 1e-3;
teichmann@4259: 
teichmann@4259:     private Utils() {
teichmann@4259:     }
teichmann@4259: 
teichmann@4259:     public static final boolean epsilonEquals(double a, double b) {
teichmann@4259:         return epsilonEquals(a, b, EPSILON);
teichmann@4259:     }
teichmann@4259: 
teichmann@4259:     public static final boolean epsilonEquals(double a, double b, double eps) {
teichmann@4259:         return Math.abs(a - b) < eps;
teichmann@4259:     }
teichmann@4259: 
teichmann@4259:     public static int relativeCCW(
teichmann@4259:         double x1, double y1,
teichmann@4259:         double x2, double y2,
teichmann@4259:         double px, double py
teichmann@4259:     ) {
teichmann@4259:         if ((epsilonEquals(x1, x2) && epsilonEquals(y1, y2))
teichmann@4259:         || ((epsilonEquals(x1, px) && epsilonEquals(y1, py)))) {
teichmann@4259:             return 0; // Coincident points.
teichmann@4259:         }
teichmann@4259:         // Translate to the origin.
teichmann@4259:         x2 -= x1;
teichmann@4259:         y2 -= y1;
teichmann@4259:         px -= x1;
teichmann@4259:         py -= y1;
teichmann@4259:         double slope2 = y2 / x2;
teichmann@4259:         double slopep = py / px;
teichmann@4736:         if (epsilonEquals(slope2, slopep)
teichmann@4259:         || (epsilonEquals(x2, 0.0) && epsilonEquals(px, 0.0))) {
teichmann@4259:             return y2 > EPSILON // Colinear.
teichmann@4259:                 ? (py < -EPSILON ? -1 : py > y2 ? 1 : 0)
teichmann@4259:                 : (py > -EPSILON ? -1 : py < y2 ? 1 : 0);
teichmann@4259:         }
teichmann@4259:         if (x2 >= EPSILON && slope2 >= EPSILON) {
teichmann@4259:             return px >= EPSILON // Quadrant 1.
teichmann@4259:                 ? (slope2 > slopep ? 1 : -1)
teichmann@4259:                 : (slope2 < slopep ? 1 : -1);
teichmann@4259:         }
teichmann@4259: 
teichmann@4259:         if (y2 > EPSILON) {
teichmann@4259:             return px < -EPSILON // Quadrant 2.
teichmann@4259:                 ? (slope2 > slopep ? 1 : -1)
teichmann@4259:                 : (slope2 < slopep ? 1 : -1);
teichmann@4259:         }
teichmann@4259:         if (slope2 >= EPSILON) {
teichmann@4259:             return px >= EPSILON // Quadrant 3.
teichmann@4259:                 ? (slope2 < slopep ? 1 : -1)
teichmann@4259:                 : (slope2 > slopep ? 1 : -1);
teichmann@4259:         }
teichmann@4259:         return px < -EPSILON // Quadrant 4.
teichmann@4259:             ? (slope2 < slopep ? 1 : -1)
teichmann@4259:             : (slope2 > slopep ? 1 : -1);
teichmann@4259:     }
teichmann@4259: }