An Axis-Aligned Bounding Box (AABB) Sweep Test
2008-11-12 09:45
465 查看
Just
like the name says, the faces of an axis-aligned bounding box are aligned
with the coordinate axes of its parent frame (see Figure 3). In most
cases AABBs can fit an object more tightly than a sphere, and their
overlap test is extremely fast.
To
see if A and B overlap, a separating axis test is used along the x,
y, and z-axes. If the two boxes are disjoint, then at least one of these
will form a separating axis. Figure 4 illustrates an overlap test in
one dimension.
In
this example the x-axis forms a separating axis because
Note
that the separating axis test will return true even if one box fully
contains the other. A more general separating axis test is given in
the section below on oriented bounding boxes (OBB’s). Listing 3 defines
an AABB class that implements this overlap test.
Listing
3. An AABB class.
#include
"vector.h"
// An
axis-aligned bounding box
class
AABB
{
public:
VECTOR P; //position
VECTOR E;
//x,y,z extents
AABB(
const VECTOR& p,
const VECTOR& e ): P(p),
E(e)
{}
//returns
true if this is overlapping b
const bool
overlaps( const AABB& b ) const
{
const
VECTOR T = b.P - P;//vector from A to B
return fabs(T.x)
<= (E.x + b.E.x)
&&
fabs(T.y)
<= (E.y + b.E.y)
&&
fabs(T.z)
<= (E.z + b.E.z);
}
//NOTE:
since the vector indexing operator is not const,
//we must cast
away the const of the this pointer in the
//following
min() and max() functions
//min x,
y, or z
const
SCALAR min( long i ) const
{
return
((AABB*)this)->P - ((AABB*)this)->E[i];
}
//max
x, y, or z
const SCALAR
max( long i ) const
{
return
((AABB*)this)->P[i] + ((AABB*)this)->E[i];
}
};
For
more information on AABBs and their applications, please see [8].
Just
like spheres, AABBs can be swept to find the first and last occurrence
of overlap. In Figure 5(a), A and B experienced displacements va
and vb, respectively, while Figure 5(b) shows B's
displacement as observed by A.
Figure 6 shows
B's displacement as observed by A.
In
this example, the normalized times it took for the x-extents and y-extents
to overlap are given by
and
it can be seen that the x-extents will cross before the y-extents. The
two boxes cannot overlap until all the extents are overlapping, and
the boxes will cease to overlap when any one of these extents becomes
disjoint. If [i]u0,x, u0,y, and u0,z
were the times at which the x, y, and z-extents began to overlap, then
the earliest time at which the boxes could have begun to overlap was
Likewise,
if u1,x, u1,y, and u1,z
are the times at which the x, y, and z-extents become disjoint, then
the earliest time at which the boxes could have become disjoint was
In
order for the two boxes to have overlapped during their displacement,
the condition
must
have been met. Just like in the sphere sweep test, the positions of
first and last overlap can be linearly interpolated with u. Listing
4 gives an implementation of this AABB sweep algorithm.
Listing
4. An AABB sweep algorithm.
#include
"aabb.h"
//Sweep
two AABB's to see if and when they first
//and last
were overlapping
const
bool AABBSweep
(
const
VECTOR& Ea, //extents of AABB A
const VECTOR& A0, //its
previous position
const VECTOR& A1, //its
current position
const VECTOR& Eb, //extents
of AABB B
const VECTOR& B0, //its
previous position
const VECTOR& B1, //its
current position
SCALAR& u0, //normalized
time of first collision
SCALAR& u1 //normalized
time of second collision
)
{
const
AABB A( A0, Ea );//previous state of AABB A
const AABB
B( B0, Eb );//previous state of AABB B
const VECTOR
va = A1 - A0;//displacement of A
const VECTOR
vb = B1 - B0;//displacement of B
//the
problem is solved in A's frame of reference
VECTOR
v = vb - va;
//relative
velocity (in normalized time)
VECTOR
u_0(0,0,0);
//first times of overlap along each axis
VECTOR
u_1(1,1,1);
//last times of overlap along each axis
//check
if they were overlapping
// on the
previous frame
if( A.overlaps(B)
)
{
u0
= u1 = 0;
return
true;
}
//find
the possible first and last times
//of overlap
along each axis
for( long
i=0 ; i<3 ; i++ )
{
if(
A.max(i)<B.min(i) && v[i]<0 )
{
u_0[i]
= (A.max(i) - B.min(i)) / v[i];
}
else
if( B.max(i)<A.min(i) && v[i]>0 )
{
u_0[i]
= (A.min(i) - B.max(i)) / v[i];
}
if(
B.max(i)>A.min(i) && v[i]<0 )
{
u_1[i] = (A.min(i)
- B.max(i)) / v[i];
}
else
if( A.max(i)>B.min(i) && v[i]>0 )
{
u_1[i]
= (A.max(i) - B.min(i)) / v[i];
}
}
//possible
first time of overlap
u0 = MAX(
u_0.x, MAX(u_0.y, u_0.z) );
//possible
last time of overlap
u1 = MIN(
u_1.x, MIN(u_1.y, u_1.z) );
//they
could have only collided if
//the first
time of overlap occurred
//before
the last time of overlap
return u0
<= u1;
}
like the name says, the faces of an axis-aligned bounding box are aligned
with the coordinate axes of its parent frame (see Figure 3). In most
cases AABBs can fit an object more tightly than a sphere, and their
overlap test is extremely fast.
To
see if A and B overlap, a separating axis test is used along the x,
y, and z-axes. If the two boxes are disjoint, then at least one of these
will form a separating axis. Figure 4 illustrates an overlap test in
one dimension.
In
this example the x-axis forms a separating axis because
Note
that the separating axis test will return true even if one box fully
contains the other. A more general separating axis test is given in
the section below on oriented bounding boxes (OBB’s). Listing 3 defines
an AABB class that implements this overlap test.
Listing
3. An AABB class.
#include
"vector.h"
// An
axis-aligned bounding box
class
AABB
{
public:
VECTOR P; //position
VECTOR E;
//x,y,z extents
AABB(
const VECTOR& p,
const VECTOR& e ): P(p),
E(e)
{}
//returns
true if this is overlapping b
const bool
overlaps( const AABB& b ) const
{
const
VECTOR T = b.P - P;//vector from A to B
return fabs(T.x)
<= (E.x + b.E.x)
&&
fabs(T.y)
<= (E.y + b.E.y)
&&
fabs(T.z)
<= (E.z + b.E.z);
}
//NOTE:
since the vector indexing operator is not const,
//we must cast
away the const of the this pointer in the
//following
min() and max() functions
//min x,
y, or z
const
SCALAR min( long i ) const
{
return
((AABB*)this)->P - ((AABB*)this)->E[i];
}
//max
x, y, or z
const SCALAR
max( long i ) const
{
return
((AABB*)this)->P[i] + ((AABB*)this)->E[i];
}
};
For
more information on AABBs and their applications, please see [8].
Just
like spheres, AABBs can be swept to find the first and last occurrence
of overlap. In Figure 5(a), A and B experienced displacements va
and vb, respectively, while Figure 5(b) shows B's
displacement as observed by A.
Figure 6 shows
B's displacement as observed by A.
In
this example, the normalized times it took for the x-extents and y-extents
to overlap are given by
and
it can be seen that the x-extents will cross before the y-extents. The
two boxes cannot overlap until all the extents are overlapping, and
the boxes will cease to overlap when any one of these extents becomes
disjoint. If [i]u0,x, u0,y, and u0,z
were the times at which the x, y, and z-extents began to overlap, then
the earliest time at which the boxes could have begun to overlap was
Likewise,
if u1,x, u1,y, and u1,z
are the times at which the x, y, and z-extents become disjoint, then
the earliest time at which the boxes could have become disjoint was
In
order for the two boxes to have overlapped during their displacement,
the condition
must
have been met. Just like in the sphere sweep test, the positions of
first and last overlap can be linearly interpolated with u. Listing
4 gives an implementation of this AABB sweep algorithm.
Listing
4. An AABB sweep algorithm.
#include
"aabb.h"
//Sweep
two AABB's to see if and when they first
//and last
were overlapping
const
bool AABBSweep
(
const
VECTOR& Ea, //extents of AABB A
const VECTOR& A0, //its
previous position
const VECTOR& A1, //its
current position
const VECTOR& Eb, //extents
of AABB B
const VECTOR& B0, //its
previous position
const VECTOR& B1, //its
current position
SCALAR& u0, //normalized
time of first collision
SCALAR& u1 //normalized
time of second collision
)
{
const
AABB A( A0, Ea );//previous state of AABB A
const AABB
B( B0, Eb );//previous state of AABB B
const VECTOR
va = A1 - A0;//displacement of A
const VECTOR
vb = B1 - B0;//displacement of B
//the
problem is solved in A's frame of reference
VECTOR
v = vb - va;
//relative
velocity (in normalized time)
VECTOR
u_0(0,0,0);
//first times of overlap along each axis
VECTOR
u_1(1,1,1);
//last times of overlap along each axis
//check
if they were overlapping
// on the
previous frame
if( A.overlaps(B)
)
{
u0
= u1 = 0;
return
true;
}
//find
the possible first and last times
//of overlap
along each axis
for( long
i=0 ; i<3 ; i++ )
{
if(
A.max(i)<B.min(i) && v[i]<0 )
{
u_0[i]
= (A.max(i) - B.min(i)) / v[i];
}
else
if( B.max(i)<A.min(i) && v[i]>0 )
{
u_0[i]
= (A.min(i) - B.max(i)) / v[i];
}
if(
B.max(i)>A.min(i) && v[i]<0 )
{
u_1[i] = (A.min(i)
- B.max(i)) / v[i];
}
else
if( A.max(i)>B.min(i) && v[i]>0 )
{
u_1[i]
= (A.max(i) - B.min(i)) / v[i];
}
}
//possible
first time of overlap
u0 = MAX(
u_0.x, MAX(u_0.y, u_0.z) );
//possible
last time of overlap
u1 = MIN(
u_1.x, MIN(u_1.y, u_1.z) );
//they
could have only collided if
//the first
time of overlap occurred
//before
the last time of overlap
return u0
<= u1;
}
相关文章推荐
- AABB(axis-aligned bounding box)
- Cesium AxisAlignedBoundingBox
- Drawing an XNA Model bounding box
- 3D空间中的AABB(轴向平行包围盒, Aixe align bounding box)的求法
- 3D空间中的AABB(轴向平行包围盒, Aixe align bounding box)的求法
- AxisAlignedBox矩形边界框
- 3D空间中的AABB(轴向平行包围盒, Aixe align bounding box)的求法
- poj 2504 Bounding box
- tf.image.crop_to_bounding_box的用法
- Seglink代码之二 数据增强 distorted_bounding_box_crop
- SPAWN and an Associated Mailbox?
- 第一次使用Genymotion遇到的问题:for an unknown reson,VirtualBox DHCP has not assigned an IP address to virtual
- Axis--An implementation of SOAP(Simple Object Access Protocol)
- Bounding Box label code
- maya bounding box & detect intersection of two faces/polygons
- Revit API相交过滤BoundingBoxIntersectsFilter
- How To: Make VirtualBox Use Your Router’s DHCP to get an IP Address in Linux
- python利用opencv标注bounding box
- cocos2d-x3.2中的getVisibleSize,getContentSize,boundingBox,getContentSizeInPixels,convertToGL,convertTo
- Can I use an image for the sidebox header?