题意:给出多边形的顶点,然后在天花板有三个摄像头,找出三个摄像头的盲区。
思路:每一个摄像头 对应有一个盲区,然后把三个摄像头的盲区取交集 然后求面积就可以 这里用到了 凸包模版和半平面交模版
代码:
#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct Point{
double x,y,z;
Point(double x=0,double y=0,double z=0):x(x),y(y),z(z) {}
};
Point tmp[200];
const double eps=1e-8;
typedef Point Vector;
Vector operator -(Point A,Point B){
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator +(Point A,Point B){
return Vector(A.x+B.x,A.y+B.y);
}
Vector operator *(Vector A,double p){
return Vector(A.x*p,A.y*p);
}
double Cross(Vector A,Vector B){
return A.x*B.y-A.y*B.x;
}
int n,res[1200],top;
Point p[1200];
bool mult(Point sp,Point ep,Point op){
return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y);
}
bool cmp(Point a,Point b){
if(a.y==b.y)return a.x<b.x;
return a.y<b.y;
}
struct Line{
Point P;
Vector v;
double ang;
Line(){}
Line(Point P,Vector v):P(P),v(v){
ang=atan2(v.y,v.x);
}
bool operator <(const Line &L)const{
return ang<L.ang;
}
};
bool Onleft(Line L,Point pp){
return Cross(L.v,pp-L.P)>0;
}
Point GetIntersection(Line a,Line b){
Vector u=a.P-b.P;
double t=Cross(b.v,u)/Cross(a.v,b.v);
// cout<<t<<endl;
return a.P+a.v*t;
}
void Graham(){
int len;
top=1;
sort(p,p+n,cmp);
if(n==0)return;res[0]=0;
if(n==1)return;res[1]=1;
if(n==2)return;res[2]=2;
for(int i=2;i<n;i++){
while(top&&mult(p[i],p[res[top]],p[res[top-1]]))top--;
res[++top]=i;
}
len=top;
res[++top]=n-2;
for(int i=n-3;i>=0;i--){
while(top!=len&&mult(p[i],p[res[top]],p[res[top-1]]))top--;
res[++top]=i;
}
}
int HalfplaneIntersection(Line* L,int n,Point *poly){
sort(L,L+n);
int ft,la;
Point *pp=new Point[n];
Line *q=new Line[n];
q[ft=la=0]=L[0];
for(int i=1;i<n;++i) {
while (ft<la&&!Onleft(L[i],pp[la-1]))
--la;
while (ft<la&&!Onleft(L[i], pp[ft])) ++ft;
q[++la]=L[i];
if(fabs(Cross(q[la].v,q[la-1].v))<eps){
la--;
if (Onleft(q[la], L[i].P))
q[la]=L[i];
}
if(ft<la){
pp[la-1]=GetIntersection(q[la-1],q[la]);
// cout<<pp[la-1].x<<" "<<pp[la-1].y<<endl;
}
}
while (ft<la&&!Onleft(q[ft],pp[la-1])) --la;
if (la-ft<=1)
return 0;
pp[la]=GetIntersection(q[la],q[ft]);
int m=0;
for (int i=ft; i<=la; ++i) {
poly[m++]=pp[i];
}
return m;
}
int main()
{
Point a[3];Line l[1000];
while (cin>>n) {
for (int i=0; i<n; ++i)
cin>>tmp[i].x>>tmp[i].y>>tmp[i].z;
for (int i=0; i<3; ++i)
cin>>a[i].x>>a[i].y;
int tol=0;
for (int i=0; i<3; ++i) {
for (int j=0; j<n; ++j) {
p[j].x=-100.0*(tmp[j].x-a[i].x)/(tmp[j].z-100)+a[i].x;
p[j].y=-100.0*(tmp[j].y-a[i].y)/(tmp[j].z-100)+a[i].y;
}
Graham();
// cout<<top<<endl;
for (int j=0;j<top; ++j){
// cout<<p[j].x<<" "<<p[j].y<<endl;
l[tol++]=Line(p[res[j]],p[res[(j+1)%top]]-p[res[j]]);
}
// cout<<endl;
}
// cout<<tol<<endl;
int m=HalfplaneIntersection(l, tol, tmp);
// cout<<m<<endl;
double ans=0;
for (int i=2; i<m; ++i) {
ans+=Cross(tmp[i-1]-tmp[0],tmp[i]-tmp[0]);
}
printf("%.2f\n",ans/2.0);
}
return 0;
}