AABB包囲ボックスアルゴリズム
3852 ワード
OgreのVector 3が使用されているので、まずOgreの環境を構成する必要があり、ここではこれ以上説明しない.
以下はAABBヘッダファイルです:aabb.h
以下、AABBの実装:aabb.cpp
次はメイン関数です:main.cpp
以下はAABBヘッダファイルです:aabb.h
#ifndef AABB3_H
#define AABB3_H
#include "OgreOde_Core.h"
#include "OgreOde_Prefab.h"
#include "OgreOde_Loader.h"
class cAABB3
{
public:
Ogre::Vector3 min,max;
public:
//query for dimentions
Ogre::Vector3 size() const {return max - min;}
Ogre::Real x_size() {return max.x - min.x;}
Ogre::Real y_size() {return max.y - min.y;}
Ogre::Real z_size() {return max.z - min.z;}
Ogre::Vector3 center() const {return (min + max)*0.5f;}
// 8
Ogre::Vector3 corner(int i) const;
//
void empty();
//add a point to the box
void add(const Ogre::Vector3 &p);
//add an AABB to the box
void add(const cAABB3 &box);
//return true if the box is empty
bool is_empty() const;
//return true if the box contains a point
bool contains(const Ogre::Vector3 &p) const;
//return the clostet point on this box to another point
Ogre::Vector3 clostet_point_to(const Ogre::Vector3 &p) const;
};
#endif
以下、AABBの実装:aabb.cpp
#include "aabb.h"
//Empty the box, by setting the values to really large/small numbers
void cAABB3::empty()
{
const Ogre::Real big_number = 1e37f;
min.x = min.y = min.z = big_number;
max.x = max.y = max.z = -big_number;
}
//Add a point to the box
void cAABB3::add(const Ogre::Vector3 &p)
{
//expand the box as necessary to contain the point
if(p.x < min.x)
min.x = p.x;
if(p.x > max.x)
max.x = p.x;
if(p.y < min.y)
min.y = p.y;
if(p.y > max.y)
max.y = p.y;
if(p.z < min.z)
min.z = p.z;
if(p.z > max.z)
max.z = p.z;
}
//return one of the 8 corner points.
//Bit 0 selects min.x vs max.x
//bit 1 selects min.y vs max.y
//bit 2 selects min.z vs max.z
Ogre::Vector3 cAABB3::corner(int i) const
{
assert(i >= 0 && i <= 7); //make sure index is in range
return Ogre::Vector3((i&1)?max.x:min.y,
(i&2)?max.y:min.y,(i&4)?max.z:min.z);
}
//add an AABB to the box
void cAABB3::add(const cAABB3 &box)
{
//expand the box as necessary
if(box.min.x < min.x)
min.x = box.min.x;
if(box.max.x > max.x)
max.x = box.max.x;
if(box.min.y < min.y)
min.y = box.min.y;
if(box.max.y > max.y)
max.y = box.max.y;
if(box.min.z < min.z)
min.z = box.min.z;
if(box.max.z > max.z)
max.z = box.max.z;
}
//return true if the box is empty
bool cAABB3::is_empty() const
{
//check if we're inverted on any axis
return (min.x>max.x)||(min.y>max.y)||(min.z>max.z);
}
//return true if the box contains a point
bool cAABB3::contains(const Ogre::Vector3 &p) const
{
//check for overlap on each axis
return (p.x>=min.x)&&(p.x<=max.x)&&(p.y>=min.y)&&
(p.y<=max.y)&&(p.z>=min.z)&&(p.z<=max.z);
}
//return the closest point on this box to another point
Ogre::Vector3 cAABB3::clostet_point_to(const Ogre::Vector3 &p) const
{
//push p into the box, on each dimension
Ogre::Vector3 r;
if(p.x < min.x)
r.x = min.x;
else if(p.x > max.x)
r.x = max.x;
else
r.x = p.x;
if(p.y < min.y)
r.y = min.y;
else if(p.y > max.y)
r.y = max.y;
else
r.y = p.y;
if(p.z < min.z)
r.z = min.z;
else if(p.z > max.z)
r.z = max.z;
else
r.z = p.z;
return r;
}
次はメイン関数です:main.cpp
#include
#include "aabb.h"
int main()
{
const int N = 10;
Ogre::Vector3 list[N] = {Ogre::Vector3(0,0,0),Ogre::Vector3(1,0,0),Ogre::Vector3(2,0,0),
Ogre::Vector3(3,0,0),Ogre::Vector3(4,0,0),Ogre::Vector3(10,10,10),
Ogre::Vector3(10,0,10),Ogre::Vector3(0,0,10),Ogre::Vector3(0,10,0),
Ogre::Vector3(0,10,10)};
cAABB3 box;
box.empty();
for(int i = 0; i != N; i++)
{
box.add(list[i]);
}
std::cout<