Reputation: 185
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.
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
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
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
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