Structure AffineParts
See Also: Class Matrix3, Class Quat, Class Point, Class ScaleValue.
Description:
This structure and the associated functions provide a way to decompose an arbitrary Matrix3 into its translation, rotation, and scale components.
To use these APIs put the following statement in your source file:
#include "decomp.h"
For a full discussion of this decomposition see Graphics Gems IV - Polar Matrix Decomposition by Ken Shoemake. ISBN 0-12-336155-9.
T F R U K U'
T - translation matrix
F - either an identity matrix or negative identity matrix
R - rotation defined by Quat q.
U - rotates you into the coordinates system where the scaling or stretching is done
K - scaling matrix
U' - inverse of u.
Structure:
typedef struct {
Point3 t;
The translation components.
Quat q;
The essential rotation.
Quat u;
The stretch rotation. This is the axis system of the scaling application.
Point3 k;
The stretch factors. These are the scale factors for x, y and z.
float f;
Sign of the determinant.
} AffineParts;
Functions:
Prototype:
void decomp_affine(Matrix3 A, AffineParts *parts);
Remarks:
This will decompose a matrix into the translation, rotation and scale components and store the results in the AffineParts structure passed. This will return correct results for off axis scale. This is a fairly computationally intensive iterative solution operation.
Parameters:
Matrix3 A
The input matrix to decompose.
AffineParts *parts
The result. See above.
Sample Code:
Note: If you want to rebuild a Matrix3 from the decomposed parts you get back from decomp_affine()the important thing is the order the parts are combined.
Consider the following matrices constructed from the various affine parts:
ptm = position component (t)
rtm = "essential" rotation (q)
srtm = "stretch" rotation (u)
stm = scale component (k)
ftm = the flip tm -> ScaleMatrix(Point3(ap.f,ap.f,ap.f));
Here's the correct way of reassembling the decomposed matrix:
Matrix3 srtm, rtm, ptm, stm, ftm;
ptm.IdentityMatrix();
ptm.SetTrans(ap.t);
ap.q.MakeMatrix(rtm);
ap.u.MakeMatrix(srtm);
stm = ScaleMatrix(ap.k);
mat = Inverse(srtm) * stm * srtm * rtm * ftm * ptm;
Prototype:
void SpectralDecomp(Matrix3 m, Point3 &s, Quat& q);
Remarks:
This is another way to decompose a matrix into the scale and rotation parts (the position part can be retrieved from the bottom row of the matrix). This does not return correct results for off axis scale.
Parameters:
Matrix3 m
The input matrix to decompose.
Point3 &s
The scale from the matrix.
Quat& q
The rotation of the matrix.
Prototype:
void invert_affine(AffineParts *parts, AffineParts *inverse);
Remarks:
This is used to take the AffineParts and inverts them. This gives you the equivalent parts for the inverse matrix.
Parameters:
AffineParts *parts
The input AffineParts pointer.
AffineParts *inverse
The inverse of parts.