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 ...
随机推荐
- 1.3 第一个C#程序
几乎没一门编程语言的第一个程序都叫“你好,世界”,所以先在visual studio 中创建一个Helloworld程序. 各部分的详细内容: Main方法是程序运行的起点,最重要的代码就写在Main ...
- gulp使用引导
全局安装npm install –g gulp 安装到本地 npm install gulp –save-dev 新建gulpfile.js 编写文件内容并运行 var gulp = requi ...
- aspcms,2.x以上版本,保护栏目不可删除处理方法
aspcms,2.x以上版本,保护栏目不可删除处理方法.首先找到\admin\_content\_Sort\AspCms_SortFun.asp这个文件.然后将if isnul(id) then a ...
- django静态文件配置
开发环境配置 需要下面几个步骤 1. 在app目录下创建static目录,将静态文件和相关文件夹放到此目录下,如your_app/static/img等 2. 确保settings.py中的INSTA ...
- 日常总结——JSP篇(补)
序—— 初次接触JSP,写一个登录注册界面 正文—— JSP介绍:JSP通过在标准的HTML页面中插入java代码,其静态的部分无须java程序控制.每个JSP页面就是一个servlet实例, WEB ...
- 中文乱码~Windows 7
1.安装匹配的中文语言包 2.安装中文字体
- 基于CNN的人脸相似度检测
人脸相似度检测主要是检测两张图片中人脸的相似度,从而判断这两张图片的对象是不是一个人. 在上一篇文章中,使用CNN提取人脸特征,然后利用提取的特征进行分类.而在人脸相似度检测的工作中,我们也可以利用卷 ...
- Weblogic日志机制详解
服务器日志 每个 WebLogic Server 实例将来自子系统和应用程序的所有消息写入位于本地主机上的服务器日志文件.默认情况下,服务器日志文件位于服务器实例根目录下的 logs 目录中:例如, ...
- bootstrap——下拉菜单右对齐
通过向 .dropdown-menu 添加 .pull-right 类来向右对齐下拉菜单. Bootstrap默认情况下,下拉菜单自动沿着父元素的上沿和左侧被定位为 100% 宽度. 为 .dropd ...
- angularJS和jQuery的区别
问题: 假如我熟悉利用jQuery去开发客户端应用,那么我怎么上手angularjs,能否描述下所需要的模式转变,下面这些问题能够帮助你给出一个回答: 1.在设计客户端web应用的时候有什么区别,最大 ...