您的位置:首页 > 其它

POJ 3528 Ultimate Weapon(三维凸包表面积)

2012-12-28 21:16 543 查看
题目链接:http://poj.org/problem?id=3528

题意:求三维凸包表面积。

思路:模板。

struct Point
{
double x,y,z;

Point() {}
Point(double _x,double _y,double _z)
{
x=_x;
y=_y;
z=_z;
}

void Get()
{
RD(x,y,z);
}
Point operator-(const Point p1)
{
return Point(x-p1.x,y-p1.y,z-p1.z);
}

Point operator*(Point p)
{
return Point(y*p.z-z*p.y,z*p.x-x*p.z,x*p.y-y*p.x);
}
double operator^(Point p)
{
return x*p.x+y*p.y+z*p.z;
}

double len()
{
return sqrt(sqr(x)+sqr(y)+sqr(z));
}
};

struct _3DCH
{
struct face
{
int a,b,c,ok;

face(){}
face(int _a,int _b,int _c,int _ok)
{
a=_a;
b=_b;
c=_c;
ok=_ok;
}
}F[N<<2];
int n,cnt,b

;
Point p
;

int DB(double x)
{
if(x>1e-10) return 1;
if(x<-1e-10) return -1;
return 0;
}

double vlen(Point a)
{
return a.len();
}

double getArea(Point a,Point b,Point c)
{
return vlen((b-a)*(c-a));
}

double getVolume(Point a,Point b,Point c,Point d)
{
return (b-a)*(c-a)^(d-a);
}

//t在f的正面返回1,反面返回-1,在f上返回0
int getDir(Point t,face f)
{
double x=(p[f.b]-p[f.a])*(p[f.c]-p[f.a])^(t-p[f.a]);
return DB(x);
}

void deal(int i,int x,int y)
{
int f=b[x][y];
face temp;
if(!F[f].ok) return;
if(getDir(p[i],F[f])>0) DFS(i,f);
else
{
temp=face(y,x,i,1);
b[y][x]=b[x][i]=b[i][y]=cnt;
F[cnt++]=temp;
}
}

void DFS(int i,int j)
{
F[j].ok=0;
deal(i,F[j].b,F[j].a);
deal(i,F[j].c,F[j].b);
deal(i,F[j].a,F[j].c);
}

void construct()
{
if(n<4) return;
int i,j,k=0;
FOR1(i,n-1) if(DB(vlen(p[0]-p[i])))
{
swap(p[1],p[i]);
k=1;
break;
}
if(!k) return;
k=0;
FOR(i,2,n-1) if(DB(getArea(p[0],p[1],p[i])))
{
swap(p[2],p[i]);
k=1;
break;
}
if(!k) return;;
k=0;
FOR(i,3,n-1) if(DB(getVolume(p[0],p[1],p[2],p[i])))
{
swap(p[3],p[i]);
k=1;
break;
}
if(!k) return;

cnt=0;
face temp;
FOR0(i,4)
{
temp=face((i+1)%4,(i+2)%4,(i+3)%4,1);
if(getDir(p[i],temp)>0) swap(temp.b,temp.c);
b[temp.a][temp.b]=b[temp.b][temp.c]=b[temp.c][temp.a]=cnt;
F[cnt++]=temp;
}

FOR(i,4,n-1) FOR0(j,cnt) if(F[j].ok&&getDir(p[i],F[j])>0)
{
DFS(i,j);
break;
}
j=0;
FOR0(i,cnt) if(F[i].ok) F[j++]=F[i];
cnt=j;
}

double getSumArea()
{
double ans=0;
int i;
FOR0(i,cnt) ans+=getArea(p[F[i].a],p[F[i].b],p[F[i].c]);
return ans/2;
}
};

_3DCH a;

int main()
{
while(scanf("%d",&a.n)!=-1)
{
int i;
FOR0(i,a.n) a.p[i].Get();
a.construct();
double s=a.getSumArea();
printf("%.3lf\n",s);
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: