de.jreality.math
Class FactoredMatrix

java.lang.Object
  extended by de.jreality.math.Matrix
      extended by de.jreality.math.FactoredMatrix
All Implemented Interfaces:
Serializable

public class FactoredMatrix
extends Matrix

The FactoredMatrix class is a subclass of Matrix supporting a canonical factorization of the matrix into simpler factors. The class provides a variety of methods for setting and getting the transformation. One instance can handle a series of transformations, based on the so-called polar decomposition. See Duff and Shoemaker paper. To be exact, the matrix M is factored as the matrix product M=T*R*S. Note that matrices act on column vectors which stand to the right of the matrix. S is a "stretch" or "scale" matrix -- a diagonal matrix. R is an arbitrary rotation of Euclidean 3-space, and T is a translation.

NOTE: the current implementation omits part of the factorization described in the above paper. There is only one scale matrix.

Users may set the matrix directly, then the factors will be computed and are accessible. Or, the user can set one or more of the factors, and the corresponding matrix is calculated and made available. The update mechanism either decomposes or composes the matrix depending on the type of the most recent "setter" called by the user.

This class is designed to work with any of the classical homogeneous geometries: euclidean, elliptic, or hyperbolic. The variable {\it metric} controls which geometry is active. [Note: Probably should be constructor parameter and not allowed to change].

By default the origin (0,0,0,1) is the fixed point of the scale and rotation part of the transformation. It is however possible to specity another center (see setCenter(double[], boolean). The resulting matrix is then T*C*R*S*IC where C is the translation taking the origin to C, and IC is its inverse. The fixed point for the rotation and stretch is then center .

It is also possible to work with reflections, since any reflection can be factored as T*R*S*G where G is the diagonal matrix {-1,-1,-1,1} (that is, reflection around the origin). A matrix is considered a reflection if its determinant is negative.

The matrix in general belongs to the matrix group GL(4,R). It is also possible to query the matrix to find out if it belongs to the subgroup SL(4,R) of matrices with determinant +/- 1. See getIsSpecial().

It is also possible to factor isometries of non-euclidean space. In this case use a constructor that allows specifying the metric. See Pn for a more complete description of the non-euclidean isometries. Then the above remarks should be extended whereever they refer to euclidean metric.

See also Pnfor a collection of static methods useful for generating 4x4 matrices for specific purposes.

Warning! The matrix is stored as type double[16], not double[4][4], due to efficiency concerns arising from the way Java implements multi-dimensional arrays.

Warning Angles are measured in radians.

Author:
Charles Gunn
See Also:
Serialized Form

Field Summary
 
Fields inherited from class de.jreality.math.Matrix
TOLERANCE
 
Constructor Summary
FactoredMatrix()
           
FactoredMatrix(double[] m)
           
FactoredMatrix(DoubleArray da)
           
FactoredMatrix(FactoredMatrix fm)
          copy constructor
FactoredMatrix(int metric)
           
FactoredMatrix(int metric, double[] m)
          Generate a new transform with given metric and matrix If m is null, use identity matrix.
FactoredMatrix(Matrix m, int metric)
          copy constructor
FactoredMatrix(Transformation trafo)
           
 
Method Summary
 double[] getArray()
           
 double[] getCenter()
           
 FactoredMatrix getInverseFactored()
           
 boolean getIsReflection()
           
 boolean getIsSpecial()
          Is the determinant 1 or -1? (Or within Matrix.TOLERANCE.
 int getMetric()
           
 Matrix getRotation()
           
 double getRotationAngle()
           
 double[] getRotationAxis()
           
 Quaternion getRotationQuaternion()
          Get the rotation specified as a unit quaternion
 double[] getStretch()
          Return the stretch vector for this transformation.
 double[] getTranslation()
          Get the translation vector for this transform
 boolean getUseCenter()
           
 boolean isMatrixHasChanged()
           
 void setCenter(double[] aVec)
          Invoke setCenter(double[], boolean)with the second parameter false.
 void setCenter(double[] aVec, boolean keepMatrix)
          Set the center of the transformation.
 void setIsReflection(boolean aVal)
          Set the matrix to be a reflection based on the value of aval .
 void setRotation(double angle, double[] axis)
          Set the angle and the axis simulataneously.
 void setRotation(double angle, double ax, double ay, double az)
          Set the angle and the axis (= (ax, ay, az)) simulataneously.
 void setRotation(Quaternion aQ)
          Set the rotation for this transformation using the unit quaternion aQ .
 void setRotationAngle(double angle)
          Set the rotation angle for this transformation.
 void setRotationAxis(double[] axis)
          Set the rotation axis of this transformation using the 3-vector axis .
 void setRotationAxis(double ax, double ay, double az)
          Set the rotation axis of this transformation using the three components (ax, ay, ax) .
 void setStretch(double stretch)
          Set the stretch vector associated to this transform using the factor stretch for all three dimensions.
 void setStretch(double[] stretchV)
          Set the stretch using the 3-vector stretchV .
 void setStretch(double sx, double sy, double sz)
          Set the stretch factor using the the vector (sx, sy, sz)
 void setTranslation(double[] aTransV)
          Set the translation part of the transform with the vector aTransV .
 void setTranslation(double tx, double ty, double tz)
          Set the translation factor with the three components tx, ty, tz .
 void update()
          Updates the current state of the transformation.
 
Methods inherited from class de.jreality.math.Matrix
add, assignFrom, assignFrom, assignFrom, assignFrom, assignFrom, assignIdentity, assignTo, assignTo, assignTo, assignTo, conjugate, conjugateBy, containsNanOrInfinite, equals, getColumn, getDeterminant, getEntry, getInverse, getRow, getTrace, getTranspose, invert, multiplyOnLeft, multiplyOnLeft, multiplyOnRight, multiplyOnRight, multiplyVector, setColumn, setEntry, setRow, subtract, sum, times, times, toString, transformVector, transpose, writeToArray
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

FactoredMatrix

public FactoredMatrix(int metric,
                      double[] m)
Generate a new transform with given metric and matrix If m is null, use identity matrix.

Parameters:
metric - See Pn.
m -

FactoredMatrix

public FactoredMatrix(Matrix m,
                      int metric)
copy constructor

Parameters:
metric - the metric
m - the matrixc to copy

FactoredMatrix

public FactoredMatrix(FactoredMatrix fm)
copy constructor

Parameters:
fm - the FactoredMatrix to copy

FactoredMatrix

public FactoredMatrix(int metric)

FactoredMatrix

public FactoredMatrix(double[] m)

FactoredMatrix

public FactoredMatrix()

FactoredMatrix

public FactoredMatrix(DoubleArray da)

FactoredMatrix

public FactoredMatrix(Transformation trafo)
Method Detail

getArray

public double[] getArray()
Overrides:
getArray in class Matrix
Returns:
reference to the current matrix

getIsReflection

public boolean getIsReflection()
Returns:
true if the matrix has negative determinant.

setIsReflection

public void setIsReflection(boolean aVal)
Set the matrix to be a reflection based on the value of aval . (This is a somewhat questionable method.-cg)

Parameters:
aVal -

getUseCenter

public boolean getUseCenter()
Returns:
true if the transform has been set to respect a separate center for its rotation and stretch factors.
See Also:
#setCenter(double[]), and introductory remarks on this class.

getIsSpecial

public boolean getIsSpecial()
Is the determinant 1 or -1? (Or within Matrix.TOLERANCE.

Returns:

setCenter

public void setCenter(double[] aVec)
Invoke setCenter(double[], boolean)with the second parameter false.

Parameters:
aVec -

setCenter

public void setCenter(double[] aVec,
                      boolean keepMatrix)
Set the center of the transformation. See the class description above for a description. If keepMatrix is true, then the value of the transformation will be left unchanged; the translation factor will be adjusted to achieve this effect. If it is not, then the other factors will be left unchanged and the resulting matrix will take on a new value. Side effect:

Parameters:
aVec - the position of the center (as a 3-vector or homogeneous 4-vector)
keepMatrix - whether to preseve the value of the matrix

getCenter

public double[] getCenter()
Returns:
the center vector (as homogeneous 4-vector).

setTranslation

public void setTranslation(double tx,
                           double ty,
                           double tz)
Set the translation factor with the three components tx, ty, tz .

Parameters:
tx -
ty -
tz -

setTranslation

public void setTranslation(double[] aTransV)
Set the translation part of the transform with the vector aTransV . The length of aTransV must be less than or equal to 4.

Parameters:
aTransV -

getTranslation

public double[] getTranslation()
Get the translation vector for this transform

Returns:
double[4]

setRotationAxis

public void setRotationAxis(double ax,
                            double ay,
                            double az)
Set the rotation axis of this transformation using the three components (ax, ay, ax) .

Parameters:
ax -
ay -
az -

setRotationAxis

public void setRotationAxis(double[] axis)
Set the rotation axis of this transformation using the 3-vector axis .

Parameters:
axis -

setRotationAngle

public void setRotationAngle(double angle)
Set the rotation angle for this transformation.

Parameters:
angle - The angle measured in radians.

setRotation

public void setRotation(double angle,
                        double[] axis)
Set the angle and the axis simulataneously.

Parameters:
angle -
axis -

setRotation

public void setRotation(double angle,
                        double ax,
                        double ay,
                        double az)
Set the angle and the axis (= (ax, ay, az)) simulataneously.

Parameters:
angle -
axis -

setRotation

public void setRotation(Quaternion aQ)
Set the rotation for this transformation using the unit quaternion aQ .

Parameters:
aQ -

getRotationAxis

public double[] getRotationAxis()
Returns:
double[3] the rotation axis.

getRotationAngle

public double getRotationAngle()
Returns:
the rotation angle (in radians)

getRotationQuaternion

public Quaternion getRotationQuaternion()
Get the rotation specified as a unit quaternion

Returns:

setStretch

public void setStretch(double stretch)
Set the stretch vector associated to this transform using the factor stretch for all three dimensions.

Parameters:
stretch -

setStretch

public void setStretch(double sx,
                       double sy,
                       double sz)
Set the stretch factor using the the vector (sx, sy, sz)

Parameters:
sx -
sy -
sz -

setStretch

public void setStretch(double[] stretchV)
Set the stretch using the 3-vector stretchV .

Parameters:
sV -

getStretch

public double[] getStretch()
Return the stretch vector for this transformation. Default: (1,1,1).

Returns:
double[3]

update

public void update()
Updates the current state of the transformation. If a factor was most recently changed, then the matrix is updated. Otherwise, if the matrix has changed since the last invocation, the factorization is updated.


getInverseFactored

public FactoredMatrix getInverseFactored()

getMetric

public int getMetric()

isMatrixHasChanged

public boolean isMatrixHasChanged()

getRotation

public Matrix getRotation()