分析:题目就是让你求多边形的核的面积,多边形的核就相当于在某一点能看到所有顶点(不穿过边),这些点的集合就是多边形的核。
如果有不懂地方可以看我写的求两线段交点。
# include <stdio.h>
# include <math.h>
# define EPS 1e-8
struct point
{
double x,y;
};
void Swap(point &a,point &b)//交换两点
{
point t;
t=a; a=b; b=t;
}
double Cross(point a,point b,point c)//求ab ac向量的叉积
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double Area(point v[1505],int n)//求多边形的面积
{
int i;
double ans=0;
for(i=1;i<n;i++)
ans+=Cross(v[1],v[i],v[i+1]);
return ans/2;
}
void Equation(point p1,point p2,double &a,double &b,double &c)
{//求过点p1,p2的直线ax+by+c=0
a=p2.y-p1.y;
b=p1.x-p2.x;
c=p1.y*p2.x-p1.x*p2.y;
}
point Intersection(point p1,point p2,double a,double b,double c)
{//求直线ax+by+c=0与点p1,p2的交点t
double s1,s2;
point t;
s1=fabs(a*p1.x+b*p1.y+c);
s2=fabs(a*p2.x+b*p2.y+c);
t.x=(p1.x*s2+p2.x*s1)/(s1+s2);
t.y=(p1.y*s2+p2.y*s1)/(s1+s2);
return t;
}
void Cut(double a,double b,double c,point v[1505],int &m)
{//直线ax+by+c=0切多边形v
int i,t=0;
point u[1505];
for(i=1;i<=m;i++)
{//如果点v在直线上或在直线的左侧(直线方向是按多边形逆时针方向)
if(a*v[i].x+b*v[i].y+c<EPS)
u[++t]=v[i];
else
{
if(a*v[i-1].x+b*v[i-1].y+c<-EPS)
u[++t]=Intersection(v[i-1],v[i],a,b,c);
if(a*v[i+1].x+b*v[i+1].y+c<-EPS)
u[++t]=Intersection(v[i],v[i+1],a,b,c);
}
}
for(i=1;i<=t;i++)
v[i]=u[i];
v[0]=v[t]; v[t+1]=v[1]; m=t;
}
int main()
{
int i,j,t,n,m;
double a,b,c;
point v[1505],p[1505];
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%lf%lf",&v[i].x,&v[i].y);
if(Area(v,n)<EPS)//如果给的点的顺序是顺时针,就改为逆时针
for(i=1;i<=n/2;i++)
Swap(v[i],v[n+1-i]);
v[0]=v[n]; v[n+1]=v[1]; m=n;
for(i=0;i<=n+1;i++)
p[i]=v[i];
for(i=1;i<=n;i++)
{//对原图的每一条边按逆时针方向切割一边
Equation(p[i],p[i+1],a,b,c);
Cut(a,b,c,v,m);
}
printf("%.2f\n",Area(v,m));
}
return 0;
}