package com.revolsys.geometry.algorithm; import java.util.Comparator; import com.revolsys.geometry.model.Point; /** * Compares {@link Coordinates}s for their angle and distance * relative to an origin. * * @author Martin Davis * @version 1.7 */ class RadialComparator implements Comparator<Point> { private final double originX; private final double originY; public RadialComparator(final double originX, final double originY) { this.originX = originX; this.originY = originY; } /** * Given two points p and q compare them with respect to their radial * ordering about point o. First checks radial ordering. * If points are collinear, the comparison is based * on their distance to the origin. * <p> * p < q iff * <ul> * <li>ang(o-p) < ang(o-q) (e.g. o-p-q is CCW) * <li>or ang(o-p) == ang(o-q) && dist(o,p) < dist(o,q) * </ul> * * @param o the origin * @param p a point * @param q another point * @return -1, 0 or 1 depending on whether p is less than, * equal to or greater than q */ @Override public int compare(final Point p1, final Point p2) { final double originX = this.originX; final double originY = this.originY; final double x1 = p1.getX(); final double y1 = p1.getY(); final double x2 = p2.getX(); final double y2 = p2.getY(); final double dxp = x1 - originX; final double dyp = y1 - originY; final double dxq = x2 - originX; final double dyq = y2 - originY; final int orient = CGAlgorithmsDD.orientationIndex(originX, originY, x1, y1, x2, y2); if (orient == CGAlgorithms.COUNTERCLOCKWISE) { return 1; } else if (orient == CGAlgorithms.CLOCKWISE) { return -1; } else { // points are collinear - check distance final double op = dxp * dxp + dyp * dyp; final double oq = dxq * dxq + dyq * dyq; if (op < oq) { return -1; } else if (op > oq) { return 1; } else { return 0; } } } }