您的位置:首页 > 其它

ZOJ 1010

2015-04-18 00:18 225 查看
这道题是考察计算几何的,主要有两个点。

一是根据有序输入的多边形的顶点求出任意多边形的面积,二是判断不相邻的边是否相交,如果相交则不构成多边形。

计算任意多边形的面积需要线性代数的知识,我也没接触过,详细的推导过程可以自行百度,介绍的很详细。

大体上就是将多边形切分成多个三角形,然后用各个三角形的矢量面积求和得出多边形面积。

最后,得出一个普适的公式,即



这里P(k)和P(k+1) 是多边形上连续的两点,将向量OP(k) 和 OP(k+1) 作叉乘,然后求和,注意最后一个点要和第一个点形成一组。

第二点,判断线段是否相交,当两个线段相交时,以其中一个线段的角度来看,另一个线段的两个端点在自身的两侧。

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
typedef struct
{
double x;
double y;
}coor;
coor v[1000];

double cross_product(int a,int b,int c);

int main()
{
int n,i,j,num = 0;
while(scanf("%d",&n)!=0&&n!=0)
{
int flag = 1;
double area = 0;
num++;
if(num>1)
{
printf("\n");
}
for(i = 0;i < n;i++)
{
scanf("%lf %lf",&v[i].x,&v[i].y);
}
for(i = 0;i < n&&flag;i++)
{
int t = (i+1)%n;
for(j = (i+1)/n;j < i-1;j++)
{
if(cross_product(i,j,t)*cross_product(i,j+1,t)<=0&&cross_product(j,i,j+1)*cross_product(j,t,j+1)<=0)
{
flag = 0;
break;
}
}
}
if(flag==0||n<3)
{
printf("Figure %d: Impossible\n",num);
}
else
{
for(i = 0;i < n;i++)
{
area += v[i].x * v[(i+1)%n].y - v[(i+1)%n].x * v[i].y;
}
printf("Figure %d: %.2lf\n",num,fabs(area)/2);
}
}
return 0;
}

double cross_product(int a,int b,int c)
{
coor p,q;
p.x = v[b].x - v[a].x;
p.y = v[b].y - v[a].y;
q.x = v[c].x - v[a].x;
q.y = v[c].y - v[a].y;

return p.x * q.y - q.x * p.y;
}


我也没有研究过计算几何,想要详细的了解本题算法的背后原理,请自行百度。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: