bzoj 1964: hull 三维凸包 计算几何

1964: hull 三维凸包

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 54  Solved: 39
[Submit][Status][Discuss]

Description

三维凸包问题是一个基础的三维计算几何问题,不过这次你只需要做一个简单版的三维凸包问题就行了。

Input

输入数据一共有若干行,每行三个整数,表示一个点的坐标。点的个数为五个。

Output

输出一个实数,保留两位小数,表示三维凸包的体积。

Sample Input

0 0 0
2 0 0
0 2 0
2 2 0
1 1 1

Sample Output

1.33

HINT

对于所有数据,坐标范围在[0,100]*[0,100]*[0,100]。

  直接水过,不过网上的三维凸包的标程一个比一个不靠谱,由一组数据拍出来,加上我的程序,三个程序三个答案。整个人都不好了。

  枚举一个面,使得剩下两个点与这条面组成四面体的有向体积符号不同,则两点在面的两侧,计算即可。

  四面体的计算公式是三个向量组成的矩阵行列式的1/6.

  这是居然我的第一个三维算几题。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
#define MAXN 10
typedef double real;
struct point
{
        real x,y,z;
        point(real x,real y,real z):x(x),y(y),z(z){}
        point(){}
        void read()
        {
                scanf("%lf %lf %lf",&x,&y,&z);
        }
}pl[MAXN];;
real area(point p1,point p2,point p3)
{
        return (p1.x*p2.y*p3.z + p1.z*p2.x*p3.y + p1.y*p2.z*p3.x
                -p1.x*p2.z*p3.y - p1.z*p2.y*p3.x - p1.y*p2.x*p3.z)/6;
}
point operator -(point p1,point p2)
{
        return point(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z);
}
typedef point line;

bool vis[MAXN];
int main()
{
        freopen("input.txt","r",stdin);
        for (int i=0;i<5;i++)
        {
                pl[i].read();
        }
//        printf("%.2lf\n",area(pl[1]-pl[0],pl[2]-pl[0],pl[3]-pl[0]));
        real ans=0;
        real s1,s2,s3;
        for (int a=0;a<5;a++)
        {
                vis[a]=true;
                for (int b=0;b<5;b++)
                {
                        if (vis[b])continue;
                        vis[b]=true;
                        for (int c=0;c<5;c++)
                        {
                                if (vis[c])continue;
                                vis[c]=true;
                                for (int d=0;d<5;d++)
                                {
                                        if (vis[d])continue;
                                        vis[d]=true;
                                        for (int e=0;e<5;e++)
                                        {
                                                if (vis[e])continue;
                                                vis[e]=true;
                                                s3=abs(s1=area(pl[c]-pl[a],pl[b]-pl[a],pl[d]-pl[a]))+abs(s2=area(pl[c]-pl[a],pl[b]-pl[a],pl[e]-pl[a]));
                                                if (s1*s2>0)
                                                {
                                                        vis[e]=false;continue;
                                                }
                                                if (s1==0 && s2==0)
                                                {
                                                        vis[e]=false;continue;
                                                }
                                                ans=max(ans,s3);
                                                vis[e]=false;
                                        }
                                        vis[d]=false;
                                }
                                vis[c]=false;
                        }
                        vis[b]=false;
                }
                vis[a]=false;
        }
        printf("%.2lf\n",ans);
}
时间: 2024-10-01 05:03:43

bzoj 1964: hull 三维凸包 计算几何的相关文章

bzoj1964: hull 三维凸包

传送门 二维平面四个点求凸包面积->任选三个点面积之和/2 三维平面五个点求凸包体积->任选四个点体积之和/2 二维平面三个点面积->二个二维向量行列式值的绝对值/2 三维平面四个点体积->三个三维向量行列式值的绝对值/6 1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<

Hdu 3662 3D Convex Hull(三维凸包)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3662 思路:三维凸包模板. #include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #define PR 1e-8 #define N 510 using namespace std; struct TPoint { doub

bzoj 1209: [HNOI2004]最佳包裹 三维凸包

1209: [HNOI2004]最佳包裹 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 160  Solved: 58[Submit][Status][Discuss] Description H 公司生产了一种金属制品,是由一些笔直的金属条支撑起来的,金属条和别的金属条在交点上被焊接在了一起.现在由于美观需要,在这个产品用一层特殊的材料包 裹起来.公司为了节约成本,希望消耗的材料最少(不计裁剪时的边角料的损失).你的程序需要根据给定的输入,给出

POJ3528 HDU3662 三维凸包模板

POJ3528 HDU3662 第一道题 给定若干点 求凸包的表面积,第二题 给定若干点就凸包的面数. 简单说一下三维凸包的求法,首先对于4个点假设不共面,确定了唯一四面体,对于一个新的点,若它不在四面体内,为了让它进入凸包, 则对于所有凸包上的边,若边的一面是该点可以看到的而另一面看不到,则该点与该边构成的面要加入凸包. 模板代码非常清晰, #include<stdio.h> #include<algorithm> #include<string.h> #includ

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

题意: 两个凸多面体,可以任意摆放,最多贴着,问他们重心的最短距离. 解法: 由于给出的是凸多面体,先构出两个三维凸包,再求其重心,求重心仿照求三角形重心的方式,然后再求两个多面体的重心到每个多面体的各个面的最短距离,然后最短距离相加即为答案,因为显然贴着最优. 求三角形重心见此: http://www.cnblogs.com/whatbeg/p/4234518.html 代码:(模板借鉴网上模板) #include <iostream> #include <cstdio> #in

三维凸包模板

poj3528 参照 #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; #define inf 0x7fffffff #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) #define eps 1e-7 #define MAXV 505 //三维点 s

hdu4266(三维凸包模板题)

/*给出三维空间中的n个顶点,求解由这n个顶点构成的凸包表面的多边形个数. 增量法求解:首先任选4个点形成的一个四面体,然后每次新加一个点,分两种情况: 1> 在凸包内,则可以跳过 2> 在凸包外,找到从这个点可以"看见"的面,删除这些面, 然后对于一边没有面的线段,和新加的这个点新建一个面,至于这个点可以看见的面, 就是求出这个面的方程(可以直接求法向量). */ #include<iostream> #include<cmath> #includ

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

链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了"的讲解. 这题说起来很简单,求下三维凸包,枚举每一个面,进行坐标旋转,使得当前面作为xoy面时的其他坐标,然后求下投影面的凸包的面积. 为什么要旋转面而不直接算点到面的距离,是因为投影的面积没有办法算. 面旋转时是怎么旋转的,首先求得当前面的法向量p1,再求得它与向量e(0,0,1)的法向量pp,所有的点

hdu4273Rescue(三维凸包重心)

链接 模板题已不叫题.. 三维凸包+凸包重心+点到平面距离(体积/点积)  体积-->混合积(先点乘再叉乘) 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<