package purrpackagedemo.polygon;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import purrpackagedemo.Point;
import purrpackagedemo.Region;
public class Polygon implements Region {
public static final Polygon UNIT_SQUARE = new Polygon(new Point(0, 0),
new Point(1, 0), new Point(1, 1), new Point(0, 1));
List<Point> points;
public Polygon(List<Point> points) {
this.points = points;
}
public Polygon(Point... points) {
this(Arrays.asList(points));
}
// It is inside if there are an odd number of intersections
// of polygon segments with a horizontal line through p
// to the left of p.
public boolean contains(Point p) {
if (points.size() < 3) {
return false;
}
int segmentsIntersectingToTheLeft = 0;
Iterator<Point> i = points.iterator();
Point prev = i.next();
while (i.hasNext()) {
Point current = i.next();
if (rightOfIntersection(p, prev, current)) {
++segmentsIntersectingToTheLeft;
}
}
return segmentsIntersectingToTheLeft % 2 != 0;
}
boolean rightOfIntersection(Point a, Point b, Point c) {
boolean result = false;
if (isBetween(a.y, b.y, c.y)) {
if (xIntercept(a.y, b, c) < a.x) {
result = true;
} // else intersection is to the right of a;
} // else the segment lies below or above horizontal through a;
return result;
}
// is a between b and c? The handling of >= is important
boolean isBetween(double a, double b, double c) {
return a < b ? a >= c : a < c;
}
// the x value for where the line between b and c crosses the y value
double xIntercept(double y, Point b, Point c) {
return (y - b.y) / (c.y - b.y) * (c.x - b.x) + b.x;
}
}