/*
 * "Transforming Axis-Aligned Bounding Boxes",
 *  by Jim Arvo, in "Graphics Gems", Academic Press, 1990.
 *
 * This function transforms a 3D axis-aligned box using a 3x3 
 * matrix and a translation vector.  It returns the tightest
 * axis-aligned box that encloses the result. 
 *
 * The utility of this algorithm is that it performs the box
 * transformation with far fewer flops than the naive approach
 * of transforming the eight vertices of the original box,
 * then computing upper and lower bounds of the transformed
 * points.  By using all of the inherent symmetry of the boxes,
 * this algorithms is about four times as fast as the naive
 * algorithm.
 *
 * Note that computing axis-aligned boxes in this way is fast,
 * but NOT recommended.  Whenever possible, the bounding box
 * should be computed from the transformed object, NOT the
 * transformed bounding box of the object.  The latter approach
 * can produce very loose bounding boxes, which can hurt the
 * performance of ray tracers and other algorithms that make
 * use of bounding boxes.
 *
 */ 

#include "GraphicsGems.h"

void Transform_Box( M, T, A, B )
Matrix3  M;  /* Transform matrix.             */
Vector3  T;  /* Translation vector.           */
Box3     A;  /* The original bounding box.    */
Box3    *B;  /* The transformed bounding box. */
    {
    float  a, b;
    float  Amin[3], Amax[3];
    float  Bmin[3], Bmax[3];
    int    i, j;

    /* Copy box A into a min array and a max array for easy reference. */

    Amin[0] = A.min.x;  Amax[0] = A.max.x;
    Amin[1] = A.min.y;  Amax[1] = A.max.y;
    Amin[2] = A.min.z;  Amax[2] = A.max.z;

    /* Account for the translation by beginning at T. */

    Bmin[0] = Bmax[0] = T.x;
    Bmin[1] = Bmax[1] = T.y;
    Bmin[2] = Bmax[2] = T.z;

    /* Now find the extreme points by considering the product */
    /* of the min and max with each component of M.           */
                     
    for( i = 0; i < 3; i++ )
    for( j = 0; j < 3; j++ )
        {
        a = M.element[i][j] * Amin[j];
        b = M.element[i][j] * Amax[j];
        if( a < b ) 
            { 
            Bmin[i] += a; 
            Bmax[i] += b;
            }
        else 
            { 
            Bmin[i] += b; 
            Bmax[i] += a;
            }
        }

    /* Copy the result into the new box. */

    B->min.x = Bmin[0];  B->max.x = Bmax[0];
    B->min.y = Bmin[1];  B->max.y = Bmax[1];
    B->min.z = Bmin[2];  B->max.z = Bmax[2];

    } 




