AABB类实现

简介:

AABB是最常用的碰撞检测使用的包围盒。听起来好像很神秘的,其实就是一个简单的数据结构。

原理可以一句话概括:

因为可以说所有的2d和3d物体都是由点组成的,所以只要找出这些物体的最大值点和最小值点,那么就可以使用这两个点表示该物体的AABB包围盒了。

检测碰撞的时候我们只需要检测这些物体的AABB(即他们的最大值点和最小值点)是否相交,就可以判断是否碰撞了。

缺点:

不准确,因为AABB不能很准确地包围一个物体,所以难免会在不相交的时候误判为相交,如下图:

但是对于一般应用来说,这点误差可以容忍。

优点:

计算简单,速度很快。也因为这样所以应用很广。

下面看看如何表示一个AABB类:

定义:

[cpp][/cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片

  1. #ifndef AABB_H
  2. #define AABB_H
  3. #include “Vector3.h”
  4. class AABB
  5. {
  6. public:
  7.     AABB();
  8.     AABB(const AABB &aabb);
  9.     ~AABB();
  10.     void add(const Vector3 &v);
  11.     void clear();
  12.     void makeAABB(Vector3 V[], int n);
  13.     Vector3 min, max, center;
  14. };
  15. void aabbPrint(AABB &ab);
  16. #endif

类实现:

[cpp][/cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片

  1. #include<iostream>
  2. #include”AABB.h”
  3. AABB::AABB()
  4. {
  5. }
  6. AABB::AABB(const AABB &aabb)
  7. {
  8.     min = aabb.min;
  9.     max = aabb.max;
  10.     center = aabb.center;
  11. }
  12. void AABB::clear()
  13. {
  14.     min.x = min.y = min.z = FLT_MAX;
  15.     //careful: This is not FLT_MIN, ’cause FLT_MIN is a little larger than 0,
  16.     //hence not a minus value.
  17.     max.x = max.y = max.z = -FLT_MAX;
  18. }
  19. void AABB::add(const Vector3 &v)
  20. {
  21.     if (v.x < min.x) min.x = v.x;
  22.     if (v.y < min.y) min.y = v.y;
  23.     if (v.z < min.z) min.z = v.z;
  24.     if (v.x > max.x) max.x = v.x;
  25.     if (v.y > max.y) max.y = v.y;
  26.     if (v.z > max.z) max.z = v.z;
  27. }
  28. //make AABB out of Vector3 points
  29. void AABB::makeAABB(Vector3 V[], int n)
  30. {
  31.     if (!V) return;
  32.     for (int i = 0; i < n; i++)
  33.         add(V[i]);
  34.     center.x = (min.x + max.x) * 0.5f;
  35.     center.y = (min.y + max.y) * 0.5f;
  36.     center.z = (min.z + max.z) * 0.5f;
  37. }
  38. AABB::~AABB()
  39. {
  40. }
  41. void aabbPrint(AABB &ab)
  42. {
  43.     std::cout<<“AABB min is: “;
  44.     ab.min.printVec3();
  45.     std::cout<<“AABB max is: “;
  46.     ab.max.printVec3();
  47.     std::cout<<std::endl;
  48. }

测试:

[cpp][/cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片

  1. #include<iostream>
  2. #include “AABB.h”
  3. using namespace std;
  4. void test()
  5. {
  6.     AABB aabb;
  7.     aabbPrint(aabb);
  8.     Vector3 v1(1.0f, 2.0f, 3.0f);
  9.     Vector3 v2(3.0f, 2.0f, 1.0f);
  10.     Vector3 v3(-1.0f, -2.0f, -3.0f);
  11.     Vector3 v4(-2.0f, 1.0f, 3.0f);
  12.     Vector3 v5(2.0f, -1.0f, 3.0f);
  13.     Vector3 v6(2.0f, 2.0f, -2.0f);
  14.     Vector3 v[] = {v1,v2,v3,v4,v5,v6};
  15.     aabb.makeAABB(v, 6);
  16.     aabbPrint(aabb);
  17. }
  18. int main()
  19. {
  20.     test();
  21.     system(“pause”);
  22.     return 0;
  23. }

运行结果:

标签