简介:
AABB是最常用的碰撞检测使用的包围盒。听起来好像很神秘的,其实就是一个简单的数据结构。
原理可以一句话概括:
因为可以说所有的2d和3d物体都是由点组成的,所以只要找出这些物体的最大值点和最小值点,那么就可以使用这两个点表示该物体的AABB包围盒了。
检测碰撞的时候我们只需要检测这些物体的AABB(即他们的最大值点和最小值点)是否相交,就可以判断是否碰撞了。
缺点:
不准确,因为AABB不能很准确地包围一个物体,所以难免会在不相交的时候误判为相交,如下图:
但是对于一般应用来说,这点误差可以容忍。
优点:
计算简单,速度很快。也因为这样所以应用很广。
下面看看如何表示一个AABB类:
定义:
#ifndef AABB_H
#define AABB_H
#include "Vector3.h"
class AABB
{
public:
AABB();
AABB(const AABB &aabb);
~AABB();
void add(const Vector3 &v);
void clear();
void makeAABB(Vector3 V[], int n);
Vector3 min, max, center;
};
void aabbPrint(AABB &ab);
#endif
类实现:
#include<iostream>
#include"AABB.h"
AABB::AABB()
{
}
AABB::AABB(const AABB &aabb)
{
min = aabb.min;
max = aabb.max;
center = aabb.center;
}
void AABB::clear()
{
min.x = min.y = min.z = FLT_MAX;
//careful: This is not FLT_MIN, 'cause FLT_MIN is a little larger than 0,
//hence not a minus value.
max.x = max.y = max.z = -FLT_MAX;
}
void AABB::add(const Vector3 &v)
{
if (v.x < min.x) min.x = v.x;
if (v.y < min.y) min.y = v.y;
if (v.z < min.z) min.z = v.z;
if (v.x > max.x) max.x = v.x;
if (v.y > max.y) max.y = v.y;
if (v.z > max.z) max.z = v.z;
}
//make AABB out of Vector3 points
void AABB::makeAABB(Vector3 V[], int n)
{
if (!V) return;
for (int i = 0; i < n; i++)
add(V[i]);
center.x = (min.x + max.x) * 0.5f;
center.y = (min.y + max.y) * 0.5f;
center.z = (min.z + max.z) * 0.5f;
}
AABB::~AABB()
{
}
void aabbPrint(AABB &ab)
{
std::cout<<"AABB min is: ";
ab.min.printVec3();
std::cout<<"AABB max is: ";
ab.max.printVec3();
std::cout<<std::endl;
}
测试:
#include<iostream>
#include "AABB.h"
using namespace std;
void test()
{
AABB aabb;
aabbPrint(aabb);
Vector3 v1(1.0f, 2.0f, 3.0f);
Vector3 v2(3.0f, 2.0f, 1.0f);
Vector3 v3(-1.0f, -2.0f, -3.0f);
Vector3 v4(-2.0f, 1.0f, 3.0f);
Vector3 v5(2.0f, -1.0f, 3.0f);
Vector3 v6(2.0f, 2.0f, -2.0f);
Vector3 v[] = {v1,v2,v3,v4,v5,v6};
aabb.makeAABB(v, 6);
aabbPrint(aabb);
}
int main()
{
test();
system("pause");
return 0;
}
运行结果: