Math

Math-related code is stored in the /lib/math/ directory.

Contents

Math Namespace

Xrb::Math contains mathematical structures and functions for the many systems which require the use of complex formulae.

Note: XuqRijBuh uses degrees instead of radians througout. Although radians are more natural in a pure mathematical sense, degrees have been chosen for ease of human use. Radians are based on the irrational value of pi, so they aren't particularly user friendly when it comes to printing and reading angles in decimal notation. Thus, all trigonometric functions which accept angles use degrees unless otherwise noted.

Vector

Xrb::Vector is a templatized vector construct (with dimension and component type being the template arguments), geared towards function inlining and speed. The intent is that all the syntactical suger-coating will melt away when compiled, leaving instructions that look like hand-written array code.

Static Zero Vector

Because it is so commonly used, Vector contains a static member variable to contain the zero vector. This static variable must be instantiated for each template instance of Vector .

FloatVector2

Since Vector is templatized so that the dimension and component type can be specified on an as-needed basis, XuqRijBuh provides an instance of Vector<Float,2> ( see Xrb::FloatVector2 ) which is used for all the Xrb::Engine2 computation as well as for OpenGL rendering.

Matrix2

Xrb::Matrix2 is a templatized matrix class which performs pseudo-3-dimensional transformations. What this means is that the matrix is of form:

    [ A B X ]
    [ C D Y ]
    [ 0 0 1 ]

Only A , B , X , C , D , and Y are stored. This form of matrix is closed under multiplication -- any two matrices of this form, when multiplied together, will result in another matrix of this form. The identity matrix is also included in the set of possible matrices.

Matrix2 provides operator overloads for interaction with Vector types of dimension 2.

The reason the matrix is designed like this, as opposed to a natural 2 by 2 matrix, is so translations can be performed on vectors by matrix multiplication. In order for this form of matrix to actually perform translation on a vector (and for the vector's dimension to even match up with the matrix's), the vector must have the value 1 in its 3rd component.

    [ A B X ]   [ P ]   [ A*P + B*Q + X ]
    [ C D Y ] * [ Q ] = [ C*P + D*Q + Y ]
    [ 0 0 1 ]   [ 1 ]   [       1       ]

There are three operations that can be done to a matrix: scaling, rotation, and translation.

Matrix2 Scaling

Scaling is done by multiplying on the left using a matrix of this form:

    [ R 0 0 ]
    [ 0 S 0 ]
    [ 0 0 1 ]

R gives the scaling factor in the X dimension, while S gives the scaling factor in the Y dimension. If R and S are both 1, the matrix is the identity.

Matrix2 Rotation

Rotation (counterclockwise) is done by multiplying on the left using a matrix of this form:

    [ cos W  -sin W   0 ]
    [ sin W   cos W   0 ]
    [   0       0     1 ]

W gives the angle, in degrees, to rotate in a counterclockwise direction. If W is 0, then the rotation matrix becomes the identity.

Matrix2 Translation

Translation is done by multiplying on the left using a matrix of this form:

    [ 1 0 X ]
    [ 0 1 Y ]
    [ 0 0 1 ]

X and Y give the amount to be translated. If X and Y are both set to 0, the translation matrix becomes the identity.

Static Identity Matrix

Because it is so commonly used, Matrix2 contains a static member variable to contain the identity matrix. This static variable must be instantiated for each template instance of Matrix2 .

FloatMatrix2

Since Matrix2 is templatized, so that the component type can be specified on an as-needed basis, XuqRijBuh provides an instance of Matrix2<Float> ( see Xrb::Float ) which is used for all the Xrb::Engine2 computation as well as for OpenGL rendering.

Transform2

The difference between Xrb::Matrix2 and Xrb::Transform2 is that Matrix2 stores the composition of potentially limitless transformations in its native matrix form, while Transform2 stores separately the components of transformation (scaling, rotation, and translation) and only produces a native-form matrix when necessary. This is done so that specific components of transformations can be changed without having to do expensive matrix inversions. The space of possible transformations using this form is more limited than that of Matrix2 , but are sufficient for the systems that use them.

A Transform2 is manipulated using its component transformations, and then at the latest necessary time, a Matrix2 is composited using those values and then cached for likely repeated use. There are actually two cached values, one being a composition of scaling and rotation, the other being a composition of the first cache Matrix2 and translation.

A Transform2 is composited in one of the two following manners.

    [ a b x ]   [ 1 0 X ]   [ cos W  -sin W   0 ]   [ R 0 0 ]
    [ c d y ] = [ 0 1 Y ] * [ sin W   cos W   0 ] * [ 0 S 0 ]
    [ 0 0 1 ]   [ 0 0 1 ]   [   0       0     1 ]   [ 0 0 1 ]

    [ a b x ]   [ cos W  -sin W   0 ]   [ R 0 0 ]   [ 1 0 X ]   
    [ c d y ] = [ sin W   cos W   0 ] * [ 0 S 0 ] * [ 0 1 Y ]
    [ 0 0 1 ]   [   0       0     1 ]   [ 0 0 1 ]   [ 0 0 1 ]

In the first mode, scaling is applied first, then rotation, then translation (remember, matrices are multiplied on the left). This sort of component-wise transformation is adapted for physical objects moving and rotating in space (and potentially scaling as well). The scaling and rotation happens about the object's center, whereas the translation is relative to world coordinates.

The second mode translates coordinates first, then scales, and finally rotates. This is used for transforming world coordinates into view coordinates ( see Xrb::Engine2::WorldView ).

The Xrb::Transform2::m_post_translate property is what controls wether or not the translation is done before or after. A value of true indicates that the translation will be done after scaling and rotation (as in the first mode), while a value of false indicates the translation will be done first (as in the second mode). Xrb::Engine2::Object uses a Transform2 with a m_post_translation value of true ( see Xrb::Engine2::Object::m_transform ), while Xrb::Engine2::WorldView uses a Transform2 with a m_post_translation value of false ( see Xrb::Engine2::WorldView::m_transform ).

The method that is used to calculate and return the composite Matrix2 is Xrb::Transform2::Transformation .

SimpleTransform2

Xrb::SimpleTransform2 performs a function similar to Xrb::Transform2 except that there is no rotation involved. A SimpleTransform2 is a matrix of the form

    [ R 0 X ]
    [ 0 S Y ]
    [ 0 0 1 ]

R and S provide scaling factors like those mentioned in Matrix2, while X and Y provide translation vector components.

A subtle difference is that there is no m_post_translate property. SimpleTransform2 provides operator overloads for SimpleTransform2 / Vector multiplication, with the effective transformation component order being scaling then translation.

Matrices of the form that SimpleTransform2 takes are closed under multiplication, thus matrix/matrix multiplication operators are provided (unlike in Transform2 ). Multiplication between Matrix2 and SimpleTransform2 is also valid, resulting in a Matrix2 type matrix. Thus, operators are provided to accomplish this type of multiplication.

SimpleTransform2 is mainly used in the GUI system, as its scaling and translating abilities are very well suited for transforming screen coordinates.


Hosted by SourceForge.net Logo -- Generated on Fri Aug 21 21:46:38 2009 for XuqRijBuh by doxygen 1.5.8