Luogu 4724 三维凸包

  • 增量法,维护当前凸包,每次加入一个点 \(P\) ,视其为点光源,将可见面删去,新增由"晨昏线"(分割棱)与 \(P\) 构成的平面.
  • 注意每个平面表面积为其三个端点算出的法向量模长一半.
  • 参考讲解.
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define pii pair<int,int>
  5. inline int read()
  6. {
  7. int x=0;
  8. bool pos=1;
  9. char ch=getchar();
  10. for(;!isdigit(ch);ch=getchar())
  11. if(ch=='-')
  12. pos=0;
  13. for(;isdigit(ch);ch=getchar())
  14. x=x*10+ch-'0';
  15. return pos?x:-x;
  16. }
  17. const int MAXN=2e3+10;
  18. const double eps=1e-9;
  19. double Rand()
  20. {
  21. return rand()/(double)RAND_MAX;
  22. }
  23. int dcmp(double x)
  24. {
  25. return fabs(x)<eps?0:(x>0?1:-1);
  26. }
  27. struct point{
  28. double x,y,z;
  29. point(double x=0,double y=0,double z=0):x(x),y(y),z(z) {}
  30. void randtrans()
  31. {
  32. x+=(Rand()-0.5)*eps;
  33. y+=(Rand()-0.5)*eps;
  34. z+=(Rand()-0.5)*eps;
  35. }
  36. };
  37. point A[MAXN];
  38. struct Vector{
  39. double x,y,z;
  40. Vector(double x=0,double y=0,double z=0):x(x),y(y),z(z) {}
  41. double modulus()
  42. {
  43. return sqrt(x*x+y*y+z*z);
  44. }
  45. };
  46. Vector vec(point a,point b)
  47. {
  48. return Vector(b.x-a.x,b.y-a.y,b.z-a.z);
  49. }
  50. Vector cross(Vector a,Vector b)
  51. {
  52. return Vector(a.y*b.z-b.y*a.z,-(a.x*b.z-b.x*a.z),a.x*b.y-b.x*a.y);
  53. }
  54. double cdot(Vector a,Vector b)
  55. {
  56. return a.x*b.x+a.y*b.y+a.z*b.z;
  57. }
  58. struct Plane{
  59. int v[3];
  60. Vector Normal()
  61. {
  62. return cross(vec(A[v[0]],A[v[1]]),vec(A[v[0]],A[v[2]]));
  63. }
  64. double area()
  65. {
  66. return Normal().modulus()/2.0;
  67. }
  68. };
  69. Plane getplane(int a,int b,int c)
  70. {
  71. Plane res;
  72. res.v[0]=a;
  73. res.v[1]=b;
  74. res.v[2]=c;
  75. return res;
  76. }
  77. bool insight(Plane a,point p)
  78. {
  79. Vector w=a.Normal();
  80. return dcmp(cdot(w,vec(A[a.v[0]],p)))>0;
  81. }
  82. int n;
  83. Plane f[MAXN],C[MAXN];
  84. int vis[MAXN][MAXN];
  85. double ConvexHullSurfaceArea()
  86. {
  87. int cnt=0;
  88. f[++cnt]=(Plane){1,2,3};
  89. f[++cnt]=(Plane){3,2,1};
  90. for(int i=4,cc=0;i<=n;i++)
  91. {
  92. for(int j=1,v;j<=cnt;j++)
  93. {
  94. if(!(v=insight(f[j],A[i])))
  95. C[++cc]=f[j];
  96. for(int k=0;k<3;k++)
  97. vis[f[j].v[k]][f[j].v[(k+1)%3]]=v;
  98. }
  99. for(int j=1;j<=cnt;j++)
  100. for(int k=0;k<3;k++)
  101. {
  102. int x=f[j].v[k],y=f[j].v[(k+1)%3];
  103. if(vis[x][y]&&!vis[y][x])
  104. C[++cc]=(Plane){x,y,i};
  105. }
  106. for(int j=1;j<=cc;j++)
  107. f[j]=C[j];
  108. cnt=cc;cc=0;
  109. }
  110. double ans=0;
  111. for(int i=1;i<=cnt;++i)
  112. ans+=f[i].area();
  113. return ans;
  114. }
  115. int main()
  116. {
  117. n=read();
  118. for(int i=1;i<=n;++i)
  119. {
  120. scanf("%lf%lf%lf",&A[i].x,&A[i].y,&A[i].z);
  121. A[i].randtrans();
  122. }
  123. double ans=ConvexHullSurfaceArea();
  124. printf("%.3lf\n",ans);
  125. return 0;
  126. }

Luogu 4724 三维凸包的更多相关文章

  1. luogu P4724 模板 三维凸包

    LINK:三维凸包 一个非常古老的知识点.估计也没啥用. 大体上了解了过程 能背下来就背下来吧. 一个bf:暴力枚举三个点 此时只需要判断所有的点都在这个面的另外一侧就可以说明这个面是三维凸包上的面了 ...

  2. POJ 2225 / ZOJ 1438 / UVA 1438 Asteroids --三维凸包,求多面体重心

    题意: 两个凸多面体,可以任意摆放,最多贴着,问他们重心的最短距离. 解法: 由于给出的是凸多面体,先构出两个三维凸包,再求其重心,求重心仿照求三角形重心的方式,然后再求两个多面体的重心到每个多面体的 ...

  3. hdu4273Rescue(三维凸包重心)

    链接 模板题已不叫题.. 三维凸包+凸包重心+点到平面距离(体积/点积)  体积-->混合积(先点乘再叉乘) #include <iostream> #include<cstd ...

  4. hdu4449Building Design(三维凸包+平面旋转)

    链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了&quo ...

  5. hdu 4273 2012长春赛区网络赛 三维凸包中心到最近面距离 ***

    新模板 /* HDU 4273 Rescue 给一个三维凸包,求重心到表面的最短距离 模板题:三维凸包+多边形重心+点面距离 */ #include<stdio.h> #include&l ...

  6. HDU 4573 Throw the Stones(动态三维凸包)(2013 ACM-ICPC长沙赛区全国邀请赛)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4573 Problem Description Remember our childhood? A fe ...

  7. bzoj 1209: [HNOI2004]最佳包裹 三维凸包

    1209: [HNOI2004]最佳包裹 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 160  Solved: 58[Submit][Status] ...

  8. bzoj 1964: hull 三维凸包 计算几何

    1964: hull 三维凸包 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 54  Solved: 39[Submit][Status][Discuss ...

  9. POJ 3528 求三维凸包表面积

    也是用模板直接套的题目诶 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include < ...

随机推荐

  1. 在php中define和const定义常量的区别

    define和const都可以用来定义常量,但是const定义常量的时候大小写敏感,而define可以通过设置第三个参数为true的时候来取消大小写敏感! 如图: 引用地址:点这里

  2. Javascript 十移跳转页面

    <srcipty> var t = 10; function openwin(){ t -= 1; if( t==0){ location.href='prototype.html'; } ...

  3. Memcached stats items 命令

    Memcached stats items 命令用于显示各个 slab 中 item 的数目和存储时长(最后一次访问距离现在的秒数). 语法: stats items 命令的基本语法格式如下: sta ...

  4. angular指令与指令交互

    app.directive('mansory',function(){ return { controller:function($scope){ this.changed = function(){ ...

  5. 英语每日阅读---8、VOA慢速英语(翻译+字幕+讲解):脸肓症患者记不住别人的脸

    英语每日阅读---8.VOA慢速英语(翻译+字幕+讲解):脸肓症患者记不住别人的脸 一.总结 一句话总结: a.neural abnormalities are more widespread:Duc ...

  6. JSP 表达式语言

    JSP 表达式语言 JSP表达式语言(EL)使得访问存储在JavaBean中的数据变得非常简单.JSP EL既可以用来创建算术表达式也可以用来创建逻辑表达式.在JSP EL表达式内可以使用整型数,浮点 ...

  7. Kotlin------函数和代码注释

    定义函数 Kotlin定义一个函数的风格大致如下 访问控制符 fun 方法名(参数,参数,参数) : 返回值类型{ ... ... } 访问控制符:与Java有点差异,Kotlin的访问范围从大到小分 ...

  8. HDU 4825 Trie树 异或树!

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total S ...

  9. nyoj35——逆波兰表达式

    逆波兰表达式又称作后缀表达式,在四则混合运算的程序设计中用到. 例如: 1+2写成后缀表达式就是12+ 4+5*(3-2)的后缀表达式就是4532-*+ 后缀表达式在四则运算中带来了意想不到的方便,在 ...

  10. python----tkinterm模块

    python tkinter学习——布局   目录 一.pack() 二.grid() 三.place() 四.Frame() 正文 布局 一.pack() pack()有以下几个常用属性: side ...