Out Of Bounds
Out Of Bounds

Reputation: 185

Computing area of a polygon in Java

I have a class called SimplePolygon that creates a polygon with coordinates provided by the user. I am trying to define a method to compute the area of the polygon. It's an assignment and course instructor wants us to use the following formula to compute the area.

Formula for polygon area

I can use either formula. I chose the right one.

My code gives me the wrong area. I don't know what's wrong.

public class SimplePolygon implements Polygon {

  protected int n; // number of vertices of the polygon
  protected Point2D.Double[] vertices; // vertices[0..n-1] around the polygon

  public double area() throws NonSimplePolygonException {
    try 
    {
        if(isSimple()==false)
            throw new NonSimplePolygonException();
        else
        {
            double sum = 0;
            for(int i = 0; i < vertices.length - 1; i++)
                if(i == 0)
                    sum += vertices[i].x * (vertices[i+1].y - vertices[vertices.length - 1].y);
                else
                    sum += vertices[i].x * (vertices[i+1].y - vertices[i-1].y);

            double area = 0.5 * Math.abs(sum);
            return area;
        }
    }

    catch(NonSimplePolygonException e)
    {
        System.out.println("The Polygon is not simple.");
    }

    return 0.0;

}

The following is a tester code. The polygon is a rectangle with area 2, but the output is 2.5

    Point2D.Double a = new Point2D.Double(1,1);
    Point2D.Double b = new Point2D.Double(3,1);
    Point2D.Double c = new Point2D.Double(3,2);
    Point2D.Double d = new Point2D.Double(1,2);

    SimplePolygon poly = new SimplePolygon(4);
    poly.vertices[0] = a;
    poly.vertices[1] = b;
    poly.vertices[2] = c;
    poly.vertices[3] = d;

    System.out.println(poly.area());

Upvotes: 2

Views: 10351

Answers (3)

Saurabh Khare
Saurabh Khare

Reputation: 1277

I found another way,

Add first element again into polygon array

So that we can avoid "Out of bound" case as well as many If conditions.

Here is my solution:

public class PolygonArea {

public static void main(String[] args) {
    PolygonArea p = new PolygonArea();
    System.out.println(p.calculateArea());
}

Point[] points = new Point[5];
public double calculateArea() {
    points[0] = new Point("A", 4, 10);
    points[1] = new Point("B", 9, 7);
    points[2] = new Point("C", 11, 2);
    points[3] = new Point("D", 2, 2);

    /** Add first entry again to polygon */
    points[4] = new Point("A", 4, 10);

    double sum = 0.0;

    for (int i = 0; i < points.length - 1; ++i) {
        sum += (points[i].X * points[i + 1].Y) - (points[i + 1].X * points[i].Y);
    }

    return Math.abs(sum / 2);
}

class Point {
    final String _ID;
    final int X;
    final int Y;

    public Point(String id, int x, int y) {
        _ID = id;
        X = x;
        Y = y;
    }

  }
}

Upvotes: 1

Henry
Henry

Reputation: 43788

There is one missing term from the sum: vertices[n-1].x * (vertices[0].y - vertices[n-2].y).

Before the edit of the question there was also a problem with the first term:

Furthermore, if i==0 the term should be vertices[i].x * (vertices[i+1].y - vertices[n-1].y).

Assuming that n is equal to vertices.length.

The simplest way to code the loop is probably:

n = vertices.length;
sum =0;
for (int i = 0; i < n; i++) {
    sum += vertices[i].x * (vertices[(i + 1) % n].y - vertices[(i + n - 1) % n].y);
}

Upvotes: 3

Evan Knowles
Evan Knowles

Reputation: 7511

Now that you've fixed the trivial boundary case, you're missing another boundary and your loop is wrong. Corrected code with debug:

 public double area()
  {
    double sum = 0;
    for (int i = 0; i < vertices.length ; i++)
    {
      if (i == 0)
      {
        System.out.println(vertices[i].x + "x" + (vertices[i + 1].y + "-" + vertices[vertices.length - 1].y));
        sum += vertices[i].x * (vertices[i + 1].y - vertices[vertices.length - 1].y);
      }
      else if (i == vertices.length - 1)
      {
        System.out.println(vertices[i].x + "x" + (vertices[0].y + "-" + vertices[i - 1].y));
        sum += vertices[i].x * (vertices[0].y - vertices[i - 1].y);
      }
      else
      {
        System.out.println(vertices[i].x + "x" + (vertices[i + 1].y + "-" + vertices[i - 1].y));
        sum += vertices[i].x * (vertices[i + 1].y - vertices[i - 1].y);
      }
    }

    double area = 0.5 * Math.abs(sum);
    return area;

  }

Upvotes: 5

Related Questions