// check that this is a valid ring - if not, simply return a dummy value
if (nPts < 4) return false;
// algorithm to check if a Ring is stored in CCW order
// find highest point
Coordinate hip = ring[0];
int hii = 0;
for (int i = 1; i <= nPts; i++) {
Coordinate p = ring[i];
if (p.y > hip.y) {
hip = p;
hii = i;
}
}
// find different point before highest point
int iPrev = hii;
do {
iPrev = (iPrev - 1) % nPts;
} while (ring[iPrev].equals(hip) && iPrev != hii);
// find different point after highest point
int iNext = hii;
do {
iNext = (iNext + 1) % nPts;
} while (ring[iNext].equals(hip) && iNext != hii);
Coordinate prev = ring[iPrev];
Coordinate next = ring[iNext];
if (prev.equals(hip) || next.equals(hip) || prev.equals(next))
throw new IllegalArgumentException("degenerate ring (does not contain 3 different points)");
// translate so that hip is at the origin.
// This will not affect the area calculation, and will avoid
// finite-accuracy errors (i.e very small vectors with very large coordinates)