Luogu 4724 三维凸包

  • 增量法,维护当前凸包,每次加入一个点 \(P\) ,视其为点光源,将可见面删去,新增由"晨昏线"(分割棱)与 \(P\) 构成的平面.
  • 注意每个平面表面积为其三个端点算出的法向量模长一半.
  • 参考讲解.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
inline int read()
{
int x=0;
bool pos=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='-')
pos=0;
for(;isdigit(ch);ch=getchar())
x=x*10+ch-'0';
return pos?x:-x;
}
const int MAXN=2e3+10;
const double eps=1e-9;
double Rand()
{
return rand()/(double)RAND_MAX;
}
int dcmp(double x)
{
return fabs(x)<eps?0:(x>0?1:-1);
}
struct point{
double x,y,z;
point(double x=0,double y=0,double z=0):x(x),y(y),z(z) {}
void randtrans()
{
x+=(Rand()-0.5)*eps;
y+=(Rand()-0.5)*eps;
z+=(Rand()-0.5)*eps;
}
};
point A[MAXN];
struct Vector{
double x,y,z;
Vector(double x=0,double y=0,double z=0):x(x),y(y),z(z) {}
double modulus()
{
return sqrt(x*x+y*y+z*z);
}
};
Vector vec(point a,point b)
{
return Vector(b.x-a.x,b.y-a.y,b.z-a.z);
}
Vector cross(Vector a,Vector b)
{
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);
}
double cdot(Vector a,Vector b)
{
return a.x*b.x+a.y*b.y+a.z*b.z;
}
struct Plane{
int v[3];
Vector Normal()
{
return cross(vec(A[v[0]],A[v[1]]),vec(A[v[0]],A[v[2]]));
}
double area()
{
return Normal().modulus()/2.0;
}
};
Plane getplane(int a,int b,int c)
{
Plane res;
res.v[0]=a;
res.v[1]=b;
res.v[2]=c;
return res;
}
bool insight(Plane a,point p)
{
Vector w=a.Normal();
return dcmp(cdot(w,vec(A[a.v[0]],p)))>0;
}
int n;
Plane f[MAXN],C[MAXN];
int vis[MAXN][MAXN];
double ConvexHullSurfaceArea()
{
int cnt=0;
f[++cnt]=(Plane){1,2,3};
f[++cnt]=(Plane){3,2,1};
for(int i=4,cc=0;i<=n;i++)
{
for(int j=1,v;j<=cnt;j++)
{
if(!(v=insight(f[j],A[i])))
C[++cc]=f[j];
for(int k=0;k<3;k++)
vis[f[j].v[k]][f[j].v[(k+1)%3]]=v;
}
for(int j=1;j<=cnt;j++)
for(int k=0;k<3;k++)
{
int x=f[j].v[k],y=f[j].v[(k+1)%3];
if(vis[x][y]&&!vis[y][x])
C[++cc]=(Plane){x,y,i};
}
for(int j=1;j<=cc;j++)
f[j]=C[j];
cnt=cc;cc=0;
}
double ans=0;
for(int i=1;i<=cnt;++i)
ans+=f[i].area();
return ans;
}
int main()
{
n=read();
for(int i=1;i<=n;++i)
{
scanf("%lf%lf%lf",&A[i].x,&A[i].y,&A[i].z);
A[i].randtrans();
}
double ans=ConvexHullSurfaceArea();
printf("%.3lf\n",ans);
return 0;
}

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. git 提交某个内容

    git add 你所添加的文件或者文件夹 git commit git push

  2. linux下增加useradd提示existing lock file /etc/subgid.lock without a PID

    # useradd git -g git useradd: existing lock file /etc/subgid.lock without a PID useradd: cannot lock ...

  3. jQuery回车键快速切换下一个input文本框解决方案

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. cglib动态代理(需导入cglib-nodep-2.1_3.jar)

    public interface AnimalInterface { public void cry(); } public class AnimalImpl implements AnimalInt ...

  5. IntelliJ IDEA 左侧显示/展开类中的方法

    困扰我很久的问题: project直接右键: 打开.关闭对应效果: 之前查到的都是 : 虽然也有类似的功能,但是展开的是右侧窗口中,打开的那个类的: 即使不是我想要的,但也是不错的功能!

  6. 1023: Pong’s Birds(概率)

    1023: Pong’s Birds 时间限制: 1 Sec  内存限制: 128 MB提交: 94  解决: 21[提交][状态][讨论版] 题目描述 In order to train his b ...

  7. 个人知识管理系统Version1.0开发记录(02)

    第 一 步 做 什 么 我们该如何入手呢?先来看看目前常用的三个方法. 1.从事物产生的源头出发,层层推进,步步验证,最后开花结果.这种方法经常用于科研项目,或者三期以后的工程,国家政府项目用的较多. ...

  8. MySQL的登陆错误:ERROR 1049 (42000): Unknown database 'root'

    当初刚装MySQL的时候,到网上查的命令行登陆MySQL的方法都是mysql -u root -p password mysql -r root -p 123456 但是奇怪的是这条命令我输进去死活都 ...

  9. Shell test 命令,Shell 输入/输出重定向

    一.Shell test 命令 Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值.字符和文件三个方面的测试. 数值测试 参数 说明 -eq 等于则为真 -ne 不等于则为真 -g ...

  10. NPOI:操作总结

    1.套路 使用了NPOI一段时间,也慢慢了解了操作的流程,或者说套路: a.创建Workbook: HSSFWorkbook Workbook = new HSSFWorkbook(); b.在Wor ...