博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 11769 All Souls Night 的三维凸包要求的表面面积
阅读量:5348 次
发布时间:2019-06-15

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

主题链接:

求给定的3维坐标的凸包的表面积

三维凸包裸题。。

#include 
#include
#include
#include
#include
#include
#include
using namespace std;#define PR 1e-8#define N 510struct TPoint{ double x, y, z; TPoint(){} TPoint(double _x, double _y, double _z):x(_x), y(_y), z(_z){} TPoint operator-(const TPoint p){return TPoint(x-p.x, y-p.y, z-p.z);} TPoint operator*(const TPoint p){return TPoint(y*p.z-z*p.y, z*p.x-x*p.z, x*p.y-y*p.x);} double operator^(const TPoint p){return x*p.x+y*p.y+z*p.z;}};struct fac{ int a, b, c; bool ok;};struct T3dhull{ int n; TPoint ply[N]; int trianglecnt; fac tri[N]; int vis[N][N]; double dist(TPoint a){return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);} double area(TPoint a, TPoint b, TPoint c) { return dist((b-a)*(c-a));} double volume(TPoint a, TPoint b, TPoint c, TPoint d) { return (b-a)*(c-a)^(d-a);} double ptoplane(TPoint &p, fac &f) { TPoint m = ply[f.b] - ply[f.a], n = ply[f.c]-ply[f.a], t = p-ply[f.a]; return (m*n)^t; } void deal(int p, int a, int b){ int f = vis[a][b]; fac add; if(tri[f].ok) { if((ptoplane(ply[p], tri[f])) > PR) dfs(p, f); else { add.a = b, add.b = a, add.c = p, add.ok = 1; vis[p][b] = vis[a][p] = vis[b][a] = trianglecnt; tri[trianglecnt++] = add; } } } void dfs(int p, int cnt) { tri[cnt].ok = 0; deal(p, tri[cnt].b, tri[cnt].a); deal(p, tri[cnt].c, tri[cnt].b); deal(p, tri[cnt].a, tri[cnt].c); } bool same(int s, int e) { TPoint a = ply[tri[s].a], b = ply[tri[s].b], c = ply[tri[s].c]; return fabs(volume(a,b,c,ply[tri[e].a])) < PR && fabs(volume(a,b,c,ply[tri[e].b])) < PR && fabs(volume(a,b,c,ply[tri[e].c])) < PR; } void construct() { int i, j; trianglecnt = 0; if(n<4) return ; bool tmp = true; for(i = 1; i < n; i++) { if((dist(ply[0]-ply[i])) > PR) { swap(ply[1], ply[i]); tmp = false; break; } } if(tmp)return ; tmp = true; for(i = 2; i < n; i++) { if((dist((ply[0]-ply[1])*(ply[1]-ply[i]))) > PR) { swap(ply[2], ply[i]); tmp = false; break; } } if(tmp) return ; tmp = true; for(i = 3; i < n; i++) { if(fabs((ply[0]-ply[1])*(ply[1]-ply[2])^(ply[0]-ply[i]))>PR) { swap(ply[3], ply[i]); tmp =false; break; } } if(tmp)return ; fac add; for(i = 0; i < 4; i++) { add.a = (i+1)%4, add.b = (i+2)%4, add.c = (i+3)%4, add.ok = 1; if((ptoplane(ply[i], add))>0) swap(add.b, add.c); vis[add.a][add.b] = vis[add.b][add.c] = vis[add.c][add.a] = trianglecnt; tri[trianglecnt++] = add; } for(i = 4; i < n; i++) { for(j = 0; j < trianglecnt; j++) { if(tri[j].ok && (ptoplane(ply[i], tri[j])) > PR) { dfs(i, j); break; } } } int cnt = trianglecnt; trianglecnt = 0; for(i = 0; i < cnt; i++) { if(tri[i].ok) tri[trianglecnt++] = tri[i]; } } double area() { double ret = 0; for(int i = 0; i < trianglecnt; i++) ret += area(ply[tri[i].a], ply[tri[i].b], ply[tri[i].c]); return ret/2.0; } double volume() { TPoint p(0,0,0); double ret = 0; for(int i = 0; i < trianglecnt; i++) ret += volume(p, ply[tri[i].a], ply[tri[i].b], ply[tri[i].c]); return fabs(ret/6); }}hull;int main(){ int Cas = 1; while(scanf("%d",&hull.n), hull.n){ int i ; for(i = 0; i < hull.n; i++) scanf("%lf %lf %lf",&hull.ply[i].x, &hull.ply[i].y, &hull.ply[i].z); hull.construct(); printf("Case %d: %.2lf\n", Cas++, hull.area()); } return 0;}

版权声明:本文博主原创文章,博客,未经同意不得转载。

转载于:https://www.cnblogs.com/zfyouxi/p/4854819.html

你可能感兴趣的文章
关于TDD的思考
查看>>
Cocos2d-x学习之windows 7 android环境搭建
查看>>
将html代码中的大写标签转换成小写标签
查看>>
jmeter多线程组间的参数传递
查看>>
零散笔记
查看>>
MaiN
查看>>
[Python学习] 简单网络爬虫抓取博客文章及思想介绍
查看>>
触发器课程SQL Server 知识梳理九 触发器的使用
查看>>
信息浏览器从Android的浏览器中传递cookie数据到App中信息浏览器
查看>>
客户端连接linux虚拟机集群报错
查看>>
linux下部署一个JavaEE项目的简单步骤
查看>>
hash储存机制
查看>>
[Android学习系列16]Android把php输出的json加载到listview
查看>>
20145205 《信息安全系统设计基础》第14周学习总结
查看>>
6)添加一个窗口的图标
查看>>
POJ - 1422 Air Raid 二分图最大匹配
查看>>
Road Map
查看>>
正则替换中的一个Bug
查看>>
HI3531uboot开机画面 分类: arm-linux-Ubunt...
查看>>
制作U盘启动CDLinux 分类: 生活百科 ...
查看>>