博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 3862 Asteroids (三维凸包,求两个凸包重心到表面的最短距离)
阅读量:5879 次
发布时间:2019-06-19

本文共 4967 字,大约阅读时间需要 16 分钟。

Asteroids
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 297   Accepted: 65   Special Judge

Description

Association of Collision Management (ACM) is planning to perform the controlled collision of two asteroids. The asteroids will be slowly brought together and collided at negligible speed. ACM expects asteroids to get attached to each other and form a stable object.
Each asteroid has the form of a convex polyhedron. To increase the chances of success of the experiment ACM wants to bring asteroids together in such manner that their centers of mass are as close as possible. To achieve this, ACM operators can rotate the asteroids and move them independently before bringing them together.
Help ACM to find out what minimal distance between centers of mass can be achieved.
For the purpose of calculating center of mass both asteroids are considered to have constant density.

Input

Input file contains two descriptions of convex polyhedra.
The first line of each description contains integer number n - the number of vertices of the polyhedron (4 <= n <= 60). The following n lines contain three integer numbers xi, yi, zi each - the coordinates of the polyhedron vertices (-10
4 <= xi, yi, zi <= 10
4). It is guaranteed that the given points are vertices of a convex polyhedron, in particular no point belongs to the convex hull of other points. Each polyhedron is non-degenerate.
The two given polyhedra have no common points.

Output

Output one floating point number - the minimal distance between centers of mass of the asteroids that can be achieved. Your answer must be accurate up to 10
-5.

Sample Input

80 0 00 0 10 1 00 1 11 0 01 0 11 1 01 1 150 0 51 0 6-1 0 60 1 60 -1 6

Sample Output

0.75

Source

 
就是对两个凸包求重心到表面的最短距离。
/*HDU 4273 Rescue给一个三维凸包,求重心到表面的最短距离模板题:三维凸包+多边形重心+点面距离*/#include
#include
#include
#include
#include
using namespace std;const int MAXN=550;const double eps=1e-8;struct Point{ double x,y,z; Point(){} Point(double xx,double yy,double zz):x(xx),y(yy),z(zz){} //两向量之差 Point operator -(const Point p1) { return Point(x-p1.x,y-p1.y,z-p1.z); } //两向量之和 Point operator +(const Point p1) { return Point(x+p1.x,y+p1.y,z+p1.z); } //叉乘 Point operator *(const Point p) { return Point(y*p.z-z*p.y,z*p.x-x*p.z,x*p.y-y*p.x); } Point operator *(double d) { return Point(x*d,y*d,z*d); } Point operator / (double d) { return Point(x/d,y/d,z/d); } //点乘 double operator ^(Point p) { return (x*p.x+y*p.y+z*p.z); }};struct CH3D{ struct face { //表示凸包一个面上的三个点的编号 int a,b,c; //表示该面是否属于最终凸包上的面 bool ok; }; //初始顶点数 int n; //初始顶点 Point P[MAXN]; //凸包表面的三角形数 int num; //凸包表面的三角形 face F[8*MAXN]; //凸包表面的三角形 int g[MAXN][MAXN]; //向量长度 double vlen(Point a) { return sqrt(a.x*a.x+a.y*a.y+a.z*a.z); } //叉乘 Point cross(const Point &a,const Point &b,const Point &c) { return Point((b.y-a.y)*(c.z-a.z)-(b.z-a.z)*(c.y-a.y), (b.z-a.z)*(c.x-a.x)-(b.x-a.x)*(c.z-a.z), (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x) ); } //三角形面积*2 double area(Point a,Point b,Point c) { return vlen((b-a)*(c-a)); } //四面体有向体积*6 double volume(Point a,Point b,Point c,Point d) { return (b-a)*(c-a)^(d-a); } //正:点在面同向 double dblcmp(Point &p,face &f) { Point m=P[f.b]-P[f.a]; Point n=P[f.c]-P[f.a]; Point t=p-P[f.a]; return (m*n)^t; } void deal(int p,int a,int b) { int f=g[a][b];//搜索与该边相邻的另一个平面 face add; if(F[f].ok) { if(dblcmp(P[p],F[f])>eps) dfs(p,f); else { add.a=b; add.b=a; add.c=p;//这里注意顺序,要成右手系 add.ok=true; g[p][b]=g[a][p]=g[b][a]=num; F[num++]=add; } } } void dfs(int p,int now)//递归搜索所有应该从凸包内删除的面 { F[now].ok=0; deal(p,F[now].b,F[now].a); deal(p,F[now].c,F[now].b); deal(p,F[now].a,F[now].c); } bool same(int s,int t) { Point &a=P[F[s].a]; Point &b=P[F[s].b]; Point &c=P[F[s].c]; return fabs(volume(a,b,c,P[F[t].a]))
eps) { swap(P[1],P[i]); flag=false; break; } } if(flag)return; flag=true; //使前三个点不共线 for(i=2;i
eps) { swap(P[2],P[i]); flag=false; break; } } if(flag)return; flag=true; //使前四个点不共面 for(int i=3;i
eps) { swap(P[3],P[i]); flag=false; break; } } if(flag)return; //***************************************** for(i=0;i<4;i++) { add.a=(i+1)%4; add.b=(i+2)%4; add.c=(i+3)%4; add.ok=true; if(dblcmp(P[i],add)>0)swap(add.b,add.c); g[add.a][add.b]=g[add.b][add.c]=g[add.c][add.a]=num; F[num++]=add; } for(i=4;i
eps) { dfs(i,j); break; } } } tmp=num; for(i=num=0;i

 

转载地址:http://uwcix.baihongyu.com/

你可能感兴趣的文章
python活用isdigit方法显示系统进程
查看>>
项目开发总结
查看>>
知行合一
查看>>
jmeter插件之jsonpath提取响应结果和做断言
查看>>
发布支持多线程的PowerShell模块 —— MultiThreadTaskRunner
查看>>
Ubuntu ctrl+alt会导致窗口还原的问题
查看>>
第四十期百度技术沙龙笔记整理
查看>>
推荐系统那点事 —— 基于Spark MLlib的特征选择
查看>>
linux 下RTL8723/RTL8188调试记录(命令行)【转】
查看>>
SpringMVC案例1——对User表进行CRUD操作
查看>>
看雪CTF第十四题
查看>>
[Contiki系列论文之1]Contiki——为微传感器网络而生的轻量级的、灵活的操作系统...
查看>>
Android 网络编程 记录
查看>>
微软同步发行Windows 10和Windows 10 Mobile系统更新
查看>>
Maven 传递依赖冲突解决(了解)
查看>>
Zeppelin的入门使用系列之使用Zeppelin运行shell命令(二)
查看>>
[Spark][Python]Spark Join 小例子
查看>>
form表单下的button按钮会自动提交表单的问题
查看>>
springBoot介绍
查看>>
Intellij IDEA 快捷键整理
查看>>