Below is my program that determines the perimeter and area of a polygon given a certain amount of (x,y) coordinates but I seem to be getting the wrong output and I can't see why.
The input is:
3 12867 1.0 2.0 1.0 5.0 4.0 5.0
5 15643 1.0 2.0 4.0 5.0 7.8 3.5 5.0 0.4 1.0 0.4
With the first entry being the number of points (points) and the second entry being the polygon ID, anything after that is a set of coordinates.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_PTS 100
#define MAX_POLYS 100
#define END_INPUT 0
struct Point {
double x, y;
};
double getDistance(struct Point a, struct Point b) {
double distance;
distance = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y));
return distance;
}
double polygon_area(int length, double x[], double y[]) {
double area = 0.0;
for (int i = 0; i < length; ++i) {
int j = (i + 1) % length;
area += (x[i] * y[j] - x[j] * y[i]);
}
area = area / 2;
area = (area > 0 ? area : -1 * area);
return (area);
}
int main(int argc, char *argv[]) {
int npoints, poly_id;
struct Point a, b;
if(scanf("%d %d", &npoints, &poly_id)) {
int iteration = 0;
scanf("%lf %lf", &a.x, &a.y);
struct Point initialPoint = a;
double perimeter = 0; // i start with 0 value of parameter.
for (iteration = 1; iteration < npoints; ++iteration) {
scanf("%lf %lf", &b.x, &b.y); // take input for new-point.
perimeter += getDistance(a, b); // add the perimeter.
// for next iteration, new-point would be first-point in getDistance
a = b;
}
// now complete the polygon with last-edge joining the last-point
// with initial-point.
perimeter += getDistance(a, initialPoint);
printf("First polygon is %d\n", poly_id);
printf("perimeter = %2.2lf m\n", perimeter);
scanf("%d %d", &npoints, &poly_id);
double x[MAX_PTS], y[MAX_PTS];
double area = 0;
for (iteration = 0; iteration < npoints; ++iteration) {
scanf("%lf %lf", &(x[iteration]), &(y[iteration]));
}
area = polygon_area(npoints, x, y);
printf("First polygon is %d\n", poly_id);
printf("area = %2.2lf m^2\n", area);
} else if(scanf("%d", &npoints)==0) {
exit(EXIT_SUCCESS);
}
return 0;
}
My output I keep getting is:
First polygon is 12867
perimeter = 10.24 m
First polygon is 15643
area = 19.59 m^2
But the output I want is:
First polygon is 12867
perimeter = 10.24 m
First polygon is 12867
area = 4.50 m^2
Or alternatively:
First polygon is 12867
perimeter = 10.24 m
area = 4.50 m^2
Would be appreciated if someone could just point out where I've gone wrong.
If you haven't sorted it out yet, your problem is obvious. You read the data for the first polygon and then you calculate the
perimeter
:Then, inexplicably, you read data for your second polygon before calculating the area:
How you expect to get the area for the first polygon using data for the second polygon is a bit bewildering.
What you need to do is calculate both the
perimeter
and thearea
for each polygon before reading the data for the next. Rather than yourif
block of code, you would usually prompt to enter thenumber of polygons
to process and then do something like:Next, when you expect data from a user, prompt for it. Don't just leave the user looking at a blinking cursor wondering if your program hung, etc.. A simple
printf
asking for the number of points and polygon id works fine. Then a like prompt to enter each x/y pair goes a long way to eliminating confusion. Taking all the above into consideration, your code could be re-written as:But why not write an input routine for your code to read your data file and eliminate the error prone user input? It takes a little time, but it's not hard. That way you can completely separate the input and processing functions of your code.
That frees you to actually concentrate on laying the processing part of your code out in a logical manner, instead of having the processing logic sprinkled with user input. The following is an example of how separating input from the logic of your code can help keep your code clean and readable. It reads all data into an array of structures before beginning the first computation.
When you keep your code separated into logical function, it makes maintaining any individual computation like
perimeter
orarea
a simple matter of adjusting the logic of a single function. Take a look at the following and let me know if you have questions:Input
Output