LINK:三维凸包

一个非常古老的知识点。估计也没啥用。

大体上了解了过程 能背下来就背下来吧.

一个bf:暴力枚举三个点 此时只需要判断所有的点都在这个面的另外一侧就可以说明这个面是三维凸包上的面了。

一个问题 :多点共面问题。一个trick:可以利用扰动法然后 就可以解决这个问题了。

正解:\(n^2\)的增量法求三维凸包。

先加入三个不共线的点组成一个面(正反两面然后不断加入点。

然后考虑每一个点 删除这个点可以看到的面 然后边界与新加入的点连边即可。

具体理解看代码(我也有点迷。。

code
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-9
#define sq sqrt
#define mod 998244353
#define S second
#define F first
#define op(x) t[x].op
#define d(x) t[x].d
#define Set(a,v) memset(a,v,sizeof(a))
#define pf(x) ((x)*(x))
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const int MAXN=2010;
int n,cnt;
int vis[MAXN][MAXN];
db ans=0;
db Rand(){return rand()/(db)RAND_MAX;}
db reps() {return (Rand()-0.5)*EPS;}
struct Vec
{
db x,y,z;
void shake(){x+=reps();y+=reps();z+=reps();}//扰动.
db len(){return sq(pf(x)+pf(y)+pf(z));}
Vec operator -(Vec a){return (Vec){x-a.x,y-a.y,z-a.z};}
Vec operator %(Vec a){return (Vec){y*a.z-z*a.y,z*a.x-x*a.z,x*a.y-y*a.x};}
db operator *(Vec a){return x*a.x+y*a.y+z*a.z;}
}a[MAXN];
typedef Vec point;
struct wy
{
int v[3];
Vec Nor(){return (a[v[1]]-a[v[0]])%(a[v[2]]-a[v[0]]);}
db area(){return Nor().len()/2.0;}
}f[MAXN],c[MAXN];
inline bool pd(wy c,Vec b){return ((b-a[c.v[0]])*c.Nor())>0;}
inline void Convex_3D()
{
f[cnt=1].v[0]=1;
f[cnt=1].v[1]=2;
f[cnt=1].v[2]=3;
f[cnt=2].v[0]=3;
f[cnt=2].v[1]=2;
f[cnt=2].v[2]=1;
rep(4,n,i)
{
int cc=0;
rep(1,cnt,j)
{
int ww=pd(f[j],a[i]);
if(!ww)c[++cc]=f[j];
rep(0,2,k)vis[f[j].v[k]][f[j].v[(k+1)%3]]=ww;
}
rep(1,cnt,j)
{
rep(0,2,k)
{
int x=f[j].v[k],y=f[j].v[(k+1)%3];
if(vis[x][y]&&!vis[y][x])
{
c[++cc].v[0]=x;c[cc].v[1]=y;c[cc].v[2]=i;
}
}
}
rep(1,cc,j)f[j]=c[j];
cnt=cc;
}
}
int main()
{
freopen("1.in","r",stdin);
gt(n);rep(1,n,i)scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z),a[i].shake();
Convex_3D();rep(1,cnt,i)ans+=f[i].area();
printf("%.3lf",ans);return 0;
}

luogu P4724 模板 三维凸包的更多相关文章

  1. [Luogu4724][模板]三维凸包(增量构造法)

    1.向量点积同二维,x1y1+x2y2+x3y3.向量叉积是行列式形式,(y1z2-z1y2,z1x2-x1z2,x1y2-y1x2). 2.增量构造法: 1)首先定义,一个平面由三个点唯一确定.一个 ...

  2. 题解-洛谷P4724 【模板】三维凸包

    洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...

  3. Luogu P2742 模板-二维凸包

    Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...

  4. Luogu 4724 三维凸包

    Luogu 4724 三维凸包 增量法,维护当前凸包,每次加入一个点 \(P\) ,视其为点光源,将可见面删去,新增由"晨昏线"(分割棱)与 \(P\) 构成的平面. 注意每个平面 ...

  5. hdu4266(三维凸包模板题)

    /*给出三维空间中的n个顶点,求解由这n个顶点构成的凸包表面的多边形个数. 增量法求解:首先任选4个点形成的一个四面体,然后每次新加一个点,分两种情况: 1> 在凸包内,则可以跳过 2> ...

  6. POJ3528 HDU3662 三维凸包模板

    POJ3528 HDU3662 第一道题 给定若干点 求凸包的表面积,第二题 给定若干点就凸包的面数. 简单说一下三维凸包的求法,首先对于4个点假设不共面,确定了唯一四面体,对于一个新的点,若它不在四 ...

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

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

  8. hdu4273Rescue(三维凸包重心)

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

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

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

随机推荐

  1. web网页多语言的实现方案_前端实现多语言切换

    实现的效果 需要在web中实现多语言的切换,当用户语言切换完成后下次重新打开网页,也是上次设置的语言进行显示. 资源网站搜索大全https://55wd.com 实现步骤 1.在用户点击切换语言后,把 ...

  2. 平常我们是如何区分css中class和id之间有什么区别的?

    我们平常在用DIV+CSS制作html网页页面时,常会用到class 和id来选择调用CSS样式属性.对学习CSS的新手来说class和id可能比较模糊,同时不知道什么时候该用class,什么时候又用 ...

  3. MySQL索引 索引分类 最左前缀原则 覆盖索引 索引下推 联合索引顺序

    MySQL索引 索引分类 最左前缀原则 覆盖索引 索引下推 联合索引顺序   What's Index ? 索引就是帮助RDBMS高效获取数据的数据结构. 索引可以让我们避免一行一行进行全表扫描.它的 ...

  4. zabbix fping 监控网络质量

    1,zabbix server (proxy)安装fping wget http://www.fping.org/dist/fping-3.16.tar.gz tar zxvf fping-3.16. ...

  5. NOIP 2016 D2T2 蚯蚓](思维)

    NOIP 2016 D2T2 蚯蚓 题目大意 本题中,我们将用符号 \(\lfloor c \rfloor⌊c⌋\) 表示对 \(c\) 向下取整,例如:\(\lfloor 3.0 \rfloor = ...

  6. uniapp,微信小程序中使用 MQTT

    最近在uniapp打包成微信小程序的项目中第一次用到了MQTT.使用比较简单,但是还是遇到了一些问题.在此记录一下. 官方文档:MQTT Github 官方MQTT测试工具:MQTTX.测试工具使用说 ...

  7. shell专题(一):Shell概述

    大数据程序员为什么要学习Shell呢? 1)需要看懂运维人员编写的Shell程序. 2)偶尔会编写一些简单Shell程序来管理集群.提高开发效

  8. Centos7 python 安装 Ignoring ensurepip failure: pip 9.0.1 requires SSL/TLS

    安装python时出现Ignoring ensurepip failure:pip required SSL/TLS 因为没有安装OpenSSL 使用yum install openssl-devel

  9. CSS文本控制

    CSS文本控制 文本基础设置 字体设置 font-family可定义多个字体,系统会以从左至右的顺序进行查找,如左侧字体不存在,就往右侧找. 为什么要这么做呢?如果你只用了一种字体,而恰好人家电脑上没 ...

  10. Java常用API(Arrays类)

    Java常用API(Arrays类) 什么是Arrays类? java.util.Arrays 此类包含用来操作数组的各种方法,比如排序和搜索等.其所有方法均为静态方法,调用起来 非常简单. 这里我们 ...