Polygon.java


Below is the syntax highlighted version of Polygon.java from §3.3 Modular Programming.

/*************************************************************************
 *  Compilation:  javac Polygon.java
 *  Execution:    java Polygon
 *
 *  Implementation of 2D polygon, possibly intersecting.
 *
 *  Centroid calculation assumes polygon is nonempty (o/w area = 0)
 *
 *************************************************************************/

public class Polygon { 
    private int N;        // number of points in the polygon
    private Point[] a;    // the points, setting points[0] = points[N]
   
    // default buffer = 4
    public Polygon() {
        N = 0;
        a = new Point[4];
    }


    // double size of array
    private void resize() {
        Point[] temp = new Point[2*N+1];
        for (int i = 0; i <= N; i++) temp[i] = a[i];
        a = temp;
    }

    // return size
    public int size() { return N; }

    // draw polygon
    public void draw() {
        for (int i = 0; i < N; i++)
            a[i].drawTo(a[i+1]);
    }


    // add point p to end of polygon
    public void add(Point p) {
        if (N >= a.length - 1) resize();   // resize array if needed
        a[N++] = p;                        // add point
        a[N] = a[0];                       // close polygon
    }

    // return the perimeter
    public double perimeter() {
        double sum = 0.0;
        for (int i = 0; i < N; i++)
            sum = sum + a[i].distanceTo(a[i+1]);
        return sum;
    }

    // return signed area of polygon
    public double area() {
        double sum = 0.0;
        for (int i = 0; i < N; i++) {
            sum = sum + (a[i].x() * a[i+1].y()) - (a[i].y() * a[i+1].x());
        }
        return 0.5 * sum;
    }

    // return the centroid of the polygon
    public Point centroid() {
        double cx = 0.0, cy = 0.0;
        for (int i = 0; i < N; i++) {
            cx = cx + (a[i].x() + a[i+1].x()) * (a[i].x() * a[i+1].y() - a[i].y() * a[i+1].x());
            cy = cy + (a[i].y() + a[i+1].y()) * (a[i].x() * a[i+1].y() - a[i].y() * a[i+1].x());
        }
        cx /= (6 * area());
        cy /= (6 * area());
        return new Point(cx, cy);
    }


    // does this Polygon contain the point p?
    // if p is on boundary then 0 or 1 is returned, and p is in exactly one point of every partition of plane
    // Reference: http://exaflop.org/docs/cgafaq/cga2.html
    public boolean contains(Point p) {
        int crossings = 0;
        double x = p.x(), y = p.y();
        for (int i = 0; i < N; i++) {
            int j = i + 1;
            boolean cond1 = (a[i].y() <= y) && (y < a[j].y());
            boolean cond2 = (a[j].y() <= y) && (y < a[i].y());
            boolean cond3 = x < (a[j].x() - a[i].x()) * (y - a[i].y()) / (a[j].y() - a[i].y()) + a[i].x();
            if ((cond1 || cond2)  && cond3) crossings++;
        }
        if (crossings % 2 == 1) return true;
        else                    return false; 
    }

    // return string representation of this point
    public String toString() {
        if (N == 0) return "[ ]";
        String s = "";
        s = s + "[ ";
        for (int i = 0; i <= N; i++)
            s = s + a[i] + " ";
        s = s + "]";
        return s;
    }


    // test client
    public static void main(String[] args) {
        int N = Integer.parseInt(args[0]);

        // a square
        Polygon poly = new Polygon();
        poly.add(new Point(0.5, 0.5));
        poly.add(new Point(0.7, 0.5));
        poly.add(new Point(0.7, 0.7));
        poly.add(new Point(0.5, 0.7));

        System.out.println("polygon    = " + poly);
        System.out.println("perimeter  = " + poly.perimeter());
        System.out.println("area       = " + poly.area());
        System.out.println("centroid   = " + poly.centroid());

        // generate N random points in the unit square and check what fraction are in the polygon
        int yes = 0;
        for (int i = 0; i < N; i++) {
            Point p = new Point();
            if (poly.contains(p)) yes++;
        }

        // true answer is = 0.04
        System.out.println("Fraction in circle = " + 1.0 * yes / N);


    }
}


Last updated: Sat Jan 15 12:24:16 EST 2005 .
Copyright © 2004, Robert Sedgewick and Kevin Wayne.