標籤:
1964: hull 三維凸包Time Limit: 1 Sec Memory Limit: 64 MB
Submit: 54 Solved: 39
[Submit][Status][Discuss]Description三維凸包問題是一個基礎的三維計算幾何問題,不過這次你只需要做一個簡單版的三維凸包問題就行了。Input輸入資料一共有若干行,每行三個整數,表示一個點的座標。點的個數為五個。Output輸出一個實數,保留兩位小數,表示三維凸包的體積。Sample Input0 0 0
2 0 0
0 2 0
2 2 0
1 1 1
Sample Output1.33
HINT
對於所有資料,座標範圍在[0,100]*[0,100]*[0,100]。
直接水過,不過網上的三維凸包的標程一個比一個不靠譜,由一組資料拍出來,加上我的程式,三個程式三個答案。整個人都不好了。
枚舉一個面,使得剩下兩個點與這條面組成四面體的有向體積符號不同,則兩點在面的兩側,計算即可。
四面體的計算公式是三個向量組成的矩陣行列式的1/6.
這是居然我的第一個三維算幾題。
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>using namespace std;#define MAXN 10typedef double real;struct point{ real x,y,z; point(real x,real y,real z):x(x),y(y),z(z){} point(){} void read() { scanf("%lf %lf %lf",&x,&y,&z); }}pl[MAXN];;real area(point p1,point p2,point p3){ return (p1.x*p2.y*p3.z + p1.z*p2.x*p3.y + p1.y*p2.z*p3.x -p1.x*p2.z*p3.y - p1.z*p2.y*p3.x - p1.y*p2.x*p3.z)/6;}point operator -(point p1,point p2){ return point(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z);}typedef point line;bool vis[MAXN];int main(){ freopen("input.txt","r",stdin); for (int i=0;i<5;i++) { pl[i].read(); }// printf("%.2lf\n",area(pl[1]-pl[0],pl[2]-pl[0],pl[3]-pl[0])); real ans=0; real s1,s2,s3; for (int a=0;a<5;a++) { vis[a]=true; for (int b=0;b<5;b++) { if (vis[b])continue; vis[b]=true; for (int c=0;c<5;c++) { if (vis[c])continue; vis[c]=true; for (int d=0;d<5;d++) { if (vis[d])continue; vis[d]=true; for (int e=0;e<5;e++) { if (vis[e])continue; vis[e]=true; s3=abs(s1=area(pl[c]-pl[a],pl[b]-pl[a],pl[d]-pl[a]))+abs(s2=area(pl[c]-pl[a],pl[b]-pl[a],pl[e]-pl[a])); if (s1*s2>0) { vis[e]=false;continue; } if (s1==0 && s2==0) { vis[e]=false;continue; } ans=max(ans,s3); vis[e]=false; } vis[d]=false; } vis[c]=false; } vis[b]=false; } vis[a]=false; } printf("%.2lf\n",ans);}
bzoj 1964: hull 三維凸包 計算幾何