Contents
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
contains a static member variable to contain the zero vector. This static variable must be instantiated for each template instance of Vector
.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.
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.
There are three operations that can be done to a matrix: scaling, rotation, and translation.
[ 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.
[ 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.
X
and Y
give the amount to be translated. If X
and Y
are both set to 0, the translation matrix becomes the identity.
Matrix2
contains a static member variable to contain the identity matrix. This static variable must be instantiated for each template instance of Matrix2
.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.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
is a matrix of the form
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.