G3dMatrix.mesa
Copyright Ó 1984, 1988, 1992 by Xerox Corporation. All rights reserved.
Bloomenthal, July 15, 1992 6:27 pm PDT
Ken Fishkin, November 6, 1991 1:08 pm PST
Cf ``Principles of Interactive Computer Graphics,'' by Newman and Sproull.
Left-handed eyespace coordinate system (right, up, depth = into screen);
Right-handed world coordinate system.
Rotation correspondences:
vertical rotation: yaw <=> azimuth <=> longitude,
horizontal rotation: pitch <=> elevation <=> latitude,
longitudinal rotation: roll
Where feasible, procedures use the argument "out," if given; if not a new MatrixRep is allocated.
DIRECTORY G2dMatrix, G3dBasic;
Type Declarations
A three-dimensional affine transformation; an element is m[row][col]:
Matrix: TYPE ~ REF MatrixRep;
MatrixRep: TYPE ~ ARRAY [0..4) OF ARRAY [0..4) OF REAL;
MatrixSequence: TYPE ~ REF MatrixSequenceRep;
MatrixSequenceRep:
TYPE ~
RECORD [
length: CARDINAL ¬ 0,
element: SEQUENCE maxLength: CARDINAL OF Matrix
];
TransformOrder:
TYPE ~ {pre, post};
-- type of concatenation
Viewport:
TYPE ~
RECORD [
scale: Pair ¬ [1.0, 1.0],
aspectRecip: REAL ¬ 1.0,
translate: Pair ¬ [0.0, 0.0]];
Pair: TYPE ~ G3dBasic.Pair;
Triple: TYPE ~ G3dBasic.Triple;
Quad: TYPE ~ G3dBasic.Quad;
Ray: TYPE ~ G3dBasic.Ray;
Screen:
TYPE ~ G3dBasic.Screen;
origin: Triple ~ G3dBasic.origin;
Creation Operations
CopyMatrix:
PROC [matrix: Matrix, out: Matrix ¬
NIL]
RETURNS [Matrix];
Return a copy of the input matrix; use out if non-nil.
Identity:
PROC [out: Matrix ¬
NIL]
RETURNS [Matrix];
Return the identity matrix.
MakeFromTriad:
PROC [
v1, v2, v3: Triple,
p: Triple ¬ origin,
unitize: BOOL ¬ FALSE,
out: Matrix ¬ NIL]
RETURNS [Matrix];
Return transformation to coordinate system defined by three orthonormal axes.
v1, v2, v3 correspond to the x, y, and z axes.
MakeFromRows:
PROC [r0, r1, r2, r3: Quad, out: Matrix ¬
NIL]
RETURNS [Matrix];
Makes a matrix with the given rows.
MakeScale:
PROC [s: Triple, out: Matrix ¬
NIL]
RETURNS [Matrix];
Make a matrix which only scales by [s.x, s.y, s.z].
MakeTranslate:
PROC [p: Triple, out: Matrix ¬
NIL]
RETURNS [Matrix];
Make a matrix which only translates by [p.x, p.y, p.z].
MakeRotate:
PROC [axis: Triple, theta:
REAL, degrees:
BOOL ¬
TRUE, out: Matrix ¬
NIL]
RETURNS [Matrix];
Make matrix which rotates by theta about the given axis (which goes through the origin).
Rotation is right handed.
MakeRotateAbout:
PROC [
axis: Triple, theta: REAL, degrees: BOOL ¬ TRUE, base: Triple ¬ origin, out: Matrix ¬ NIL]
RETURNS [Matrix];
Make matrix that is a pure rotation matrix by theta about the line given by base, axis.
Rotation is right handed.
MakePerspective:
PROC [nInv, fInv, fov:
REAL, out: Matrix ¬
NIL]
RETURNS [Matrix];
Return the perspective transformation;
f (=1/fInv) is distance the far clipping plane is along +zaxis; fInverse=0 for no far clipping.
field-of-view (fov) is in degrees; it is the full field of view.
nInv=fInv=0 or fov=0 yields an orthographic projection.
nInv = 1/zNear, fInv = 1/zFar.
Eye point is assumed at [0, 0, 0], viewing along +z axis.
HasPerspective:
PROC [mat: Matrix]
RETURNS [
BOOL];
Return TRUE iff the matrix has a perspective element.
MakeVectorTransform:
PROC [pointTransform: Matrix, out: Matrix ¬
NIL]
RETURNS [Matrix];
Given a point tranform, create the tranform for transforming vectors; i.e., create a matrix
for normals/direction vectors (homogeneous coordinate = 0). Use out if non-NIL.
Transformation Operations
TransformH:
PROC [p: Triple, mat: Matrix]
RETURNS [Quad];
Postmultiply by transformation matrix, yielding a homogeneous point.
The following four transformation procedures test the transformation matrix for perspective (i.e.,
the matrix has perspective iff the last column is not [0, 0, 0, 1]. If a perspective element exists,
the return coordinates are first divided by w.
Transform:
PROC [p: Triple, mat: Matrix]
RETURNS [Triple];
Postmultiply by transformation matrix, yielding non-homogenous point.
TransformD:
PROC [p: Triple, mat: Matrix]
RETURNS [Pair];
Postmultiply by transformation matrix, yielding [x, y] pair.
This is useful when transforming from object to screen space, in which z-screen is not used.
TransformPair:
PROC [p: Pair, mat: Matrix]
RETURNS [Triple];
Postmultiply a point in the xy plane by a transformation matrix.
This is useful when transforming a planar contour into object space.
TransformPairD:
PROC [p: Pair, mat: Matrix]
RETURNS [Pair];
Postmultiply a point in the xy plane by mat, yielding [x, y] pair.
This is useful when transforming a planar contour into screen space.
TransformQuad:
PROC [q: Quad, mat: Matrix]
RETURNS [Quad];
Postmultiply a four element vector by mat, yielding a four element vector.
If no differential scaling exists within the transformation matrix, TransformVec may be used.
Otherwise, use TransformVecDiffS.
TransformVec:
PROC [vec: Triple, mat: Matrix]
RETURNS [Triple];
Postmultiply a vector by a transformation matrix, without the translation components.
TransformVecDiffS:
PROC [vec: Triple, mat: Matrix]
RETURNS [Triple];
Postmultiply a vector by transform of cofactors of mat, in case mat has differential scaling
(ie., the x, y, and z scale factors are not equal).
TransformPlane:
PROC [plane: Quad, mat: Matrix, matInverse: Matrix ¬
NIL]
RETURNS [Quad];
Transform the plane by mat. This amounts to a premultiplication by matInverse.
If matInverse is not given as an argument, then the adjoint of mat must be computed.
PremultiplyPlaneByMatrix:
PROC [plane: Quad, m: Matrix]
RETURNS [Quad];
Return a plane premultiplied by a matrix.
TransformByViewport:
PROC [p: Pair, vp: Viewport]
RETURNS [Pair];
Transform the two dimensional point by the viewport.
Concatenation Operations
The next 3 procs post-multiply the matrix, thus transforming in the reference coordinate space.
Scale:
PROC [in: Matrix, s:
REAL, out: Matrix ¬
NIL]
RETURNS [Matrix];
Concatenate a scaling by s.
DiffScale:
PROC [in: Matrix, s: Triple, out: Matrix ¬
NIL]
RETURNS [Matrix];
Differential scaling: concatenate a scaling by [s.x, s.y, s.z].
Rotate:
PROC [in: Matrix, axis: Triple, theta:
REAL,
degrees: BOOL ¬ TRUE, base: Triple ¬ origin, out: Matrix ¬ NIL] RETURNS [Matrix];
Concatenate rotation of theta about the line given by base and axis.
Translate:
PROC [in: Matrix, p: Triple, out: Matrix ¬
NIL]
RETURNS [Matrix];
Concatenate a translation by [p.x, p.y, p.z].
The next 3 procs pre-multiply the matrix, thus transforming in the local coordinate space.
LocalScale:
PROC [in: Matrix, s:
REAL, out: Matrix ¬
NIL]
RETURNS [Matrix];
Concatenate a local scaling by s.
LocalDiffScale:
PROC [in: Matrix, s: Triple, out: Matrix ¬
NIL]
RETURNS [Matrix];
Differential scaling: concatenate a local scaling by [s.x, s.y, s.z].
LocalRotate:
PROC [in: Matrix, axis: Triple, theta:
REAL,
degrees: BOOL ¬ TRUE, base: Triple ¬ origin, out: Matrix ¬ NIL] RETURNS [Matrix];
Concatenate local rotation of theta radians about line given by base, axis.
LocalTranslate:
PROC [in: Matrix, p: Triple, out: Matrix ¬
NIL]
RETURNS [Matrix];
Concatenate a local translation.
Mathematical Operations
Mul:
PROC [left, rite: Matrix, out: Matrix ¬
NIL]
RETURNS [Matrix];
Returns matrix product left right;
Examples: a ← Multiply[a, b, a]; b ← Multiply[a, b, b]; c ← Multiply[a, b].
Cat
:
PROC
[m1, m2: Matrix, m3, m4, m5, m6, out: Matrix ¬
NIL]
RETURNS [Matrix];
Return concatenation of input matrices.
Invert:
PROC
[in: Matrix, out: Matrix ¬
NIL]
RETURNS [Matrix];
Can raise ERROR: singular.
Adjoint:
PROC [in: Matrix, out: Matrix ¬
NIL]
RETURNS [Matrix];
Return the adjoint of in.
Cofactors:
PROC [in: Matrix, out: Matrix ¬
NIL]
RETURNS [Matrix];
Return the cofactors of in.
Determinant:
PROC [mat: Matrix]
RETURNS [
REAL];
Return the determinant of mat.
Transpose:
PROC [in: Matrix, out: Matrix ¬
NIL]
RETURNS [Matrix];
Return the transpose of in.
ExtractRotate:
PROC [m: Matrix]
RETURNS [Triple];
Decompose a 3x3 rotation matrix m (within a 4x4 matrix) into m = [rotx(a)]*[roty(b)]*[rotz(c)].
Correct for right-handed coordinate system and right-handed rotations.
cf: Ned Greene's Extracting Transformation Parameters from Transformation Matrices.
return [a, b, c];
InTermsOf:
PROC [A,
B: Matrix, out: Matrix ¬
NIL]
RETURNS [Matrix];
Return B in terms of A.
It is useful to be able to express one coordinate system in terms of another. Consider this
example. Given an earth coordinate system and a moon coordinate system, both expressed in
world coordinates, then displaying the moon rotating about the earth may be expressed as:
MoonInTermsOfEarth ← InTermsOf[earth, moon];
FOREVER DO:
MoonInTermsOfEarth ← YRotate[MoonInTermsOfEarth, theta];
moon ← Mul[earth, MoonInTermsOfEarth];
Draw[moon]
ENDLOOP;
Sequence Operations
CopyMatrixSequence:
PROC [matrices: MatrixSequence]
RETURNS [MatrixSequence];
Return a copy of the input sequence of matrices.
AddToMatrixSequence:
PROC [matrices: MatrixSequence, matrix: Matrix]
RETURNS [MatrixSequence];
Add matrix to the sequence.
LengthenMatrixSequence:
PROC [matrices: MatrixSequence, amount:
REAL ¬ 1.3]
RETURNS [MatrixSequence];
Return a copy of the input sequence whose maxLength is amount*input.maxLength.