zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Python之路【第四十五篇】:django日更
    Python之路【第四十四篇】:django日更
    C++ 调用动态链接库
    博客园美化
    postgresql中的UUID
    使用rustup安装rust环境
    MySQL 查询做排名
    Docker
    CentOS安装Docker和基础操作
    切换CentOS7的yum源为阿里源
  • 原文地址:https://www.cnblogs.com/idy002/p/4423625.html
Copyright © 2011-2022 走看看