【2011 Greater New York Regional 】Problem I :The Golden Ceiling

一道比较简单但是繁琐的三维计算几何,找错误找的我好心酸,没想到就把一个变量给写错了 = =;

题目的意思是求平面切长方体的截面面积+正方体顶部所遮盖的面积;

找出所有的切点,然后二维凸包一下直接算面积即可!

发个代码纪念一下!

代码:

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define eps 1e-8
  6 using namespace std;
  7 
  8 inline int sig(double x){return (x>eps)-(x<-eps);}
  9 double w,l,hh,aa,bb,cc,dd;
 10 int num1,num2;
 11 struct point
 12 {
 13     double x,y,z;
 14     point(double x=0,double y=0,double z=0):x(x),y(y),z(z) { }
 15     bool operator < (const point &t)const
 16     {
 17         if(sig(x-t.x)==0)
 18         {
 19             return y<t.y;
 20         }
 21         else return x<t.x;
 22     }
 23     point operator+(const point&b)const{return point(x+b.x,y+b.y,z+b.z);}
 24     point operator-(const point&b)const{return point(x-b.x,y-b.y,z-b.z);}
 25     point operator*(double p){return point(x*p,y*p,z*p);}
 26     point operator/(double p){return point(x/p,y/p,z/p);}
 27 } ve[12],tu[6],vv[12],tt[6];
 28 
 29 void intersection(point a,point b)
 30 {
 31     double t=(aa*a.x+bb*a.y+cc*a.z+dd)/(aa*(a.x-b.x)+bb*(a.y-b.y)+cc*(a.z-b.z));
 32     if(t>=-eps&&t<=1.00000+eps)
 33     {
 34         point v=a+(b-a)*t;
 35         ve[num1++]=v;
 36         if(sig(v.z-hh)==0)
 37             tu[num2++]=v;
 38     }
 39 }
 40 double lenth(point a){return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);}
 41 point cross(point a,point b){return point(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);}
 42 double area(point a,point b,point c){return lenth(cross(b-a,c-a))/2.0;}
 43 double cross2(point a,point b){return a.x*b.y-a.y*b.x;}
 44 bool check(point a)
 45 {
 46     if(sig(aa*a.x+bb*a.y+cc*a.z+dd)<0)
 47         return 1;
 48     return 0;
 49 }
 50 
 51 int convexhull(point *p,int n,point* ch)
 52 {
 53     sort(p,p+n);
 54     int m=0;
 55     for(int i=0;i<n;i++)
 56     {
 57         while(m>1&&cross2(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=eps)m--;
 58         ch[m++]=p[i];
 59     }
 60     int k=m;
 61     for(int i=n-2;i>=0;i--)
 62     {
 63         while(m>k&&cross2(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=eps)m--;
 64         ch[m++]=p[i];
 65     }
 66     if(n>1)m--;
 67     return m;
 68 }
 69 
 70 int main()
 71 {
 72     int t,ca;
 73     scanf("%d",&t);
 74     while(t--)
 75     {
 76         memset(tu,0,sizeof tu);
 77         memset(ve,0,sizeof ve);
 78         memset(vv,0,sizeof vv);
 79         memset(tt,0,sizeof tt);
 80         scanf("%d",&ca);
 81         printf("%d ",ca);
 82         scanf("%lf%lf%lf%lf%lf%lf%lf",&l,&w,&hh,&aa,&bb,&cc,&dd);
 83         num1=num2=0;
 84         dd=-dd;
 85         point a(0.0,0.0,0.0);
 86         point b(l,0.0,0.0);
 87         point c(l,w,0.0);
 88         point d(0.0,w,0.0);
 89         point e(0.0,0.0,hh);
 90         point f(l,0.0,hh);
 91         point g(l,w,hh);
 92         point h(0.0,w,hh);
 93         intersection(a,b);
 94         intersection(b,c);
 95         intersection(c,d);
 96         intersection(d,a);
 97         intersection(a,e);
 98         intersection(b,f);
 99         intersection(c,g);
100         intersection(d,h);
101         intersection(e,f);
102         intersection(f,g);
103         intersection(g,h);
104         intersection(h,e);
105         if(check(e)==1)tu[num2++]=e;
106         if(check(f)==1)tu[num2++]=f;
107         if(check(g)==1)tu[num2++]=g;
108         if(check(h)==1)tu[num2++]=h;
109         int x=convexhull(ve,num1,vv);
110         int y=convexhull(tu,num2,tt);
111         double ans=0;
112         for(int i=2;i<x;i++)
113             ans+=area(vv[0],vv[i-1],vv[i]);
114         for(int i=2;i<y;i++)
115             ans+=area(tt[0],tt[i-1],tt[i]);
116         printf("%.0lf
",ceil(ans));
117     }
118     return 0;
119 }
View Code
原文地址:https://www.cnblogs.com/yours1103/p/3349157.html