三维凸包裸题。
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\n", cvx.size() ); 103 for( int t=0; t<cvx.size(); t++ ) { 104 printf( "(%.0lf,%.0lf,%.0lf) (%.0lf,%.0lf,%.0lf) (%.0lf,%.0lf,%.0lf)\n", 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\n", ans ); 126 }
时间: 2024-10-16 08:53:52