Search code examples
c++rotationgame-physicsbounding-boxaabb

Calculating AABB from Box (center, halfSize, rotation)


I want to calculate AABB (axis aligned bounding box) from my Box class.

The box class:

Box{
    Point3D center; //x,y,z
    Point3D halfSize; //x,y,z
    Point3D rotation; //x,y,z rotation
};

The AABB class (Box, but without rotation):

BoundingBox{
    Point3D center; //x,y,z
    Point3D halfSize; //x,y,z
};

Ofc, when rotation = (0,0,0), BoundingBox = Box. But how to calculate minimum BoundingBox that contains everything from Box when rotation = (rx,ry,rz)?

If somebody asks: the rotation is in radians and I use it in DirectX matrix rotation:

XMMATRIX rotX = XMMatrixRotationX( rotation.getX() );
XMMATRIX rotY = XMMatrixRotationY( rotation.getY() );
XMMATRIX rotZ = XMMatrixRotationZ( rotation.getZ() );
XMMATRIX scale = XMMatrixScaling( 1.0f, 1.0f, 1.0f );
XMMATRIX translate = XMMatrixTranslation( center.getX(), center.getY(), center.getZ() );
XMMATRIX worldM = scale * rotX * rotY * rotZ * translate;

Solution

  • You can use matrix rotations in Cartesian coordinates. A rotation of an angle A around the x axis is defined by the matrix:

                 1     0      0 
        Rx(A) =  0   cos(A)  -sin(A) 
                 0   sin(A)   cos(A)
    

    If you do the same for an angle B around y and C around z you have:

                 cos(B)     0      sin(B) 
        Ry(B) =    0        1        0 
                -sin(B)     0      cos(A)
    

    and

             cos(C)   -sin(C)  0 
    Rz(C) =  sin(C)    cos(C)  0 
               0         0     1
    

    With this you can calculate (even analytically) the final rotation matrix. Let's say that you rotate (in that order) along z, then along y then along x (note that the axis x,y,z are fixed in space, they do not rotate at each rotation). The final matrix is the product:

    R = Rx(A) Ry(B) Rz(C)
    

    Now you can construct vectors with the positions of the six corners and apply the full rotation matrix to these vectors. This will give the positions of the six corners in the rotated version. Then just calculate the distance between opposing corners and you have the new bounding box dimensions.