POJ 3528 求三维凸包表面积
也是用模板直接套的题目诶
- //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
- #include <stdio.h>
- #include <iostream>
- #include <cstring>
- #include <cmath>
- #include <stack>
- #include <queue>
- #include <vector>
- #include <algorithm>
- #define ll long long
- #define Max(a,b) (((a) > (b)) ? (a) : (b))
- #define Min(a,b) (((a) < (b)) ? (a) : (b))
- #define Abs(x) (((x) > 0) ? (x) : (-(x)))
- using namespace std;
- const int INF = 0x3f3f3f3f;
- const int MAXN = ;
- const double eps = 1e-;
- struct Point{
- double x,y,z;
- Point(){}
- Point(double xx,double yy,double zz):x(xx),y(yy),z(zz){}
- //两向量之差
- Point operator -(const Point p1){
- return Point(x-p1.x,y-p1.y,z-p1.z);
- }
- //两向量之和
- Point operator +(const Point p1){
- return Point(x+p1.x,y+p1.y,z+p1.z);
- }
- //叉乘
- Point operator *(const Point p){
- return Point(y*p.z-z*p.y,z*p.x-x*p.z,x*p.y-y*p.x);
- }
- Point operator *(double d){
- return Point(x*d,y*d,z*d);
- }
- Point operator / (double d){
- return Point(x/d,y/d,z/d);
- }
- //点乘
- double operator ^(Point p){
- return (x*p.x+y*p.y+z*p.z);
- }
- };
- struct CH3D{
- struct face{
- //表示凸包一个面上的三个点的编号
- int a,b,c;
- //表示该面是否属于最终凸包上的面
- bool ok;
- };
- //初始顶点数
- int n;
- //初始顶点
- Point P[MAXN];
- //凸包表面的三角形数
- int num;
- //凸包表面的三角形
- face F[*MAXN];
- //凸包表面的三角形
- int g[MAXN][MAXN];
- //向量长度
- double vlen(Point a){
- return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
- }
- //叉乘
- Point cross(const Point &a,const Point &b,const Point &c){
- return Point((b.y-a.y)*(c.z-a.z)-(b.z-a.z)*(c.y-a.y),
- (b.z-a.z)*(c.x-a.x)-(b.x-a.x)*(c.z-a.z),
- (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x)
- );
- }
- //三角形面积*2
- double area(Point a,Point b,Point c){
- return vlen((b-a)*(c-a));
- }
- //四面体有向体积*6
- double volume(Point a,Point b,Point c,Point d){
- return (b-a)*(c-a)^(d-a);
- }
- //正:点在面同向
- double dblcmp(Point &p,face &f){
- Point m=P[f.b]-P[f.a];
- Point n=P[f.c]-P[f.a];
- Point t=p-P[f.a];
- return (m*n)^t;
- }
- void deal(int p,int a,int b){
- int f=g[a][b];//搜索与该边相邻的另一个平面
- face add;
- if(F[f].ok){
- if(dblcmp(P[p],F[f])>eps)
- dfs(p,f);
- else{
- add.a=b;
- add.b=a;
- add.c=p;//这里注意顺序,要成右手系
- add.ok=true;
- g[p][b]=g[a][p]=g[b][a]=num;
- F[num++]=add;
- }
- }
- }
- //递归搜索所有应该从凸包内删除的面
- void dfs(int p,int now){
- F[now].ok=;
- deal(p,F[now].b,F[now].a);
- deal(p,F[now].c,F[now].b);
- deal(p,F[now].a,F[now].c);
- }
- bool same(int s,int t){
- Point &a=P[F[s].a];
- Point &b=P[F[s].b];
- Point &c=P[F[s].c];
- return fabs(volume(a,b,c,P[F[t].a]))<eps &&
- fabs(volume(a,b,c,P[F[t].b]))<eps &&
- fabs(volume(a,b,c,P[F[t].c]))<eps;
- }
- //构建三维凸包
- void create(){
- int i,j,tmp;
- face add;
- num=;
- if(n<)return;
- //**********************************************
- //此段是为了保证前四个点不共面
- bool flag=true;
- for(i=;i<n;i++){
- if(vlen(P[]-P[i])>eps){
- swap(P[],P[i]);
- flag=false;
- break;
- }
- }
- if(flag)return;
- flag=true;
- //使前三个点不共线
- for(i=;i<n;i++){
- if(vlen((P[]-P[])*(P[]-P[i]))>eps){
- swap(P[],P[i]);
- flag=false;
- break;
- }
- }
- if(flag)return;
- flag=true;
- //使前四个点不共面
- for(int i=;i<n;i++){
- if(fabs((P[]-P[])*(P[]-P[])^(P[]-P[i]))>eps){
- swap(P[],P[i]);
- flag=false;
- break;
- }
- }
- if(flag)return;
- //*****************************************
- for(i=;i<;i++){
- add.a=(i+)%;
- add.b=(i+)%;
- add.c=(i+)%;
- add.ok=true;
- if(dblcmp(P[i],add)>)swap(add.b,add.c);
- g[add.a][add.b]=g[add.b][add.c]=g[add.c][add.a]=num;
- F[num++]=add;
- }
- for(i=;i<n;i++){
- for(j=;j<num;j++){
- if(F[j].ok&&dblcmp(P[i],F[j])>eps){
- dfs(i,j);
- break;
- }
- }
- }
- tmp=num;
- for(i=num=;i<tmp;i++)
- if(F[i].ok)
- F[num++]=F[i];
- }
- //表面积
- double area(){
- double res=;
- if(n==){
- Point p=cross(P[],P[],P[]);
- res=vlen(p)/2.0;
- return res;
- }
- for(int i=;i<num;i++)
- res+=area(P[F[i].a],P[F[i].b],P[F[i].c]);
- return res/2.0;
- }
- double volume(){
- double res=;
- Point tmp(,,);
- for(int i=;i<num;i++)
- res+=volume(tmp,P[F[i].a],P[F[i].b],P[F[i].c]);
- return fabs(res/6.0);
- }
- //表面三角形个数
- int triangle(){
- return num;
- }
- //表面多边形个数
- int polygon(){
- int i,j,res,flag;
- for(i=res=;i<num;i++){
- flag=;
- for(j=;j<i;j++)
- if(same(i,j)){
- flag=;
- break;
- }
- res+=flag;
- }
- return res;
- }
- //三维凸包重心
- Point barycenter(){
- Point ans(,,),o(,,);
- double all=;
- for(int i=;i<num;i++){
- double vol=volume(o,P[F[i].a],P[F[i].b],P[F[i].c]);
- ans=ans+(o+P[F[i].a]+P[F[i].b]+P[F[i].c])/4.0*vol;
- all+=vol;
- }
- ans=ans/all;
- return ans;
- }
- //点到面的距离
- double ptoface(Point p,int i){
- return fabs(volume(P[F[i].a],P[F[i].b],P[F[i].c],p)/vlen((P[F[i].b]-P[F[i].a])*(P[F[i].c]-P[F[i].a])));
- }
- };
- CH3D hull;
- int main(){
- while(scanf("%d",&hull.n)==){
- for(int i=;i<hull.n;i++){
- scanf("%lf%lf%lf",&hull.P[i].x,&hull.P[i].y,&hull.P[i].z);
- }
- hull.create();
- printf("%.3f\n",hull.area());
- }
- return ;
- }
POJ 3528 求三维凸包表面积的更多相关文章
- POJ 3528--Ultimate Weapon(三维凸包)
Ultimate Weapon Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 2430 Accepted: 1173 ...
- BZOJ1209 最佳包裹 (三维凸包 增量法)
题意 求三维凸包的表面积. N≤100N\le100N≤100 题解 暴力往当前的凸包里加点.O(n2)O(n^2)O(n2).题解详见大佬博客 扰动函数shakeshakeshake是为了避免四点共 ...
- BZOJ1209 [HNOI2004]最佳包裹 三维凸包 计算几何
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1209 题目概括 给出立体的n个点.求三维凸包面积. 题解 增量法,看了一天,还是没有完全懂. 上板 ...
- luogu P4724 模板 三维凸包
LINK:三维凸包 一个非常古老的知识点.估计也没啥用. 大体上了解了过程 能背下来就背下来吧. 一个bf:暴力枚举三个点 此时只需要判断所有的点都在这个面的另外一侧就可以说明这个面是三维凸包上的面了 ...
- POJ 2225 / ZOJ 1438 / UVA 1438 Asteroids --三维凸包,求多面体重心
题意: 两个凸多面体,可以任意摆放,最多贴着,问他们重心的最短距离. 解法: 由于给出的是凸多面体,先构出两个三维凸包,再求其重心,求重心仿照求三角形重心的方式,然后再求两个多面体的重心到每个多面体的 ...
- 三维凸包求其表面积(POJ3528)
Ultimate Weapon Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 2074 Accepted: 989 D ...
- poj 3608 旋转卡壳求不相交凸包最近距离;
题目链接:http://poj.org/problem?id=3608 #include<cstdio> #include<cstring> #include<cmath ...
- 三维凸包求凸包表面的个数(HDU3662)
3D Convex Hull Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- 三维凸包求重心到面的最短距离(HDU4273)
http://acm.hdu.edu.cn/showproblem.php?pid=4273 Rescue Time Limit: 2000/1000 MS (Java/Others) Memo ...
随机推荐
- xar安装使用方法
xar是一种扩展的归档格式(eXtensible ARchive format),是一种开源的文件格式.xar文件在Mac OS X 10.5里是用于软件安装程序. ---------------- ...
- night Mode 夜间模式css
*,*:before,*:after,html[mode='nightmode'] * { color: #61615f !important; border-color: #212a32 !impo ...
- 在IT公司,project manager 基本上和秘书,助理什么的差不多
我感觉非常有道理,所以我不做Leader,哈哈哈
- Boyer–Moore (BM)字符串搜索算法
在计算机科学里,Boyer-Moore字符串搜索算法是一种非常高效的字符串搜索算法.它由Bob Boyer和J Strother Moore设计于1977年.此算法仅对搜索目标字符串(关键字)进行预处 ...
- 开源项目live555学习心得
推荐:伊朗美女找丈夫比找工作难女人婚前一定要看清三件事 × 登录注册 疯狂少男-IT技术的博客 http://blog.sina.com.cn/crazyboyzhaolei [订阅][手机订 ...
- libevent入门
Libevent API =============================== evtimer_new evtimer_new(base, callback, NULL) 用来做定时器,即当 ...
- openstack安装配置
openstack:1.控制节点安装所有,计算节点只有nova-compute:2.网络选择: nova-network还是neutron: nova-network比较简单, neutron功能强大 ...
- SASS安装的那些事
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 【ActiveMQ】持久化消息队列的三种方式
1.ActiveMQ消息持久化方式,分别是:文件.mysql数据库.oracle数据库 2.修改方式: a.文件持久化: ActiveMQ默认的消息保存方式,一般如果没有修改过其他持久化方式的话可以不 ...
- 【转】 利用spring的profile切换不同的环境
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...