求半平面交的面积
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define Maxn 1100
struct P {double x,y;};
struct L {P a,b;double slop;}l[Maxn];
//半平面只方向向量a->b的左部分
//slop 极角
int cnt;
P operator - (P x,P y)
{
P tt;
tt.x=x.x-y.x;
tt.y=x.y-y.y;
return tt;
}
P operator + (P x,P y)
{
P tt;
tt.x=x.x+y.x;
tt.y=x.y+y.y;
return tt;
}
double Dot(P x,P y) {return x.x*y.x+x.y*y.y;}
double Cross(P x,P y) {return x.x*y.y-x.y*y.x;}
bool operator < (L a,L b)
{
if(a.slop!=b.slop)return a.slop<b.slop;
return Cross(a.b-a.a,b.b-a.a)>0;
}
P operator * (P X,double y)
{
P tt;
tt.x=X.x*y;
tt.y=X.y*y;
return tt;
}
P a[Maxn];
L q[Maxn];
int tot;
P inter(L a,L b)
{
P X=a.a-a.b,Y=b.a-b.b,nw;
double tt;
nw=b.a-a.a;
tt=Cross(nw,X)/Cross(X,Y);
P ans=b.a+Y*tt;
return ans;
}
bool jud(L a,L b,L c)
{
P p=inter(a,b);
return Cross(c.b-c.a,p-c.a)<0;
}
void opp()
{
for(int i=1;i<=cnt;i++)
{
printf("%.2lf %.2lf %.2lf %.2lf = %.2lf \n",l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y,l[i].slop);
}
printf("\n");
}
void output()
{
for(int i=1;i<=tot;i++) printf("%2lf %.2lf\n",a[i].x,a[i].y);
printf("\n");
}
void op(int L,int R)
{
for(int i=L;i<=R;i++)
printf("%lf %lf %lf %lf\n",l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y);
printf("\n");
}
void ffind()
{
for(int i=1;i<=cnt;i++)
l[i].slop=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);
sort(l+1,l+1+cnt);
// opp();
int L=1,R=0;
//去重?
tot=0;
for(int i=1;i<=cnt;i++)
{
if(l[i].slop!=l[i-1].slop) tot++;
l[tot]=l[i];
}
cnt=tot;tot=0;
// opp();
q[++R]=l[1];q[++R]=l[2];
for(int i=3;i<=cnt;i++)
{
while(L<R&&jud(q[R-1],q[R],l[i])) R--;
while(L<R&&jud(q[L+1],q[L],l[i])) L++;
q[++R]=l[i];
// op(L,R);
}
if(L<R&&jud(q[R-1],q[R],q[L])) R--;
op(L,R);
q[R+1]=q[L];
for(int i=L;i<=R;i++)
a[++tot]=inter(q[i],q[i+1]);
// output();
}
void init()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf\n",&l[i].a.x,&l[i].a.y,&l[i].b.x,&l[i].b.y);
}
cnt=n;
}
void get_area()
{
double ans=0;
for(int i=1;i<tot;i++)
{
ans+=Cross(a[i],a[i+1]);
}
ans+=Cross(a[tot],a[1]);
if(tot<3) ans=0;
printf("%.3lf\n",ans/2);
}
int main()
{
init();
ffind();
get_area();
return 0;
}
没有删调试的。
输入半平面,输出面积。
样例:
6
4 5 2 0
9 2 5 6
3 1 9 5
5 1 7 5
8 2 9 4
5 7 3 5
输出:
10.459
2016-12-25 14:39:14