版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、BSP:二叉分割树,是一种分割场景的方法,下面代码是BSP树一种实现可运行:运行例子中,将定义的16个空间面,分割为一个深度是3的BSP树,上图显示的是运行结果:#include "stdafx.h"#include <map>#include <vector>#include <iostream>using namespace std;/定义空间的点结构struct pointfloat x,y,z;point():x(0.0f),y(0.0f),z(0.0f);point(float a,float b,float c):x(a),y
2、(b),z(c)void operator += (int n)x += n;y += n;z += n;void operator = (point& p)memcpy(this,(void*)&p,sizeof(*this);/定义空间的面结构struct facepoint P3;void operator +=(int n)P0 += n;P1 += n;P2 += n;/定义包围盒结构struct BBoxpoint Min;point Max;BBox():Min(),Max();enum EAxis/沿的轴枚举Axis_X,Axis_Y,Axis_Z,;/树节点的
3、定义struct TreeNode TreeNode():box(),nDepth(0),pLChild(NULL),pRChild(NULL),Axis(Axis_X),Split(0.0f)vFaceId.reserve(16);int nDepth;TreeNode* pLChild;TreeNode* pRChild;std:vector<int> vFaceId;int Axis;BBox box;float Split;/存储空间的面std:map<int,face> m_mFace;/通过面ID获取面的地址face* GetFaceByID(int nID
4、)std:map<int,face>:iterator itr = m_mFace.find(nID);if (itr != m_mFace.end() )return &(m_mFacenID);return NULL;/BSP类的定义实现class BspTreepublic:BspTree():m_pRoot(NULL);BspTree()if (m_pRoot)DeleteNode(m_pRoot);/初始化树根void InitTreeRoot(TreeNode *pNode);/释放整个树的资源void DeleteNode(TreeNode * pNode);
5、/生成AABB包围盒void BuildAABB(TreeNode * pNode);/切分整个空间void SplitSpace(TreeNode* pRoot,int nAxis,int ndepth);/切分面void SplitFace( int nFaceId, float fSplit, int nAxis, int* pLeftNum, int* pRightNum, int* pBothNum );/遍历整个树void ErgodicTree(TreeNode * pNode);protected:private:TreeNode *m_pRoot;void BspTree:I
6、nitTreeRoot(TreeNode *pNode)if (pNode = NULL)return;m_pRoot = pNode;void BspTree:DeleteNode(TreeNode * pNode)if (pNode = NULL)return;DeleteNode(pNode->pLChild);DeleteNode(pNode->pRChild);delete pNode;/遍历整个树void BspTree:ErgodicTree(TreeNode * pNode)if (pNode = NULL)return;ErgodicTree(pNode->
7、pLChild);cout<<"节点深度: "<<pNode->nDepth<<"含有多少个面: "<<pNode->vFaceId.size();switch (pNode->Axis)case Axis_X:cout<<" 沿X轴分割"<<"分割点是: x ="<<pNode->Split<<endl;break;case Axis_Y:cout<<" 沿Y轴分割&quo
8、t;<<"分割点是: y ="<<pNode->Split<<endl;break;case Axis_Z:cout<<" 沿Z轴分割"<<"分割点是: z ="<<pNode->Split<<endl;break;ErgodicTree(pNode->pRChild);void BspTree:BuildAABB(TreeNode * pNode)if(!pNode)return;point Min(1000000,1000000,
9、1000000);point Max(-1000000,-1000000,-1000000);for(int n = 0; n < pNode->vFaceId.size(); +n)face *pFa = GetFaceByID(n);if (pFa = NULL)continue;for(int m = 0; m < 3; +m)if (pFa->Pm.x > Max.x) Max.x = pFa->Pm.x;if (pFa->Pm.y > Max.y)Max.y = pFa->Pm.y;if (pFa->Pm.z > Ma
10、x.z)Max.z = pFa->Pm.z;if (pFa->Pm.x < Min.x)Min.x = pFa->Pm.x;if (pFa->Pm.y < Min.y)Min.y = pFa->Pm.y;if (pFa->Pm.z < Min.z)Min.z = pFa->Pm.z;pNode->box.Max = Max;pNode->box.Min = Min;int CompareFloat(float a,float b,float fOff)if (abs(a - b) < fOff)return 0;if
11、 ( a > b)return 1;elsereturn -1;void BspTree:SplitFace( int nFaceId, float fSplit, int nAxis, int* pLeftNum, int* pRightNum, int* pBothNum )face* pFace = GetFaceByID(nFaceId);int nLeftCount = 0;int nRightCount = 0;int nBothCount = 0;float t3;switch( nAxis )case Axis_X:t0 = pFace->P0.x;t1 = pFa
12、ce->P1.x;t2 = pFace->P2.x;break;case Axis_Y:t0 = pFace->P0.y;t1 = pFace->P1.y;t2 = pFace->P2.y;break;case Axis_Z:t0 = pFace->P0.z;t1 = pFace->P1.z;t2 = pFace->P2.z;break;for( int i = 0; i < 3; i+ )int c = CompareFloat( ti, fSplit ,0.001f);if( c < 0 )/ 左边nLeftCount+;else
13、 if( c > 0 )/ 右边nRightCount+;else/ 正中间nBothCount+;*pLeftNum = nLeftCount;*pRightNum = nRightCount;*pBothNum = nBothCount;void BspTree:SplitSpace(TreeNode* pRoot,int nAxis,int ndepth)if(!pRoot)return;pRoot->nDepth = ndepth;pRoot->Axis = nAxis;if (pRoot->vFaceId.size() < 3 | ndepth >
14、 2)pRoot->pLChild = NULL;pRoot->pRChild = NULL;return;pRoot->pLChild = new TreeNode;pRoot->pRChild = new TreeNode;pRoot->pLChild->box.Max = pRoot->box.Max;pRoot->pLChild->box.Min = pRoot->box.Min;pRoot->pRChild->box.Max = pRoot->box.Max;pRoot->pRChild->bo
15、x.Min = pRoot->box.Min;nAxis = (int)Axis_X;float XLength = pRoot->box.Max.x - pRoot->box.Min.x;float YLength = pRoot->box.Max.y - pRoot->box.Min.y;float ZLength = pRoot->box.Max.z - pRoot->box.Min.z;if (YLength > XLength)nAxis = Axis_Y;XLength = YLength;if (ZLength > XLeng
16、th)nAxis = Axis_Z;float fslit = 0.0f;switch (nAxis)case Axis_X:fslit = (pRoot->box.Max.x + pRoot->box.Min.x)/2.0;pRoot->pLChild->box.Max.x = fslit;pRoot->pRChild->box.Min.x = fslit;break;case Axis_Y:fslit = (pRoot->box.Max.y + pRoot->box.Min.y)/2.0;pRoot->pLChild->box.M
17、ax.y = fslit;pRoot->pRChild->box.Min.y = fslit;break;case Axis_Z:fslit = (pRoot->box.Max.z + pRoot->box.Min.z)/2.0;pRoot->pLChild->box.Max.z = fslit;pRoot->pRChild->box.Min.z = fslit;break;pRoot->Split = fslit;int nSize = pRoot->vFaceId.size();int nLeftCount,nRightCount
18、,nBothCount;for (int n = 0; n < nSize; +n)SplitFace(pRoot->vFaceId.at(n),fslit,nAxis,&nLeftCount,&nRightCount,&nBothCount);/ 如果左边有if( nLeftCount > 0 | nBothCount > 0 )pRoot->pLChild->vFaceId.push_back( pRoot->vFaceId.at(n) );if( nRightCount > 0 | nBothCount > 0 )pRoot->pRChild->vFaceId.push_back
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 印后制作员安全生产基础知识评优考核试卷含答案
- 煤气化备配煤工岗位职业健康、安全、环保技术规程
- 公司租用个人车辆协议书范本
- 河北省邯郸市2025-2026学年九年级上学期期中考试化学试卷(含答案)
- 教育学核心解析
- 教育全景:构建立体课程
- 教育共进之路
- 第七章《力》单元检测-2023-2024学年八年级物理(人教版)原卷版+解析
- 2025浙江绍兴市人才市场服务有限公司招聘拟录用人员笔试历年参考题库附带答案详解
- 2025四川科瑞软件有限责任公司招聘风控专员测试笔试历年参考题库附带答案详解
- 第23课《富贵不能淫》课件 2025-2026学年统编版语文八年级上册
- 商场客服服务礼仪培训
- 2025年专升本物理学热力学与统计物理试卷(含答案)
- 企业品牌形象策划与宣传材料制作模板
- 2025心理健康服务市场需求变化及数字化解决方案与盈利模式分析
- 民航十五五规划
- 广交摊位申请书范本
- 进口食品企业质量安全管理制度
- 河南省体育彩票管理中心聘用人员招聘笔试真题2024
- 人力资源岗位岗前培训试题及答案
- 解决学习问题的做法
评论
0/150
提交评论