if (g != pivot) {
sortedGeos.add(g);
}
}
Stack hullStack = new Stack();
hullStack.push(pivot);
Geo gCross, midCross = null;
Geo geo = null, endGeo = null, midGeo = null;
Iterator sortedGeoIt = sortedGeos.iterator();
if (sortedGeoIt.hasNext()) {
midGeo = (Geo) sortedGeoIt.next();
while (midGeo.distance(pivot) == 0 && sortedGeoIt.hasNext()) {
midGeo = (Geo) sortedGeoIt.next();
}
}
Geo lastGeoRead = midGeo;
while (sortedGeoIt.hasNext() && midGeo != null) {
geo = (Geo) sortedGeoIt.next();
double dist = geo.distance(lastGeoRead);
if (dist <= tolerance) {
// Debug.output("Skipping duplicate geo");
continue;
}
endGeo = (Geo) hullStack.peek();
midCross = endGeo.crossNormalize(midGeo);
gCross = midGeo.crossNormalize(geo);
Geo i = gCross.crossNormalize(midCross).antipode();
// Debug.output("Evaluating:\n\tendGeo: " + endGeo + "\n\tmidGeo: "
// + midGeo + "\n\tto " + geo
// + "\n ****** intersection point: " + i);
if (midGeo.distance(i) < Math.PI / 2) {
// Debug.output("+++++++++++++ midGeo to hull");
// left turn, OK for hull
hullStack.push(midGeo);
endGeo = midGeo;
midGeo = geo;
} else {
// right turn, need to backtrack
while (hullStack.size() > 1) {
// Debug.output("-------- midGeo dropped");
midGeo = (Geo) hullStack.pop();
endGeo = (Geo) hullStack.peek();
midCross = endGeo.crossNormalize(midGeo);
gCross = midGeo.crossNormalize(geo);
i = gCross.crossNormalize(midCross).antipode();
// Debug.output("Evaluating:\n\tendGeo: " + endGeo
// + "\n\tmidGeo: " + midGeo + "\n\tto " + geo
// + "\n ****** intersection point: " + i);
if (midGeo.distance(i) < Math.PI / 2) {
// Debug.output("+++++++++++++ midGeo to hull");
hullStack.push(midGeo);
midGeo = geo;
break;
}
}
}
lastGeoRead = geo;
}
if (midGeo != null) {
hullStack.push(midGeo);
}
hullStack.push(pivot);
Geo[] regionGeos = new Geo[hullStack.size()];
int i = 0;
// Need to reverse order to get inside of poly on the right side of
// line.
while (!hullStack.isEmpty()) {
regionGeos[i++] = (Geo) hullStack.pop();
}
return regionGeos;
}