hdu4273Rescue(三维凸包重心)
模板题已不叫题。。
三维凸包+凸包重心+点到平面距离(体积/点积) 体积-->混合积(先点乘再叉乘)
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 510
#define INF 1e20
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define eps 1e-8
#define MAXV 505
const double pi = acos(-1.0);
const double inf = ~0u>>;
//三维点
struct point3
{
double x, y,z;
point3() {}
point3(double _x, double _y, double _z): x(_x), y(_y), z(_z) {}
point3 operator +(const point3 p1)
{
return point3(x+p1.x,y+p1.y,z+p1.z);
}
point3 operator - (const point3 p1)
{
return point3(x - p1.x, y - p1.y, z - p1.z);
}
point3 operator * (point3 p)
{
return point3(y*p.z-z*p.y, z*p.x-x*p.z, x*p.y-y*p.x); //叉乘
}
point3 operator *(double d)
{
return point3(x*d,y*d,z*d);
}
point3 operator /(double d)
{
return point3(x/d,y/d,z/d);
}
double operator ^ (point3 p)
{
return x*p.x+y*p.y+z*p.z; //点乘
} } pp[N],rp[N];
struct point
{
double x,y;
point(double x=,double y=):x(x),y(y) {}
point operator -(point b)
{
return point(x-b.x,y-b.y);
}
} p[N],ch[N];
struct _3DCH
{
struct fac
{
int a, b, c; //表示凸包一个面上三个点的编号
bool ok; //表示该面是否属于最终凸包中的面
}; int n; //初始点数
point3 P[MAXV]; //初始点 int cnt; //凸包表面的三角形数
fac F[MAXV*]; //凸包表面的三角形 int to[MAXV][MAXV];
double vlen(point3 a)
{
return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
} //向量长度
double area(point3 a, point3 b, point3 c)
{
return vlen((b-a)*(c-a));
} //三角形面积*2
double volume(point3 a, point3 b, point3 c, point3 d)
{
return (b-a)*(c-a)^(d-a); //四面体有向体积*6
}
//正:点在面同向
double point3of(point3 &p, fac &f)
{
point3 m = P[f.b]-P[f.a], n = P[f.c]-P[f.a], t = p-P[f.a];
return (m * n) ^ t;
}
void deal(int p, int a, int b)
{
int f = to[a][b];
fac add;
if (F[f].ok)
{
if (point3of(P[p], F[f]) > eps)
dfs(p, f);
else
{
add.a = b, add.b = a, add.c = p, add.ok = ;
to[p][b] = to[a][p] = to[b][a] = cnt;
F[cnt++] = add;
}
}
}
void dfs(int p, int cur)
{
F[cur].ok = ;
deal(p, F[cur].b, F[cur].a);
deal(p, F[cur].c, F[cur].b);
deal(p, F[cur].a, F[cur].c);
}
bool same(int s, int t)
{
point3 &a = P[F[s].a], &b = P[F[s].b], &c = P[F[s].c];
return fabs(volume(a, b, c, P[F[t].a])) < eps && fabs(volume(a, b, c, P[F[t].b])) < eps && fabs(volume(a, b, c, P[F[t].c])) < eps;
}
//构建三维凸包
void construct()
{
cnt = ;
if (n < )
return;
bool sb = ;
//使前两点不公点
for (int i = ; i < n; i++)
{
if (vlen(P[] - P[i]) > eps)
{
swap(P[], P[i]);
sb = ;
break;
}
}
if (sb)return;
sb = ;
//使前三点不公线
for (int i = ; i < n; i++)
{
if (vlen((P[] - P[]) * (P[] - P[i])) > eps)
{
swap(P[], P[i]);
sb = ;
break;
}
}
if (sb)return;
sb = ;
//使前四点不共面
for (int i = ; i < n; i++)
{
if (fabs((P[] - P[]) * (P[] - P[]) ^ (P[] - P[i])) > eps)
{
swap(P[], P[i]);
sb = ;
break;
}
}
if (sb)return;
fac add;
for (int i = ; i < ; i++)
{
add.a = (i+)%, add.b = (i+)%, add.c = (i+)%, add.ok = ;
if (point3of(P[i], add) > )
swap(add.b, add.c);
to[add.a][add.b] = to[add.b][add.c] = to[add.c][add.a] = cnt;
F[cnt++] = add;
}
for (int i = ; i < n; i++)
{
for (int j = ; j < cnt; j++)
{
if (F[j].ok && point3of(P[i], F[j]) > eps)
{
dfs(i, j);
break;
}
}
}
int tmp = cnt;
cnt = ;
for (int i = ; i < tmp; i++)
{
if (F[i].ok)
{
F[cnt++] = F[i];
}
}
}
//表面积
double area()
{
double ret = 0.0;
for (int i = ; i < cnt; i++)
{
ret += area(P[F[i].a], P[F[i].b], P[F[i].c]);
}
return ret / 2.0;
}
double ptoface(point3 p,int i)
{
return fabs(volume(P[F[i].a],P[F[i].b],P[F[i].c],p)/vlen((P[F[i].b]-P[F[i].a])*(P[F[i].c]-P[F[i].a])));
}
//体积
double volume()
{
point3 O(, , );
double ret = 0.0;
for (int i = ; i < cnt; i++)
{
ret += volume(O, P[F[i].a], P[F[i].b], P[F[i].c]);
}
return fabs(ret / 6.0);
}
//表面三角形数
int facetCnt_tri()
{
return cnt;
} //表面多边形数
int facetCnt()
{
int ans = ;
for (int i = ; i < cnt; i++)
{
bool nb = ;
for (int j = ; j < i; j++)
{
if(same(i, j))
{
nb = ;
break;
}
}
ans += nb;
}
return ans;
}
//三维凸包重心
point3 barycenter()
{
point3 ans(,,),o(,,);
double all=;
for(int i=;i<cnt;i++)
{
double vol=volume(o,P[F[i].a],P[F[i].b],P[F[i].c]);
ans=ans+(o+P[F[i].a]+P[F[i].b]+P[F[i].c])/4.0*vol;
all+=vol;
}
ans=ans/all;
return ans;
} }hull; void solve()
{
double ans = INF;
int i;
int cnt = hull.cnt;
point3 pp = hull.barycenter();
for(i = ; i < cnt ; i++)
{
ans = min(ans,hull.ptoface(pp,i));
}
printf("%.3f\n",ans);
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
hull.n = n;
for(i = ; i < n; i++)
{
scanf("%lf%lf%lf",&pp[i].x,&pp[i].y,&pp[i].z);
hull.P[i] = pp[i];
}
hull.construct();
solve();
}
}
hdu4273Rescue(三维凸包重心)的更多相关文章
- hdu 4273 2012长春赛区网络赛 三维凸包中心到最近面距离 ***
新模板 /* HDU 4273 Rescue 给一个三维凸包,求重心到表面的最短距离 模板题:三维凸包+多边形重心+点面距离 */ #include<stdio.h> #include&l ...
- POJ 3528 求三维凸包表面积
也是用模板直接套的题目诶 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include < ...
- POJ3528 HDU3662 三维凸包模板
POJ3528 HDU3662 第一道题 给定若干点 求凸包的表面积,第二题 给定若干点就凸包的面数. 简单说一下三维凸包的求法,首先对于4个点假设不共面,确定了唯一四面体,对于一个新的点,若它不在四 ...
- POJ 2225 / ZOJ 1438 / UVA 1438 Asteroids --三维凸包,求多面体重心
题意: 两个凸多面体,可以任意摆放,最多贴着,问他们重心的最短距离. 解法: 由于给出的是凸多面体,先构出两个三维凸包,再求其重心,求重心仿照求三角形重心的方式,然后再求两个多面体的重心到每个多面体的 ...
- 三维凸包求重心到面的最短距离(HDU4273)
http://acm.hdu.edu.cn/showproblem.php?pid=4273 Rescue Time Limit: 2000/1000 MS (Java/Others) Memo ...
- 三维凸包求其表面积(POJ3528)
Ultimate Weapon Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 2074 Accepted: 989 D ...
- 三维凸包求凸包表面的个数(HDU3662)
3D Convex Hull Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- 三维凸包求内部一点到表面的最近距离(HDU4266)
http://acm.hdu.edu.cn/showproblem.php?pid=4266 The Worm in the Apple Time Limit: 50000/20000 MS (Jav ...
- hdu4449Building Design(三维凸包+平面旋转)
链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了&quo ...
随机推荐
- Mac终端用Sublime打开指定文件或文件夹
首先你先把的sublime放到Application中,再确认您的Sublime的路径是否正确 1 创建别名: sudo ln -s "/Applications/Sublime\ Text ...
- Java中关于先有鸡还是先有蛋的问题----Class&Object
在Java中,我们常常会看到一个类型:Class.并且在类似Person.class,cache.getClass()等代码中见到它的身影. 众所周知,Class是用来描述一个类的类型,而Object ...
- sqlserver 锁与阻塞
DDL/索引重建 会申请 Sch-M锁 with (nolock) 会申请 Sch-S锁 with (nolock)会阻塞 sch-M, 同样Sch-M也会 阻塞with (nolock) 索引重建2 ...
- php 读取json数据文本所遇到的问题
json数据属于特殊的字符串,一般自己写的json数据不要误加空格,回车,换行, 若是从其他文件读取过来的json数据很有可能带有空格,回车,换行等符号,导致使用json_decode()转诚数组失败 ...
- 关于区域性网站CMS的一些个人看法
最近了解了几款国外开源CMS,与现有国内客户需求及业务习惯,结论如下:1.国人的习惯,有后台管理和会员管理2种,而老外大部分开源系统都是一个管理即前台管理,而且大部分架构是固定死的,如果在想抽出一个后 ...
- Sublime Text 3 高效编码快捷键
Sublime Text 3 高效编码快捷键 1.快速跳到第20行 Ctrl+p 框中输入 “ :20 ” 2.在文件夹中查看文件 Ctrl+p 框中输入 “ index.html” 更快 ...
- 被碾压过得Samsung SCH-W319 的取证恢复
2015年2月笔者接到一台! 被车轧过的手机Samsung SCH-W319,要求恢复 如图,显示屏被轧过,屏弯掉了 电池亦无,目前打不开!如下图: 配好电池后是这个样子,终于可以获得镜像dump 而 ...
- ubuntu安装cpu版caffe
最近在笔记本上配置了ubuntu14.04,并配置了caffe,整个过程大概花了2个小时. 希望在安装时能给大家一个启发,这里配置的是无gpu版的,因为我的笔记本时核心显卡,配置gpu版的要编译cud ...
- HashMap与ConcurrentHashMap的区别
从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...
- win7下matlab2016a配置libsvm
1.下载libsvm https://www.csie.ntu.edu.tw/~cjlin/libsvm/ 2.解压到matlab2016a的安装目录的toolbox下 例如我的D:\Program ...