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 full polar decomposition according to Duff and Shoemaker includes a second rotation U that conjugates the scaling matrix, i.e., M=TRUSU'. We assume that U is the identity, which amounts to assuming that M has no shearing component. This appears to a fairly safe assumption, but be aware that the factorization will be wrong if you have a shearing component.
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 Pn
for 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.
Constructor and Description |
---|
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) |
Modifier and Type | Method and Description |
---|---|
void |
assignFrom(FactoredMatrix fm) |
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 .
|
String |
toString() |
void |
update()
Updates the current state of the transformation.
|
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, power, setColumn, setEntry, setRow, subtract, sum, times, times, transformVector, transpose, writeToArray
public FactoredMatrix(int metric, double[] m)
metric
- See Pn
.m
- public FactoredMatrix(Matrix m, int metric)
metric
- the metricm
- the matrixc to copypublic FactoredMatrix(FactoredMatrix fm)
fm
- the FactoredMatrix to copypublic FactoredMatrix(int metric)
public FactoredMatrix(double[] m)
public FactoredMatrix()
public FactoredMatrix(DoubleArray da)
public FactoredMatrix(Transformation trafo)
public double[] getArray()
public void assignFrom(FactoredMatrix fm)
public boolean getIsReflection()
true
if the matrix has negative determinant.public void setIsReflection(boolean aVal)
aVal
- public boolean getUseCenter()
true
if the transform has been set to respect a
separate center for its rotation and stretch factors.#setCenter(double[]), and introductory remarks on this class.
public boolean getIsSpecial()
Matrix.TOLERANCE
.public void setCenter(double[] aVec)
setCenter(double[], boolean)
with the second parameter
false
.aVec
- public void setCenter(double[] aVec, boolean keepMatrix)
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:aVec
- the position of the center (as a 3-vector or homogeneous
4-vector)keepMatrix
- whether to preseve the value of the matrixpublic double[] getCenter()
public void setTranslation(double tx, double ty, double tz)
tx
- ty
- tz
- public void setTranslation(double[] aTransV)
aTransV
- public double[] getTranslation()
public void setRotationAxis(double ax, double ay, double az)
ax
- ay
- az
- public void setRotationAxis(double[] axis)
axis
- public void setRotationAngle(double angle)
angle
- The angle measured in radians.public void setRotation(double angle, double[] axis)
angle
- axis
- public void setRotation(double angle, double ax, double ay, double az)
angle
- axis
- public void setRotation(Quaternion aQ)
aQ
- public double[] getRotationAxis()
public double getRotationAngle()
public Quaternion getRotationQuaternion()
public void setStretch(double stretch)
stretch
- public void setStretch(double sx, double sy, double sz)
sx
- sy
- sz
- public void setStretch(double[] stretchV)
sV
- public double[] getStretch()
public void update()
public FactoredMatrix getInverseFactored()
public int getMetric()
public boolean isMatrixHasChanged()
public Matrix getRotation()