Luogu 4724 三维凸包
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 三维凸包的更多相关文章
- luogu P4724 模板 三维凸包
LINK:三维凸包 一个非常古老的知识点.估计也没啥用. 大体上了解了过程 能背下来就背下来吧. 一个bf:暴力枚举三个点 此时只需要判断所有的点都在这个面的另外一侧就可以说明这个面是三维凸包上的面了 ...
- POJ 2225 / ZOJ 1438 / UVA 1438 Asteroids --三维凸包,求多面体重心
题意: 两个凸多面体,可以任意摆放,最多贴着,问他们重心的最短距离. 解法: 由于给出的是凸多面体,先构出两个三维凸包,再求其重心,求重心仿照求三角形重心的方式,然后再求两个多面体的重心到每个多面体的 ...
- hdu4273Rescue(三维凸包重心)
链接 模板题已不叫题.. 三维凸包+凸包重心+点到平面距离(体积/点积) 体积-->混合积(先点乘再叉乘) #include <iostream> #include<cstd ...
- hdu4449Building Design(三维凸包+平面旋转)
链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了&quo ...
- hdu 4273 2012长春赛区网络赛 三维凸包中心到最近面距离 ***
新模板 /* HDU 4273 Rescue 给一个三维凸包,求重心到表面的最短距离 模板题:三维凸包+多边形重心+点面距离 */ #include<stdio.h> #include&l ...
- HDU 4573 Throw the Stones(动态三维凸包)(2013 ACM-ICPC长沙赛区全国邀请赛)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4573 Problem Description Remember our childhood? A fe ...
- bzoj 1209: [HNOI2004]最佳包裹 三维凸包
1209: [HNOI2004]最佳包裹 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 160 Solved: 58[Submit][Status] ...
- bzoj 1964: hull 三维凸包 计算几何
1964: hull 三维凸包 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 54 Solved: 39[Submit][Status][Discuss ...
- POJ 3528 求三维凸包表面积
也是用模板直接套的题目诶 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include < ...
随机推荐
- Maven打包命令
mvn clean 会把原来target目录给删掉重新生成.mvn install 安装当前工程的输出文件到本地仓库,然后打包mvn clean install 先删除target文件夹 ,然后打包到 ...
- RabbitMQ入门(3)——发布/订阅(Publish/Subscribe)
在上一篇RabbitMQ入门(2)--工作队列中,有一个默认的前提:每个任务都只发送到一个工作人员.这一篇将介绍发送一个消息到多个消费者.这种模式称为发布/订阅(Publish/Subscribe). ...
- PHP闭包 function() use(){}
php的闭包(Closure)也就是匿名函数.是PHP5.3引入的. 闭包的语法很简单,需要注意的关键字就只有use,use意思是连接闭包和外界变量. $a =function()use($b) { ...
- scp 上传 下载 文件
linux 中的ssh命令: scp 可以用来上传本地文件到远程服务器 或下载远程服务器中的文件到本地 1. 上传本地文件到远程服务器 scp readme.md user@www.*****.com ...
- Postman的安装
打开chrome->设置->扩展程序->获取更多扩张程序:输入 postman就可以安装了 可能需要蓝灯FQ 安装好了直接打开即可使用
- HDU 5687 字典树入门
Problem C Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- AOP(面向切面)的粗俗理解
百度百科的解释:AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. 一个比较绕的概念,简单来说就是把不影响业 ...
- cookie和localstorage sessionStorage的概念、区别、使用场景
本文分为三大板块: 1 webStorage的概念 2 cookie/localStorage/sessionStorage的介绍 3 三者之间的共同点和区别 **所有代码引用均来自 作者:OBKor ...
- 005-对象——对象的 final const
<?php /** * */ /*class shouji { public $pinpai; final function chongdian() { //final 最终的 return $ ...
- 【hdu1005】Number Sequence
题目描述 一个数列的定义如下: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 给出A和B,你要求出f(n). 输入 输 ...