bzoj 1209

三维凸包裸题。

1、通过volume计算有向体积,判断点与面的位置关系。

2、噪声

  1 /**************************************************************
  2     Problem: 1209
  3     User: idy002
  4     Language: C++
  5     Result: Accepted
  6     Time:20 ms
  7     Memory:1864 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cstdlib>
 12 #include <cmath>
 13 #include <vector>
 14 #define eps 1e-10
 15 #define N 1000
 16 using namespace std;
 17  
 18 struct Vector {
 19     double x, y, z;
 20     void read() {
 21         scanf( "%lf%lf%lf", &x, &y, &z );
 22     }
 23     Vector(){}
 24     Vector( double x, double y, double z ):x(x),y(y),z(z){}
 25     Vector operator+( const Vector &b ) const { return Vector(x+b.x,y+b.y,z+b.z); }
 26     Vector operator-( const Vector &b ) const { return Vector(x-b.x,y-b.y,z-b.z); }
 27     Vector operator*( double b ) const { return Vector(x*b,y*b,z*b); }
 28     Vector operator/( double b ) const { return Vector(x/b,y/b,z/b); }
 29     double operator&( const Vector &b ) const { return x*b.x+y*b.y+z*b.z; }
 30     Vector operator^( const Vector &b ) const { return Vector(y*b.z-z*b.y,z*b.x-x*b.z,x*b.y-y*b.x); }
 31     double len() { return sqrt(x*x+y*y+z*z); }
 32 };
 33 typedef Vector Point;
 34 struct Face {
 35     int p[3];
 36     Face(){}
 37     Face( int a, int b, int c ) {
 38         p[0]=a, p[1]=b, p[2]=c;
 39     }
 40 };
 41 typedef vector<Face> Convex;
 42  
 43 int n;
 44 Point pts[N];
 45 bool vis[N][N];
 46  
 47 double rand01() {
 48     return (double) rand()/RAND_MAX;
 49 }
 50 double randeps() {
 51     return (rand01()-0.5)*eps;
 52 }
 53 void noise() {
 54     for( int i=0; i<n; i++ ) {
 55         pts[i].x += randeps();
 56         pts[i].y += randeps();
 57         pts[i].z += randeps();
 58     }
 59 }
 60 double volume( int p, int a, int b, int c ) {
 61     return (pts[a]-pts[p])&((pts[b]-pts[a])^(pts[c]-pts[a]))/6.0;
 62 }
 63 bool cansee( Face &f, int p ) {
 64     return volume(p,f.p[0],f.p[1],f.p[2]) < 0.0;
 65 }
 66 Convex convex() {
 67     static Point back[N];
 68     for( int i=0; i<n; i++ )
 69         back[i] = pts[i];
 70     noise();
 71  
 72     int nt[] = { 1, 2, 0 };
 73     if( n<=2 ) return Convex();
 74  
 75     Convex cur;
 76     cur.push_back( Face(0,1,2) );
 77     cur.push_back( Face(2,1,0) );
 78     for( int i=3; i<n; i++ ) {
 79         Convex nxt;
 80         for( int t=0; t<cur.size(); t++ ) {
 81             Face &f = cur[t];
 82             bool see = cansee( f, i );
 83             if( !see ) nxt.push_back(f);
 84             for( int j=0; j<3; j++ )
 85                 vis[f.p[j]][f.p[nt[j]]] = see;
 86         }
 87         for( int t=0; t<cur.size(); t++ ) {
 88             Face &f = cur[t];
 89             for( int j=0; j<3; j++ ) {
 90                 int a=f.p[j], b=f.p[nt[j]];
 91                 if( (vis[a][b]^vis[b][a]) && vis[a][b] ) 
 92                     nxt.push_back( Face(a,b,i) );
 93             }
 94         }
 95         cur = nxt;
 96     }
 97     for( int i=0; i<n; i++ )
 98         pts[i] = back[i];
 99     return cur;
100 }
101 void print( Convex &cvx ) {
102     fprintf( stderr, "%d
", cvx.size() );
103     for( int t=0; t<cvx.size(); t++ ) {
104         printf( "(%.0lf,%.0lf,%.0lf) (%.0lf,%.0lf,%.0lf) (%.0lf,%.0lf,%.0lf)
", 
105                 pts[cvx[t].p[0]].x, pts[cvx[t].p[0]].y, pts[cvx[t].p[0]].z,
106                 pts[cvx[t].p[1]].x, pts[cvx[t].p[1]].y, pts[cvx[t].p[1]].z,
107                 pts[cvx[t].p[2]].x, pts[cvx[t].p[2]].y, pts[cvx[t].p[2]].z );
108     }
109 }
110 double area( int a, int b, int c ) {
111     return ((pts[a]-pts[b])^(pts[a]-pts[c])).len() / 2.0;
112 }
113  
114 int main() {
115     scanf( "%d", &n );
116     for( int i=0; i<n; i++ )
117         pts[i].read();
118     Convex cvx = convex();
119  
120 //  print( cvx );
121  
122     double ans = 0.0;
123     for( int i=0; i<cvx.size(); i++ ) 
124         ans += area( cvx[i].p[0], cvx[i].p[1], cvx[i].p[2] );
125     printf( "%.6lf
", ans );
126 }
View Code
原文地址:https://www.cnblogs.com/idy002/p/4423625.html