题意 : 求一个多边形的核的面积。
思路 : 半平面交求多边形的核,然后在求面积即可。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h> using namespace std ; struct node
{
double x;
double y ;
} p[],temp[],newp[];//p是最开始的多边形的每个点,temp是中间过程中临时存的多边形的每个点,newp是切割后的多边形的每个点
int n,newn ;//原来的点数,切割后的点数
double a,b,c ;//直线方程的三个系数 void getline(node x,node y)//求x与y两点确定的直线方程ax+by+c=0
{
a = y.y-x.y ;
b = x.x-y.x ;
c = y.x*x.y - y.y*x.x ;
}
node intersect(node x,node y)//求x与y点确定的直线与ax+by+c=0这条直线的交点
{
double u = fabs(a*x.x+b*x.y+c) ;
double v = fabs(a*y.x+b*y.y+c) ;
node t ;
t.x = (x.x*v+y.x*u)/(u+v) ;//y.y-x.y=u+v;y.y-t.y=v;y.y-x.y=u;
t.y = (x.y*v+y.y*u)/(u+v) ;
return t ;
}
void cut()
{
int cutn = ;
for(int i = ; i <= newn ; i++)
{
if(a*newp[i].x+b*newp[i].y+c >= )//所有的点都大于0,说明所有的点都在这条直线的另一边,所以不用切
temp[ ++cutn] = newp[i] ;
else
{
if(a*newp[i-].x+b*newp[i-].y+c > )
temp[++cutn ] = intersect(newp[i-],newp[i]) ;//把新交点加入
if(a*newp[i+].x+b*newp[i+].y+c > )
temp[ ++cutn] = intersect(newp[i+],newp[i]) ;
}
}
for(int i = ; i <= cutn ; i++)
newp[i] = temp[i] ;
newp[cutn+] = temp[] ;//能够找出所有点的前驱和后继
newp[] = temp[cutn] ;
newn = cutn ;
} double solve()
{
for(int i = ; i <= n ; i++)
{
newp[i] = p[i] ;
}
p[n+] = p[] ;
newp[n+] = newp[] ;
newp[] = newp[n] ;
newn = n ;
for(int i = ; i <= n ; i++)
{
getline(p[i],p[i+]) ;//从头开始顺序遍历两个相邻点。
cut() ;
}
//求多边形核的面积
double s = ;
for(int i = ; i <= newn ; i++)
s += newp[i].x*newp[i+].y-newp[i].y*newp[i+].x ;
return s = fabs(s/2.0) ;
}
void guizhenghua()
{
for(int i = ; i < (n+)/ ; i++)//规整化方向,顺时针变逆时针,逆时针变顺时针。
swap(p[i],p[n-i]) ;
}
int main()
{
int T ;
scanf("%d",&T) ;
while(T--)
{
scanf("%d",&n) ;
for(int i = ; i <= n ; i++)
scanf("%lf %lf",&p[i].x,&p[i].y) ;
double s = solve() ;
printf("%.2lf\n",s) ;
}
return ;
}