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 < ...
随机推荐
- [解决]JS失效,提示HTML1114: (UNICODE 字节顺序标记)的代码页 utf-8 覆盖(META 标记)的冲突的代码页 utf-8
上网找了找,木有找到相关的解决办法,索性自己试了试. 原页面是这样写的: <html> <head> <meta http-equiv="Content-Typ ...
- SpringBoot创建定时任务
之前总结过spring+quartz实现定时任务的整合http://www.cnblogs.com/gdpuzxs/p/6663725.html,而springboot创建定时任务则是相当简单. (1 ...
- 卡在了“正在设定 ttf-mscorefonts-installer”的解决
方向键啊鼠标的都不行,其实用tab键就可以选择了.冏死--
- Linux命令详解-cal
cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历."阳历"又名"太阳历",系以地球绕行太阳一周为一年,为西方各国所通用,故 ...
- ngnix配置自解
全局配置 user [user] [group]; #只有被设置为用户或用户组的成员才有nginx的启动权限.(#user nobody nobody <=> user nobody no ...
- JavaScript中Function Declaration与Function Expression 或者说 function fn(){}和var fn=function(){} 的区别
JavaScript是一种解释型语言,函数声明会在JavaScript代码加载后.执行前被解释,而函数表达式只有在执行到这一行代码时才会被解释. 在JS中有两种定义函数的方式, 1是:var aaa= ...
- day29 主机管理-堡垒机2-原生ssh会话记录
day29课堂代码:https://github.com/liyongsan/git_class/tree/master/day29 课堂笔记: 通过原生Ssh 记录会话1. 在我们自己的堡垒机交互脚 ...
- 【MySQL】CSV 文件导入MySQL
此问题是前几天整理数据的时候碰到的,数据存在 CSV文件中(200多万记录),通过python 往数据库中导入太慢了,后来使用MySQL 中自带的命令 LOAD DATA INFILE, 30多秒就能 ...
- Linux命令 ls -l 输出内容含义详解
Linux命令 ls -l s输出内容含义详解 1. ls 只显示文件名或者文件目录 2. ls -l(这个参数是字母L的小写,不是数字1) 用来查看详细的文件资料 在某个目录下键入ls -l可 ...
- MYSQL中的日期转换
MYSQL中的日期转换 网址: http://www.eygle.com/digest/2006/09/mysql_date_convert.html 对于每个类型拥有的值范围以及并且指定日期何时间值 ...