自己封装的三维AABB包围盒类,用于三维模型静态碰撞检测,可以直接调用,使用OpenGL进行绘制

23 篇文章 13 订阅
5 篇文章 2 订阅

由于需要在三维空间中进行三维模型的碰撞与相交,为了加快检测的效率,考虑用三维物体包围盒。AABB与OOBB包围盒比起来原理简单,容易实现,为了更好的在三维空间中使用AABB包围盒,所以自己写了一个关于三维的AABB包围盒类AABB类,写了不同参数的构造函数,以及关于AABB包围盒的各种成员方法,虽然不是很全,但是可以满足日常的需要。

下面贴代码:

AABB.h

 

#pragma once
typedef struct My3DPoint//定义自己的三维点结构体
{
	double X;//X坐标
	double Y;//Y坐标
	double Z;//Z坐标
};
typedef struct Triangle//三角形的结构体
{
	My3DPoint Verters[3];//三角形的三个顶点
	BOOL IsShow;//三维面是否需要显示
	My3DPoint TriangleFaceNormal;//三角面片的法向量
};
class AABB
{
public:
	AABB(void);//默认的无参构造函数
	~AABB(void);//默认的析构函数
AABB(My3DPoint pointMin,My3DPoint pointMax);//自定义的有参构造函数,参数为两个My3DPoint结构的AABB包围盒最小最大坐标点
AABB(double m_Xmin,double m_Xmax,double m_Ymin,double m_Ymax,double m_Zmin,double m_Zmax);//自定义的有参的构造函数,参数为AABB包围盒最小最大点的坐标
AABB(Triangle a);//传进一个三角形结构体
BOOL IsOrNotInterection(AABB *a);//判断两个AABB包围盒是否相交,如果相交返回TRUE,如果不相交,返回FALSE
BOOL PointIsOrNotInAABBBoundingBox(My3DPoint pt);//判断一三维点是否落在某个AABB包围盒内
My3DPoint GetAABBBoxCeter();//求AABB包围盒的中心或者质心
BOOL IsOrNotEmpty();//判断AABB包围盒是否为空
double GetXLength();//得到X方向上的长度
double GetYLength();//得到Y方向上的长度
double GetZLength();//得到Z方向上的长度
double GetVolume();//得到AABB包围盒的体积
void DrawAABBBoundingBox();//绘制AABB包围盒

private:
	double Xmin;//X的最小值
	double Xmax;//X的最大值
	double Ymin;//Y的最小值
	double Ymax;//Y的最大值
	double Zmin;//Z的最小值
	double Zmax;//Z的最大值
};

AABB.cpp

 

 

#include "StdAfx.h"
#include "AABB.h"

//默认的构造函数
AABB::AABB(void)
{
}
//以AABB包围盒最小最大坐标点的My3DPoint结构体作为参数的构造函数
AABB::AABB(My3DPoint pointMin,My3DPoint pointMax)
{
	Xmin=pointMin.X;
	Ymin=pointMin.Y;
	Zmin=pointMin.Z;
	Xmax=pointMax.X;
	Ymax=pointMax.Y;
	Zmax=pointMax.Z;
}
//以AABB包围盒最小最大坐标点的六个坐标作为参数的构造函数
AABB::AABB(double m_Xmin,double m_Ymin,double m_Zmin,double m_Xmax,double m_Ymax,double m_Zmax)
{
	Xmin=m_Xmin;
	Xmax=m_Xmax;
	Ymin=m_Ymin;
	Ymax=m_Ymax;
	Zmin=m_Zmin;
	Zmax=m_Zmax;
}
//以Triangle三角形结构体作为参数的构造函数
AABB::AABB(Triangle a)
{
	//用三元运算符来求出最大最小值
	//求X的最小值
	Xmin=a.Verters[0].X<a.Verters[1].X?a.Verters[0].X:a.Verters[1].X;
	Xmin=Xmin<a.Verters[2].X?Xmin:a.Verters[3].X;
	//求Y的最小值
	Ymin=a.Verters[0].Y<a.Verters[1].Y?a.Verters[0].Y:a.Verters[1].Y;
	Ymin=Ymin<a.Verters[2].Y?Ymin:a.Verters[3].Y;
	//求Z的最小值
	Zmin=a.Verters[0].Z<a.Verters[1].Z?a.Verters[0].Z:a.Verters[1].Z;
	Zmin=Zmin<a.Verters[2].Z?Zmin:a.Verters[3].Z;
	//求X的最大值
	Xmax=a.Verters[0].X>a.Verters[1].X?a.Verters[0].X:a.Verters[1].X;
	Xmax=Xmax>a.Verters[2].X?Xmax:a.Verters[2].X;
	//求Y的最大值
	Ymax=a.Verters[0].Y>a.Verters[1].Y?a.Verters[0].Y:a.Verters[1].Y;
	Ymax=Ymax>a.Verters[2].Y?Ymax:a.Verters[2].Y;
	//求Z的最大值
	Zmax=a.Verters[0].Z>a.Verters[1].Z?a.Verters[0].Z:a.Verters[1].Z;
	Zmax=Zmax>a.Verters[2].Z?Zmax:a.Verters[2].Z;
}

/*-----IsOrNotInterection(AABB *a,AABB *b)---------
函数功能:判断两个AABB包围盒是否相交
函数参数:a为AABB对象指针,本身对象为b包围盒
--------------------------------------------------*/
//判断两个AABB包围盒是否相交
BOOL AABB::IsOrNotInterection(AABB *a)
{
    return ((Xmin >= a->Xmin && Xmin <= a->Xmax) || 
	(a->Xmin >= Xmin && a->Xmin <= Xmax)) &&
	((Ymin >= a->Ymin && Ymin <= a->YMax) || 
	(a->Ymin >= Ymin && a->Ymin <= YMax)) &&
	((Zmin >= a->Zmin && Zmin <= a->Zmax) || 
	(a->Zmin >= Zmin && a->Zmin <= Zmax));
}
/*-----PointIsOrNotInAABBBoundingBox(My3DPoint pt,AABB *box)判断点是否落在AABB包围盒之内------
函数功能:判断三维点是否落在AABB包围盒之内
函数参数:pt为My3DPoint结构体,box为AABB包围盒对象指针
---------------------------------------------------------------------------------------------*/

BOOL AABB::PointIsOrNotInAABBBoundingBox(My3DPoint pt)
{
	return (pt.X>=Xmin)&&(pt.X<=Xmax)&&
		(pt.Y>=Ymin)&&(pt.Y<=Ymax)&&
		(pt.Z>=Zmin)&&(pt.Z<=Zmax);
}

/*-----GetAABBBoxCeter()-------------------------------------------
函数功能:得到此AABB包围盒对象的质心,中心,返回一个My3DPoint结构体
-------------------------------------------------------------------*/
My3DPoint AABB::GetAABBBoxCeter()
{
	My3DPoint m_point;
	m_point.X=(Xmin+Xmax)*0.5;
	m_point.Y=(Ymin+Ymax)*0.5;
	m_point.Z=(Zmin+Zmax)*0.5;
	return m_point;
}

/*-----IsOrNotEmpty()---------------------------------------------
函数功能:判断AABB包围盒是否为空,为空返回TRUE,不为空返回FALSE
------------------------------------------------------------------*/
BOOL AABB::IsOrNotEmpty()
{
	return(Xmin>Xmax)||(Ymin>Ymax)||(Zmin>Zmax);
}
/*-----GetXLength()---------
函数功能:得到X方向上的长度
--------------------------*/
double AABB::GetXLength()
{
	return Xmax-Xmin;
}
/*-----GetYLength()---------
函数功能:得到Y方向上的长度
--------------------------*/
double AABB::GetYLength()
{
	return Ymax-Ymin;
}
/*-----GetZLength()---------
函数功能:得到Z方向上的长度
--------------------------*/
double AABB::GetZLength()
{
	return Zmax-Zmin;
}
/*-----GetVolume()-------------
函数功能:得到AABB包围盒的体积
------------------------------*/
double AABB::GetVolume()
{
	return (Xmax-Xmin)*(Ymax-Ymin)*(Zmax-Zmin);
}

/*-----DrawAABBBoundingBox()-------------------
函数功能:绘制AABB包围盒
-----------------------------------------------*/
void AABB::DrawAABBBoundingBox()
{
	//第一根线
	glBegin(GL_LINE);
	glVertex3f(Xmin,Ymin,Zmin);
	glVertex3f(Xmax,Ymin,Zmin);
	glEnd();
	//第二根线
	glBegin(GL_LINE);
	glVertex3f(Xmin,Ymin,Zmin);
	glVertex3f(Xmin,Ymin,Zmax);
	glEnd();
	//第三根线
	glBegin(GL_LINE);
	glVertex3f(Xmin,Ymin,Zmin);
	glVertex3f(Xmin,Ymax,Zmin);
	glEnd();
	//第四根线
	glBegin(GL_LINE);
	glVertex3f(Xmin,Ymin,Zmax);
	glVertex3f(Xmax,Ymin,Zmax);
	glEnd();
	//第五根线
	glBegin(GL_LINE);
	glVertex3f(Xmax,Ymin,Zmin);
	glVertex3f(Xmax,Ymin,Zmax);
	glEnd();
	//第六根线
	glBegin(GL_LINE);
	glVertex3f(Xmax,Ymin,Zmin);
	glVertex3f(Xmax,Ymax,Zmin);
	glEnd();
	//第七根线
	glBegin(GL_LINE);
	glVertex3f(Xmax,Ymax,Zmin);
	glVertex3f(Xmin,Ymax,Zmin);
	glEnd();
	//第八根线
	glBegin(GL_LINE);
	glVertex3f(Xmin,Ymax,Zmin);
	glVertex3f(Xmin,Ymax,Zmax);
	glEnd();
	//第九根线
	glBegin(GL_LINE);
	glVertex3f(Xmax,Ymax,Zmin);
	glVertex3f(Xmax,Ymax,Zmax);
	glEnd();
	//第十根线
	glBegin(GL_LINE);
	glVertex3f(Xmin,Ymin,Zmax);
	glVertex3f(Xmin,Ymax,Zmax);
	glEnd();
	//第十一根线
	glBegin(GL_LINE);
	glVertex3f(Xmax,Ymin,Zmax);
	glVertex3f(Xmax,Ymax,Zmax);
	glEnd();
	//第十二根线
	glBegin(GL_LINE);
	glVertex3f(Xmin,Ymax,Zmax);
	glVertex3f(Xmax,Ymax,Zmax);
	glEnd();

}
AABB::~AABB(void)
{
}


如果日后有修改会贴上修改后的代码。

如果您觉得这篇博文有用,请访问我的个人站:http://www.stubbornhuang.com,更多博文干货等着您。

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HW140701

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值