Matrix2.mesa
Copyright © 1984, Xerox Corporation. All rights reserved.
Frank Crow, July 31, 1983 3:28 pm
Michael Plass, February 7, 1984 10:44:55 am PST
Doug Wyatt, August 8, 1984 10:40:03 am PDT
Homogeneous transformation matrices for two dimensions.
DIRECTORY
Vector2 USING [VEC];
Matrix2: CEDAR DEFINITIONS
~ BEGIN
Types
Ref: TYPE ~ REF Rep;
Rep:
TYPE ~
RECORD[a, b, c, d, e, f:
REAL];
Represents the following 3 by 3 matrix:
a d 0
b e 0
c f 1
VEC: TYPE ~ Vector2.VEC;
Converting between Ref and Rep.
Contents: PROC[m: Ref] RETURNS[Rep] ~ INLINE { RETURN[m^] };
FromRec: PROC[Rep] RETURNS[Ref];
Creating new transformation matrices.
Create:
PROC[a, b, c, d, e, f:
REAL]
RETURNS[Ref];
Create a new transformation.
Copy:
PROC[m: Ref]
RETURNS[Ref];
Make a copy of m.
Translate:
PROC[x, y:
REAL]
RETURNS[Ref];
Equivalent to Create[1, 0, x, 0, 1, y].
Scale:
PROC[s:
REAL]
RETURNS[Ref];
Equivalent to Create[s, 0, 0, 0, s, 0].
Scale2:
PROC[sx, sy:
REAL]
RETURNS[Ref];
Equivalent to Create[sx, 0, 0, 0, sy, 0].
Rotate:
PROC[a:
REAL]
RETURNS[Ref];
Equivalent to Create[cos(a), -sin(a), 0, sin(a), cos(a), 0]. Angle a is in degrees.
Concat:
PROC[m, n: Ref]
RETURNS[Ref];
Returns the matrix product mn.
Invert:
PROC[m: Ref]
RETURNS[Ref];
Returns m's inverse.
Altering an existing matrix.
PreMultiply:
PROC[m, pre: Ref];
Equivalent to m^ ← Concat[pre, m]^.
PreScale:
PROC[m: Ref, s:
REAL];
Equivalent to PreMultiply[m, Scale[s]].
PreScale2:
PROC[m: Ref, sx, sy:
REAL];
Equivalent to PreMultiply[m, Scale2[sx, sy]].
PreRotate:
PROC[m: Ref, a:
REAL];
Equivalent to PreMultiply[m, Rotate[a]].
PreTranslate:
PROC[m: Ref, x, y:
REAL];
Equivalent to PreMultiply[m, Translate[x, y]].
PostMultiply:
PROC[m, post: Ref];
Equivalent to m^ ← Concat[m, post]^.
PostScale:
PROC[m: Ref, s:
REAL];
Equivalent to PostMultiply[m, Scale[s]].
PostScale2:
PROC[m: Ref, sx, sy:
REAL];
Equivalent to PostMultiply[m, Scale2[sx, sy]].
PostRotate:
PROC[m: Ref, a:
REAL];
Equivalent to PostMultiply[m, Rotate[a]].
PostTranslate:
PROC[m: Ref, x, y:
REAL];
Equivalent to PostMultiply[m, Translate[x, y]].
Applying a transformation.
Transform:
PROC[m: Ref, p:
VEC]
RETURNS[
VEC];
"Point" transformation: [m.a*p.x + m.b*p.y + m.c, m.d*p.x + m.e*p.y + m.f].
TransformVec:
PROC[m: Ref, p:
VEC]
RETURNS[
VEC];
"Vector" transformation: [m.a*p.x + m.b*p.y, m.d*p.x + m.e*p.y].
InverseTransform:
PROC[m: Ref, p:
VEC]
RETURNS[
VEC];
Equivalent to Invert[m].Transform[p].
InverseTransformVec:
PROC[m: Ref, p:
VEC]
RETURNS[
VEC];
Equivalent to Invert[m].TransformVec[p].
Testing for transformations that are close to each other.
CloseEnough:
PROC[s, t: Ref, rangeSize:
REAL ← 2000.0]
RETURNS[
BOOLEAN];
Returns TRUE if for all points p such that Transform[p, s] is in [0, 0, rangeSize, rangeSize], Transform[p, s] and Transform[p, t] differ by at most 1/4 pixel.
CloseToTranslation:
PROC[s, t: Ref, rangeSize:
REAL ← 2000.0]
RETURNS[
BOOLEAN];
Returns TRUE if for all points p such that TransformVec[p, s] is in [0, 0, rangeSize, rangeSize], TransformVec[p, s] and TransformVec[p, t] differ by at most 1/4 pixel.
These always return rectangles, thus "hard" transforms will cause a bounding box to be returned
Rectangle: TYPE ~ RECORD[x, y, w, h: REAL];
IntRectangle: TYPE ~ RECORD[x, y, w, h: INTEGER];
TransformRectangle: PROC[m: Ref, rect: Rectangle] RETURNS[Rectangle];
TransformIntRectangle: PROC[m: Ref, rect: Rectangle] RETURNS[IntRectangle];
Computing singular values
SingularValues:
PROC[m: Ref]
RETURNS[
VEC];
Returns the singular values of the non-translation portion of the transform. These are the square roots of the eigenvalues of the symmetric matrix MMT, where M is the non-translation portion. The x component is the larger of the two. These correspond to the maximum and minimum magnitudes that the image of a unit vector can achive.
END.