poj 3862 && LA 4589 Asteroids (三维凸包+多面体重心)
用给出的点求出凸包的重心,并求出重心到多边形表面的最近距离。
代码如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath> using namespace std; const double EPS = 1e-;
const int N = ;
inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
struct Point {
double x, y, z;
Point() {}
Point(double x, double y, double z) : x(x), y(y), z(z) {}
bool operator < (Point a) const {
if (sgn(x - a.x)) return x < a.x;
if (sgn(y - a.y)) return y < a.y;
return z < a.z;
}
bool operator == (Point a) const { return !sgn(x - a.x) && !sgn(y - a.y) && !sgn(z - a.z);}
Point operator + (Point a) { return Point(x + a.x, y + a.y, z + a.z);}
Point operator - (Point a) { return Point(x - a.x, y - a.y, z - a.z);}
Point operator * (double p) { return Point(x * p, y * p, z * p);}
Point operator / (double p) { return Point(x / p, y / p, z / p);}
} ;
inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y + a.z * b.z;}
inline double dot(Point o, Point a, Point b) { return dot(a - o, b - o);}
inline Point cross(Point a, Point b) { return Point(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);}
inline Point cross(Point o, Point a, Point b) { return cross(a - o, b - o);}
inline double veclen(Point x) { return sqrt(dot(x, x));}
inline double area(Point o, Point a, Point b) { return veclen(cross(o, a, b)) / 2.0;}
inline double volume(Point o, Point a, Point b, Point c) { return dot(cross(o, a, b), c - o) / 6.0;} struct _3DCH{
Point pt[N];
int pcnt;
struct Face {
int a, b, c;
bool ok;
Face() {}
Face(int a, int b, int c) : a(a), b(b), c(c) { ok = true;}
} fc[N << ];
int fcnt;
int fid[N][N]; bool outside(int p, int a, int b, int c) { return sgn(volume(pt[a], pt[b], pt[c], pt[p])) < ;}
bool outside(int p, int f) { return outside(p, fc[f].a, fc[f].b, fc[f].c);}
void addface(int a, int b, int c, int d) {
if (outside(d, a, b, c)) fc[fcnt] = Face(c, b, a), fid[c][b] = fid[b][a] = fid[a][c] = fcnt++;
else fc[fcnt] = Face(a, b, c), fid[a][b] = fid[b][c] = fid[c][a] = fcnt++;
} bool dfs(int p, int f) {
if (!fc[f].ok) return true;
int a = fc[f].a, b = fc[f].b, c = fc[f].c;
if (outside(p, a, b, c)) {
fc[f].ok = false;
if (!dfs(p, fid[b][a])) addface(p, a, b, c);
if (!dfs(p, fid[c][b])) addface(p, b, c, a);
if (!dfs(p, fid[a][c])) addface(p, c, a, b);
return true;
}
return false;
}
void build() {
bool ok;
fcnt = ;
sort(pt, pt + pcnt);
pcnt = unique(pt, pt + pcnt) - pt;
ok = false;
for (int i = ; i < pcnt; i++) {
if (sgn(area(pt[], pt[], pt[i]))) {
ok = true;
swap(pt[i], pt[]);
break;
}
}
if (!ok) return ;
ok = false;
for (int i = ; i < pcnt; i++) {
if (sgn(volume(pt[], pt[], pt[], pt[i]))) {
ok = true;
swap(pt[i], pt[]);
break;
}
}
if (!ok) return ;
addface(, , , );
addface(, , , );
addface(, , , );
addface(, , , );
for (int i = ; i < pcnt; i++) {
for (int j = fcnt - ; j >= ; j--) {
if (outside(i, j)) {
dfs(i, j);
break;
}
}
}
int sz = fcnt;
fcnt = ;
for (int i = ; i < sz; i++) if (fc[i].ok) fc[fcnt++] = fc[i];
}
double facearea() {
double ret = 0.0;
for (int i = ; i < fcnt; i++) ret += area(pt[fc[i].a], pt[fc[i].b], pt[fc[i].c]);
return ret;
}
bool same(int i, int j) {
int a = fc[i].a, b = fc[i].b, c = fc[i].c;
if (sgn(volume(pt[a], pt[b], pt[c], pt[fc[j].a]))) return false;
if (sgn(volume(pt[a], pt[b], pt[c], pt[fc[j].b]))) return false;
if (sgn(volume(pt[a], pt[b], pt[c], pt[fc[j].c]))) return false;
return true;
}
int facecnt() {
int cnt = ;
for (int i = ; i < fcnt; i++) {
bool ok = true;
for (int j = ; j < i; j++) {
if (same(i, j)) {
ok = false;
break;
}
}
if (ok) cnt++;
}
return cnt;
}
Point gravity() {
Point ret = Point(0.0, 0.0, 0.0);
Point O = Point(0.0, 0.0, 0.0);
double vol = 0.0;
for (int i = ; i < fcnt; i++) {
double tmp = volume(pt[fc[i].a], pt[fc[i].b], pt[fc[i].c], O);
ret = ret + (pt[fc[i].a] + pt[fc[i].b] + pt[fc[i].c]) / 4.0 * tmp;
vol += tmp;
}
// cout << ret.x << ' ' << ret.y << ' ' << ret.z << endl;
return ret / vol;
}
} ch; inline double pt2plane(Point o, Point a, Point b, Point c) { return 3.0 * fabs(volume(o, a, b, c) / area(a, b, c));} double getMin() {
double ret = 1e100;
Point g = ch.gravity();
for (int i = ; i < ch.fcnt; i++) {
ret = min(ret, pt2plane(g, ch.pt[ch.fc[i].a], ch.pt[ch.fc[i].b], ch.pt[ch.fc[i].c]));
}
// cout << ret << endl;
return ret;
} int main() {
// freopen("in", "r", stdin);
double x, y, z;
while (true) {
double ans = 0.0;
for (int i = ; i < ; i++) {
if (scanf("%d", &ch.pcnt) == -) return ;
for (int j = ; j < ch.pcnt; j++) {
scanf("%lf%lf%lf", &x, &y, &z);
ch.pt[j] = Point(x, y, z);
}
ch.build();
ans += getMin();
}
printf("%.8f\n", ans);
}
return ;
}
——written by Lyon
poj 3862 && LA 4589 Asteroids (三维凸包+多面体重心)的更多相关文章
- 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 ...
- hdu 4273 2012长春赛区网络赛 三维凸包中心到最近面距离 ***
新模板 /* HDU 4273 Rescue 给一个三维凸包,求重心到表面的最短距离 模板题:三维凸包+多边形重心+点面距离 */ #include<stdio.h> #include&l ...
- POJ 3528--Ultimate Weapon(三维凸包)
Ultimate Weapon Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 2430 Accepted: 1173 ...
- POJ 3528 求三维凸包表面积
也是用模板直接套的题目诶 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include < ...
- 三维凸包求内部一点到表面的最近距离(HDU4266)
http://acm.hdu.edu.cn/showproblem.php?pid=4266 The Worm in the Apple Time Limit: 50000/20000 MS (Jav ...
- 洛谷P4502 [ZJOI2018]保镖(计算几何+三维凸包)
题面 传送门 题解 我对计蒜几盒一无所知 顺便\(xzy\)巨巨好强 前置芝士 三维凸包 啥?你不会三维凸包?快去把板子写了->这里 欧拉公式 \[V-E+F=2\] \(V:vertex\)顶 ...
- hdu4273Rescue(三维凸包重心)
链接 模板题已不叫题.. 三维凸包+凸包重心+点到平面距离(体积/点积) 体积-->混合积(先点乘再叉乘) #include <iostream> #include<cstd ...
- hdu4449Building Design(三维凸包+平面旋转)
链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了&quo ...
随机推荐
- NFS实现(双httpd + php-fpm + nfs + mysql 搭建discuz论坛)的方法
NFS相关介绍 一.NFS简介 1. NFS(Network File System):NFS是一个文件共享协议, 也是是在类Unix系统中在内核中实现的文件系统. 2. 起源:最早是由SUN公司研发 ...
- Linux常用命令2 权限管理命令
1.权限管理命令:chmod 上面图片中的ugoa与rwx并不是一个命令,而是不同选项 u 所有者 g 所属组 o 其他人 a 所有人 r 读取权限 w写入权限 x 执行权限 chmod u+x ...
- R语言与非参数统计(核密度估计)
R语言与非参数统计(核密度估计) 核密度估计是在概率论中用来估计未知的密度函数,属于非参数检验方法之一,由Rosenblatt (1955)和Emanuel Parzen(1962)提出,又名Parz ...
- java memory allocation(转)
Java的运行时数据存储机制 Java程序在运行时需要为一系列的值或者对象分配内存,这些值都存在什么地方?用什么样的数据结构存储?这些数据结构有什么特点?本文试图说明此命题的皮毛之皮毛. 概念 对 ...
- 基于TCP编程的socket
什么是TCP/IP.UDP? TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域 ...
- 【JZOJ4770】【NOIP2016提高A组模拟9.9】闭门造车
题目描述 自从htn体验了一把飙车的快感,他就下定决心要闭门造车!但是他两手空空怎么造得出车来呢?无奈的他只好来到了汽车零部件商店. 一走进商店,玲琅满目的各式零件看得htn眼花缭乱.但是他很快便反应 ...
- 寒哥带你深入了解下Swift中的Value Type
http://www.cocoachina.com/swift/20150923/13539.html 关于开发到底使用ValueType 值类型还是Reference Type 引用类型,关于这个, ...
- 使用VirtualBox + Vagrant打造统一的开发环境
https://blog.csdn.net/openn/article/details/54927375 配置步骤 安装VirtualBox 虚拟系统运行在VirtualBox中,类似的工具还有VMw ...
- JAVA高级特性--String/StringBuffer/Builder
String String对象一旦创建就不能改变 是常量 需要进行大量字符串操作应采用StringBuffer/StringBuilder 最终结果转换成String对象 StringBuffer ...
- linux包之包管理rpm-yum
背景 YUM(Yellow dog Updater, Modified)为多个Linux发行版的前端软件包管理器,例如 Redhat RHEL, CentOS & Fedora. YUM通过调 ...