// gcc polygon.c -Wall -lm
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifndef null
#define null ((void *)0)
#endif
typedef struct {
float x;
float y;
} Point;
typedef struct {
Point p1;
Point p2;
} Line;
typedef Point Vertex;
typedef Line Edge;
void *mymemset(void *s, int c, size_t n) {
int i = 0;
char *b = s;
for (; i < n; i++) {
b[i]= c;
}
return s;
}
char * const Vertex_toString(const Vertex const *v) {
const size_t BUFFSIZE = 32;
char *s = (char *)malloc(sizeof(char) * BUFFSIZE);
mymemset(s, 0, BUFFSIZE);
sprintf(s, "(%.3f,%.3f)", v->x, v->y);
return s;
}
float Vertex_distance(const Vertex const *v1, const Vertex const *v2) {
return sqrt( (v1->x -v2->x) * (v1->x - v2->x) + (v1->y - v2->y) * (v1->y - v2->y) );
}
float Vertex_angle(const Vertex const *v1, const Vertex const *v2) {
return atanf( (v2->y - v1->y) / (v2->x - v1->x) );
}
void Edge_init(Edge *e, Vertex v1, Vertex v2) {
e->p1 = v1;
e->p2 = v2;
}
float Edge_len(const Edge *const e) {
return Vertex_distance(&e->p1, &e->p2);
}
float Edge_angle(const Edge *const e) {
return Vertex_angle(&e->p1, &e->p2);
}
float absf(float v) {
return v > 0 ? v : -v;
}
float getAreaByAdjEdges(const Edge *const e1, const Edge *const e2) {
float len1 = Edge_len(e1);
float len2 = Edge_len(e2);
float theta = Edge_angle(e2) - Edge_angle(e1);
return (1.0/2) * len1 * len2 * absf( sinf(theta) );
}
typedef struct {
Vertex *v;
size_t size;
size_t cap;
} Polygon;
void Polygon_init(Polygon *p, size_t cap) {
p->size = 0;
p->cap = cap;
p->v = malloc(sizeof(Vertex) * p->cap);
}
int Polygon_addVertex(Polygon *p, Vertex v) {
if (p->size >= p->cap) {
return -1;
}
p->v[ p->size++ ] = v;
return 0;
}
Vertex *Polygon_getVertex(const Polygon *const p, int idx) {
if (idx < 0 || idx > p->size) {
return null;
}
return &p->v[ idx ];
}
float Polygon_area(Polygon *p) {
int i;
Vertex v0, v1, v2;
Edge e1, e2;
float area = 0;
for (i = 0; i < p->size-2; i++) {
v0 = *Polygon_getVertex(p, i );
v1 = *Polygon_getVertex(p, i+1 );
v2 = *Polygon_getVertex(p, i+2 );
Edge_init( &e1, v0, v1 );
Edge_init( &e2, v0, v2 );
area += getAreaByAdjEdges( &e1, &e2 );
}
return area;
}
void Polygon_print(const Polygon *p) {
if (p->size < 1) {
printf("Empty polygon.\n");
return;
}
int i;
char * s = Vertex_toString(&p->v[0]);
printf(s);
free(s);
for (i = 1; i < p->size; i++) {
s = Vertex_toString(&p->v[i]);
printf(", %s", s);
free(s);
}
printf("\n");
}
void Polygon_destroy(Polygon *p) {
free(p->v);
p->v = null;
}
int main() {
Vertex v1 = {0, 0};
Vertex v2 = {1, 2};
Vertex v3 = {2, 0};
Vertex v4 = {1, -2};
printf("Distance=%.3f\n", Vertex_distance(&v1, &v2));
Polygon p;
Polygon_init(&p, 3);
Polygon_addVertex(&p, v1);
Polygon_addVertex(&p, v2);
Polygon_addVertex(&p, v3);
Polygon_print(&p);
printf("Polygon(p) area=%.3f\n", Polygon_area(&p));
Polygon_destroy(&p);
Polygon q;
Polygon_init(&q, 4);
Polygon_addVertex(&q, v1);
Polygon_addVertex(&q, v2);
Polygon_addVertex(&q, v3);
Polygon_addVertex(&q, v4);
Polygon_print(&q);
printf("Polygon(q) area=%.3f\n", Polygon_area(&q));
Polygon_destroy(&q);
return 0;
}
求源代码
本回答被网友采纳