链接

模板题已不叫题。。

三维凸包+凸包重心+点到平面距离(体积/点积)  体积-->混合积(先点乘再叉乘)

 #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(三维凸包重心)的更多相关文章

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

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

  2. POJ 3528 求三维凸包表面积

    也是用模板直接套的题目诶 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include < ...

  3. POJ3528 HDU3662 三维凸包模板

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

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

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

  5. 三维凸包求重心到面的最短距离(HDU4273)

    http://acm.hdu.edu.cn/showproblem.php?pid=4273 Rescue Time Limit: 2000/1000 MS (Java/Others)    Memo ...

  6. 三维凸包求其表面积(POJ3528)

    Ultimate Weapon Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 2074   Accepted: 989 D ...

  7. 三维凸包求凸包表面的个数(HDU3662)

    3D Convex Hull Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  8. 三维凸包求内部一点到表面的最近距离(HDU4266)

    http://acm.hdu.edu.cn/showproblem.php?pid=4266 The Worm in the Apple Time Limit: 50000/20000 MS (Jav ...

  9. hdu4449Building Design(三维凸包+平面旋转)

    链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了&quo ...

随机推荐

  1. 使用hbuilder编辑器实现移动app打包

    作为一枚web前端来讲,需要了解的东西太多,需要学习的也太多了,那天因为公司需求,就研究了下移动网站打包成app的方法,这种东西好像是H5出来后就有推出的,因为性功能不行,就没怎么关注,但现在移动互联 ...

  2. .NET 泛型分析

    .NET 泛型解析 一.问题背景 我们在编程的时候往往因为需要处理不同类型的数据或者对象,重复编写很多类似的代码,造成代码的冗余,代码也显得不那么优雅,泛型的出现,正好是为了解决这个问题,实现继承. ...

  3. EF并非我们想象的那么智能

    我之前在项目中用EF读取一个视图的数据,页面展示出现重复数据,当时百思不得其解,跟踪代码,数据读取时取到的数据并不是重复,为什么在前台显示就有重复了呢,我当时就在业务层将数据去重,但取到的数据跟数据库 ...

  4. [WCF]DomainServices客户端操作异常处理

    作为个人备忘,不做排版.此扩展函数用于DomainServices的Load及SubmitChanges时处理Error信息,包括验证消息.实体冲突. public static string ToE ...

  5. PHP就业班心得:PHP的基本含义与功能特点

    PHP的含义 PHP的原始含义:Personal Home Page  个人主页 最开始是加拿大的一哥们,开发了一个在线脚本工具,用来记录有多少人访问过他的在线简历,很受欢迎,于是他就开始开发自己的工 ...

  6. centos5安装salt-master

    本篇文档主要解决2个问题: 1. centos5通过yum安装的master版本肯定低于centos6安装的minion,所以必须升级salt-master 2. zeromq版本太低会报这个错 20 ...

  7. 面试题HTML +CSS

    HTML+CSS部分1.行内元素和块级元素?img算什么?行内元素怎么转化为块级元素?行内元素:和有他元素都在一行上,高度.行高及外边距和内边距都不可改变,文字图片的宽度不可改变,只能容纳文本或者其他 ...

  8. JS—实现拖拽

    JS中的拖拽示例:    1)实现拖拽思路:当鼠标按下和拖拽过程中,鼠标与拖拽物体之间的相对距离保持不变    2)实现拖拽遇到的问题:        问题1:当鼠标按下移动过快时,离开了拖拽的物体时 ...

  9. Jenkins安装与基本配置

    环境:centos 6.5,jenkins依赖jdk,当前版本推荐jdk1.8,1.7也可以用 首先,机器应该可以访问外网,用yum安装即可(这里版本号是2.19.4): wget -O /etc/y ...

  10. RabbitMQ 入门 Helloworld

    1.介绍 RabbitMQ 是信息传输的中间者.本质上,他从生产者(producers)接收消息,转发这些消息给消费者(consumers).换句话说,他能够按根据你指定的规则进行消息转发.缓冲.和持 ...