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;
G3dMatrix: CEDAR DEFINITIONS
~ BEGIN
singular: ERROR;
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.
Scratch Matrix Operations
ObtainMatrix: PROC RETURNS [Matrix];
Obain a matrix from the scratch pool; using the pool mimizes storage allocation.
ReleaseMatrix: PROC [matrix: Matrix];
Return the matrix to the scratch pool.
Point Transformation and Visibility Testing
GetScreen: PROC [point: Triple, view: Matrix, hasPerspective: BOOL, viewport: Viewport]
RETURNS [Screen];
Return a screen position and clip information (does not alter screen.fwdFacing).
Three-dimensional Information Derived from the Screen
TripleFromScreen: PROC [p: Pair, view: Matrix, viewInverse: Matrix ¬ NIL]
RETURNS [Triple];
Return a point that would transform to p.
TripleFromScreenAndPlane: PROC [
p: Pair,
plane: Quad,
view: Matrix]
RETURNS [Triple];
Return a point on the plane that would transform to p.
LineFromScreen: PROC [p: Pair, view: Matrix, viewInverse: Matrix ¬ NIL] RETURNS [Ray];
Return the line through the eyepoint that would intersect the display at p.
END.