#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#define N 200
#define inf 1e-6
typedef struct
{
double x;
double y;
}point;
point points[N]; //点集
point chs[N]; //栈
int sp; //栈顶指针
//计算两点之间距离
double dis(point a, point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) * 1.0 + (a.y - b.y) * (a.y - b.y));
}
//通过矢量叉积求极角关系(p0p1)(p0p2)
//k > 0 ,p0p1在p0p2顺时针方向上
double multi(point p0, point p1, point p2)
{
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
int cmp(const void *p, const void *q)
{
point a = *(point *)p;
point b = *(point *)q;
double k = multi(points[0], a, b);
if(k < -inf)
return 1;
else if(fabs(k) < inf && (dis(a, points[0]) - dis(b, points[0])) > inf) //两点在同一直线上的话,用最近的
return 1;
else return -1;
}
void convex_hull(int n)
{
int i, k, d;
double miny = points[0].y;
int index = 0;
for(i=1; i<n; i++) //找最左下顶点
{
if(points[i].y < miny) //找到y坐标最小的点
{
miny = points[i].y;
index = i;
}
else if(points[i].y == miny && points[i].x < points[index].x) //相同的话找到x最小的
{
index = i;
}
}
//把最左下顶点放到第一个
point temp;
temp = points[index];
points[index] = points[0];
points[0] = temp;
qsort(points+1, n-1, sizeof(points[0]), cmp); //p[1:n-1]按相对p[0]的极角从小到大排序
chs[0] = points[n-1];
chs[1] = points[0];
sp = 1;
k = 1;
while(k <= n-1)
{
double d = multi(chs[sp], chs[sp-1], points[k]);
if(d <= 0)
{
sp++;
chs[sp] = points[k];
k++;
}
else sp--;
}
}
int main()
{
int i, j, n;
double sum, area;
while(1)
{
scanf("%d",&n);
if(n==0)break;
for(i=0; i<n; i++)
scanf("%lf%lf", &points[i].x, &points[i].y);
convex_hull(n);
sum = 0.;
for(i=1; i<=sp; i++) //求周长
sum += dis(chs[i-1], chs[i]);
sum += dis(chs[0], chs[sp]);
printf("周长:%.4f\n", sum);
area = 0.;
for(i=1; i<sp; i++) {//求面积
double k = multi(chs[0], chs[i], chs[i+1]); //三角形面积是向量叉积的1/2
area += k;
}
area = fabs(area) / 2;
printf("面积:%.4f\n", area);
}
return 0;
}
凸包求面积,周长
最新推荐文章于 2023-10-11 22:49:20 发布