计算几何之Pick定理

Pick定理

1. Pick定理的内容

假设P的内部有I(P)个格点,边界上有B(P)个格点,则P的面积A(P)为:A(P)=I(P)+B(P)/2-1

2. Pick定理的说明

Pick定理主要是计算格点多边形(定点全是格点的不自交图形)P的面积与其边界和内部格点数之间的关系。

格点多边形的面积A(P)可以通过叉积计算出来,不过叉积计算出来的面积是实际面积的2倍;边界上的格点B(P)可以通过计算相邻两点的横坐标之差与纵坐标之差的最大公约数的和得到;内部的格点I(P)则通过公式得:I(P) = A(P)-B(P)/2+1计算出。(详见代码)

3. 代码

#include<stdio.h>
#define MAXN 101


typedef struct
{
int x, y;
}tpoint;


int gcd(int a, int b)
{
if(0==b)
return a;
return gcd(b,a%b);
}
double cross(tpoint s,tpoint e)
{
return s.x*e.y-e.x*s.y;
}


int abs(int x)
{
return x>0?(x):(-x);
}
double fabs(double x)
{
return x>0?(x):(-x);
}


//Pick定理:假设P的内部有vertexNumInSide个格点,边界上有vertexNumOnEdge个格点,则P的面积area为:area=vertexNumInSide+vertexNumOnEdge/2-1


__int64 Pick(tpoint *p,int vertexNum)
{
int i;
double area=0;//面积


//计算面积
for(i=0;i<vertexNum;i++)
area=area+cross(p[i],p[(i+1)%vertexNum]);
area=fabs(area/2);//面积为实际面积的2倍,所以要除以2;面积有可能是负数,所以要求一下绝对值

//计算边界上面的格点数
__int64 vertexNumOnEdge=0;
for(i=0;i<vertexNum;i++)
vertexNumOnEdge=vertexNumOnEdge+gcd(abs(p[i].x-p[(i+1)%vertexNum].x),abs(p[i].y-p[(i+1)%vertexNum].y));

//计算内部的格点数
__int64 vertexNumInSide=0;
vertexNumInSide=area-vertexNumOnEdge/2+1;


//根据需要来,如果求面积,返回area;如果求边界上面的格点数,返回vertexNumOnEdge;如果求内部的格点数,返回vertexNumInSide
return vertexNumInSide;

}
int main()
{
int vertexNum;//顶点个数
tpoint p[MAXN];

while(scanf("%d",&vertexNum)!=EOF)
{
int i;
for(i=0;i<vertexNum; i++)
scanf("%d%d",&p[i].x,&p[i].y);
printf("%I64d\n",Pick(p,vertexNum));
}
return 0;
}

4. 练习题

Poj 1265

Poj 2954

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值