直接上模板:

  1 # include <stdio.h>
  2 # include <algorithm>
  3 # include <string.h>
  4 # include <math.h>
  5 # include <stdlib.h>
  6 using namespace std;
  7
  8 const int MAXN = 550;
  9 const double eps = 1e - 8;
 10
 11 struct Point // 空间三维点
 12 {
 13     double x, y, z;
 14     // 构造函数
 15     Point(){}
 16     Point(double xx, double yy, double zz):x(xx),y(yy),z(zz){}
 17     //两向量之差
 18     Point operator -(const Point p1)
 19     {
 20         return Point(x-p1.x,y-p1.y,z-p1.z);
 21     }
 22     //两向量之和
 23     Point operator +(const Point p1)
 24     {
 25         return Point(x+p1.x,y+p1.y,z+p1.z);
 26     }
 27     //叉乘
 28     Point operator *(const Point p)
 29     {
 30         return Point(y*p.z-z*p.y,z*p.x-x*p.z,x*p.y-y*p.x);
 31     }
 32     // 向量*k
 33     Point operator *(double d)
 34     {
 35         return Point(x*d, y*d, z*d);
 36     }
 37     // 向量/k
 38     Point operator / (double d)
 39     {
 40         return Point(x/d,y/d,z/d);
 41     }
 42     //向量的点乘
 43     double  operator ^(Point p)
 44     {
 45         return (x*p.x+y*p.y+z*p.z);
 46     }
 47 };
 48
 49 struct CH3D
 50 {
 51     struct face
 52     {
 53         //表示凸包一个面上的三个点的编号
 54         int a, b, c;
 55         //表示该面是否属于最终凸包上的面
 56         bool ok;
 57     };
 58     //初始顶点数
 59     int n;
 60     //初始顶点
 61     Point P[MAXN];
 62     //凸包表面的三角形数
 63     int num;
 64     //凸包表面的三角形
 65     face F[8 * MAXN];
 66     //凸包表面的三角形
 67     int g[MAXN][MAXN];
 68     //向量长度
 69     double vlen(Point a)
 70     {
 71         return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
 72     }
 73     //叉乘
 74     Point cross(const Point &a, const Point &b, const Point &c)
 75     {
 76         return Point((b.y-a.y)*(c.z-a.z)-(b.z-a.z)*(c.y-a.y),
 77                      (b.z-a.z)*(c.x-a.x)-(b.x-a.x)*(c.z-a.z),
 78                      (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x)
 79                      );
 80     }
 81     //三角形面积*2
 82     double area(Point a, Point b, Point c)
 83     {
 84         return vlen((b-a)*(c-a));
 85     }
 86     //四面体有向体积 * 6
 87     double volume(Point a,Point b,Point c,Point d)
 88     {
 89         return (b-a)*(c-a)^(d-a);
 90     }
 91     //正:点在面同向
 92     double dblcmp(Point &p,face &f)
 93     {
 94         Point m=P[f.b]-P[f.a];
 95         Point n=P[f.c]-P[f.a];
 96         Point t=p-P[f.a];
 97         return (m*n)^t;
 98     }
 99     void deal(int p,int a,int b)
100     {
101         int f=g[a][b];//搜索与该边相邻的另一个平面
102         face add;
103         if(F[f].ok)
104         {
105             if(dblcmp(P[p],F[f])>eps)
106               dfs(p,f);
107             else
108             {
109                 add.a=b;
110                 add.b=a;
111                 add.c=p;//这里注意顺序,要成右手系
112                 add.ok=true;
113                 g[p][b]=g[a][p]=g[b][a]=num;
114                 F[num++]=add;
115             }
116         }
117     }
118     void dfs(int p,int now)//递归搜索所有应该从凸包内删除的面
119     {
120          F[now].ok=0;
121          deal(p,F[now].b,F[now].a);
122          deal(p,F[now].c,F[now].b);
123          deal(p,F[now].a,F[now].c);
124     }
125     bool same(int s,int t)
126     {
127         Point &a=P[F[s].a];
128         Point &b=P[F[s].b];
129         Point &c=P[F[s].c];
130         return fabs(volume(a,b,c,P[F[t].a]))<eps &&
131                fabs(volume(a,b,c,P[F[t].b]))<eps &&
132                fabs(volume(a,b,c,P[F[t].c]))<eps;
133     }
134     //构建三维凸包
135     void create()
136     {
137         int i,j,tmp;
138         face add;
139
140         num=0;
141         if(n<4)return;
142     //**********************************************
143         //此段是为了保证前四个点不共面
144         bool flag=true;
145         for(i=1;i<n;i++)
146         {
147             if(vlen(P[0]-P[i])>eps)
148             {
149                 swap(P[1],P[i]);
150                 flag=false;
151                 break;
152             }
153         }
154         if(flag)return;
155         flag=true;
156         //使前三个点不共线
157         for(i=2;i<n;i++)
158         {
159             if(vlen((P[0]-P[1])*(P[1]-P[i]))>eps)
160             {
161                 swap(P[2],P[i]);
162                 flag=false;
163                 break;
164             }
165         }
166         if(flag)return;
167         flag=true;
168         //使前四个点不共面
169         for(int i=3;i<n;i++)
170         {
171             if(fabs((P[0]-P[1])*(P[1]-P[2])^(P[0]-P[i]))>eps)
172             {
173                 swap(P[3],P[i]);
174                 flag=false;
175                 break;
176             }
177         }
178         if(flag)return;
179     //*****************************************
180         for(i=0;i<4;i++)
181         {
182             add.a=(i+1)%4;
183             add.b=(i+2)%4;
184             add.c=(i+3)%4;
185             add.ok=true;
186             if(dblcmp(P[i],add)>0)swap(add.b,add.c);
187             g[add.a][add.b]=g[add.b][add.c]=g[add.c][add.a]=num;
188             F[num++]=add;
189         }
190         for(i=4;i<n;i++)
191         {
192             for(j=0;j<num;j++)
193             {
194                 if(F[j].ok&&dblcmp(P[i],F[j])>eps)
195                 {
196                     dfs(i,j);
197                     break;
198                 }
199             }
200         }
201         tmp=num;
202         for(i=num=0;i<tmp;i++)
203           if(F[i].ok)
204             F[num++]=F[i];
205
206     }
207     //表面积
208     double area()
209     {
210         double res=0;
211         if(n==3)
212         {
213             Point p=cross(P[0],P[1],P[2]);
214             res=vlen(p)/2.0;
215             return res;
216         }
217         for(int i=0;i<num;i++)
218           res+=area(P[F[i].a],P[F[i].b],P[F[i].c]);
219         return res/2.0;
220     }
221     double volume()
222     {
223         double res=0;
224         Point tmp(0,0,0);
225         for(int i=0;i<num;i++)
226            res+=volume(tmp,P[F[i].a],P[F[i].b],P[F[i].c]);
227         return fabs(res/6.0);
228     }
229     //表面三角形个数
230     int triangle()
231     {
232         return num;
233     }
234     //表面多边形个数
235     int polygon()
236     {
237         int i,j,res,flag;
238         for(i=res=0;i<num;i++)
239         {
240             flag=1;
241             for(j=0;j<i;j++)
242               if(same(i,j))
243               {
244                   flag=0;
245                   break;
246               }
247             res+=flag;
248         }
249         return res;
250     }
251     //三维凸包重心
252     Point barycenter()
253     {
254         Point ans(0,0,0),o(0,0,0);
255         double all=0;
256         for(int i=0;i<num;i++)
257         {
258             double vol=volume(o,P[F[i].a],P[F[i].b],P[F[i].c]);
259             ans=ans+(o+P[F[i].a]+P[F[i].b]+P[F[i].c])/4.0*vol;
260             all+=vol;
261         }
262         ans=ans/all;
263         return ans;
264     }
265     //点到面的距离
266     double ptoface(Point p,int i)
267     {
268         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])));
269     }
270 };
271 CH3D hull;
272 int main()
273 {
274     while(scanf("%d", &hull.n) == 1)
275     {
276         for(int i = 0; i < hull.n; i++)
277         {
278             scanf("%lf%lf%lf", &hull.P[i].x, &hull.P[i].y, &hull.P[i].z);
279         }
280         hull.create();
281         printf("%d\n",hull.polygon());
282     }
283     return 0;
284 }

View Code

先输入点,再创建,和调用类一模一样

转载于:https://www.cnblogs.com/lyf-acm/p/5823686.html

POJ 3862 POJ 3528 HDU 3662 HDU 4273 三维凸包问题解决模板相关推荐

  1. HDU 3662 3D Convex Hull(三维凸包面的个数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3662 题意:求三维凸包面的个数. 思路:模板. struct Point {double x,y,z; ...

  2. HDU 1853 HDU 3488【有向环最小权值覆盖问题 】带权二分图匹配 KM算法

    HDU 1853 & HDU 3488[有向环最小权值覆盖问题 ]最小费用最大流 In the kingdom of Henryy, there are N (2 <= N <= ...

  3. HDU 1853 HDU 3488【有向环最小权值覆盖问题 】最小费用最大流

    HDU 1853 & HDU 3488[有向环最小权值覆盖问题 ]带权二分图匹配 KM算法 In the kingdom of Henryy, there are N (2 <= N & ...

  4. 母函数+例题(hdu 2079+hdu 2082)

    母函数+例题(hdu 2079+hdu 2082) 虽然ACM的确有点力不从心,但是还是贵在坚持,继续啃啃算法..... 昨天一个下午学了学母函数,离散数学+幂级数,只能说nb- 看了半天的原理,结果 ...

  5. 【HDU/POJ/ZOJ】Calling Extraterrestrial Intelligence Again (素数打表模板)

    http://poj.org/problem?id=1411  POJ http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=168 ...

  6. POJ 2195 Going Home / HDU 1533(最小费用最大流模板)

    题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...

  7. POJ 2135 Farm Tour amp;amp; HDU 2686 Matrix amp;amp; HDU 3376 Matrix Again 费用流求来回最短路...

    累了就要写题解,近期总是被虐到没脾气. 来回最短路问题貌似也能够用DP来搞.只是拿费用流还是非常方便的. 能够转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1.然后连 ...

  8. hdu 1251+hdu 1671(字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251 一开始我是直接用STL做的,唉...没有经验那...orz...然后毫无疑问地超时了... 看别 ...

  9. hdu 2063+hdu 1083(最大匹配数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2063 二分匹配水题,求最大匹配数(即求边数最多的匹配),匈牙利算法实现.. View Code 1 # ...

  10. HDU 4946 Area of Mushroom 凸包

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 题意:有n个人.在位置(xi,yi),速度是vi,假设对于某个点一个人比全部其它的都能先到那个点,那 ...

最新文章

  1. 2019河南对口高职高专计算机,2019年河南普通高招最后一个批次 高职高专批正式投档...
  2. HTML的<span>标签【杂记】
  3. Angle和XBGoost以及Spark的性能对比
  4. 带有Spring Boot 2支持的Apache Camel 2.22发布
  5. 关于用turbo c 编译出现的 Declaration syntax error 错误 (未解决)
  6. 具有多个Join和选定列的示例LINQ
  7. linux交叉编译出现的问题,,Ubuntu 14.10下安装GCC交叉编译器遇到问题及解决方法
  8. webform窗体怎么实现session唯一标识_微信小程序用户登录和登录态维护的实现_javascript技巧...
  9. Android Folding View(折叠视图、控件)
  10. Magento url 问题
  11. 阶段3 3.SpringMVC·_01.SpringMVC概述及入门案例_05.入门程序之入门代码编写
  12. MAC共享目录让WINDOWS访问
  13. python输入函数设计_(董付国)Python 学习笔记---Python函数设计与使用(3)
  14. 微信小程序——仿写京东购物商城带源码
  15. c语言自定义结构,C语言如何定义结构体
  16. 常用电阻阻值表怎么定的?
  17. dto转化 vo_VO(DTO)与PO(DAO)之间的转换
  18. 习题8-4 报数 (20分)
  19. [Android相机]光线传感器识别环境光亮强度
  20. Prege(图计算框架)l: A System for Large-Scale Graph Processing(译)

热门文章

  1. error: two or more data types in declaration specifiers原因及解决方法
  2. html编写个人博客_云开发平台开箱,3分钟零基础搭建个人Hexo博客
  3. 【codeVS 1082】树状数组(区间修改,区间查询)模版题
  4. hdoj1176:免费馅饼(dp基础题-数塔思想)
  5. html 域名随机跳转_看一眼就会的 HTML 小游戏搭建!
  6. 十大排序算法——计数排序(C语言)
  7. 信用评分卡 (part 3of 7)
  8. linux c 调用c程序,Linux C调用C++库(用C封装C++接口)
  9. TL摄像头如何放到html去直播,使用flash插件来调用pc的摄像头如何将它嵌入到TML页面中...
  10. 2021-09-14Apriori 算法是基于关联规则的高效数 据挖掘算法