ImagerTransformation.mesa
Copyright Ó 1985, 1986, 1991 by Xerox Corporation. All rights reserved.
Frank Crow, July 31, 1983 3:28 pm
Michael Plass, August 17, 1991 0:20 am PDT
Doug Wyatt, March 26, 1985 3:37:51 pm PST
Creating transformations
Transformation: TYPE ~ REF TransformationRep;
TransformationRep:
TYPE ~
RECORD [
a, b, c, d, e, f: REAL,
tx, ty: INTEGER ¬ 0,
integerTrans: BOOL ¬ FALSE, -- (tx=c AND ty=f)
form: NAT ¬ 0 -- identifies special forms of [a, b, d, e]
];
A two-dimensional affine transformation, using an homogeneous coordinate system. Represents the 3 by 3 matrix:
|| a d 0 ||
|| b e 0 ||
|| c f 1 ||
The values of a, b, c, d, e, f are always correct. Other fields are performance accelerators.
Points are represented by the row matrix
[ x y 1 ]
and this gets multiplied on the left by a transformation matrix to yield the transformed row vector
[ ax+by+c dx+ey+f 1 ].
When SF vectors are mixed with transformations, we use the correspondence s~x and f~y (this may initially be counterintuitive for people accustomed to frame buffers).
Create:
PROC [a, b, c, d, e, f:
REAL]
RETURNS [Transformation];
Creates a new transformation:
|| a d 0 ||
|| b e 0 ||
|| c f 1 ||
Destroy:
PROC [m: Transformation];
Asserts the Transformation is available for re-use
Copy:
PROC [m: Transformation]
RETURNS [Transformation];
Returns a copy of m.
Scale:
PROC [s:
REAL]
RETURNS [Transformation];
Creates a transformation which scales by s:
|| s 0 0 ||
|| 0 s 0 ||
|| 0 0 1 ||
Scale2:
PROC [s:
VEC]
RETURNS [Transformation];
Creates a transformation which scales x by s.x, y by s.y:
|| s.x 0 0 ||
|| 0 s.y 0 ||
|| 0 0 1 ||
Rotate:
PROC [r:
REAL]
RETURNS [Transformation];
Creates a transformation which rotates counterclockwise by r degrees:
|| cos r sin r 0 ||
|| -sin r cos r 0 ||
|| 0 0 1 ||
Translate:
PROC [t:
VEC]
RETURNS [Transformation];
Creates a transformation which translates by t.x, t.y:
|| 1 0 0 ||
|| 0 1 0 ||
|| t.x t.y 1 ||
Direction: TYPE ~ {left, right, up, down};
ScanMode:
TYPE ~
MACHINE
DEPENDENT
RECORD [slow, fast: Direction];
SFToXY:
PROC [scanMode: ScanMode, sSize, fSize:
INT]
RETURNS [Transformation];
The result transforms [s, f] to [x, y], given the source (e.g., pixel array) scan mode.
XYToSF:
PROC [scanMode: ScanMode, sSize, fSize:
INT]
RETURNS [Transformation];
The result transforms [x, y] to [s, f], given the destination (e.g., display) scan mode.
Combining transformations
Concat:
PROC [m, n: Transformation]
RETURNS [Transformation];
Returns the matrix product mn:
m.a*n.a+m.d*n.b m.a*n.d+m.d*n.e 0
m.b*n.a+m.e*n.b m.b*n.d+m.e*n.e 0
m.c*n.a+m.f*n.b+n.c m.c*n.d+m.f*n.e+n.f 1
Cat:
PROC [m1, m2, m3, m4: Transformation ¬
NIL]
RETURNS [Transformation];
Concatenates up to four transformations.
PreScale:
PROC [m: Transformation, s:
REAL]
RETURNS [Transformation];
Equivalent to Concat[Scale[s], m].
PreScale2:
PROC [m: Transformation, s:
VEC]
RETURNS [Transformation];
Equivalent to Concat[Scale2[s], m].
PreRotate:
PROC [m: Transformation, r:
REAL]
RETURNS [Transformation];
Equivalent to Concat[Rotate[r], m].
PreTranslate:
PROC [m: Transformation, t:
VEC]
RETURNS [Transformation];
Equivalent to Concat[Translate[t], m].
PostScale:
PROC [m: Transformation, s:
REAL]
RETURNS [Transformation];
Equivalent to Concat[m, Scale[s]].
PostScale2:
PROC [m: Transformation, s:
VEC]
RETURNS [Transformation];
Equivalent to Concat[m, Scale2[s]].
PostRotate:
PROC [m: Transformation, r:
REAL]
RETURNS [Transformation];
Equivalent to Concat[m, Rotate[r]].
PostTranslate:
PROC [m: Transformation, t:
VEC]
RETURNS [Transformation];
Equivalent to Concat[m, Translate[t]].
TranslateTo:
PROC [m: Transformation, t:
VEC]
RETURNS [Transformation];
Returns m with origin moved to t:
|| m.a m.d 0 ||
|| m.b m.e 0 ||
|| t.x t.y 1 ||
Modifying transformations
These operations change the value of an existing Transformation.
Do not apply these to any Transformation that might be shared!
ApplyPreConcat:
PROC [m, p: Transformation];
Equivalent to m^ ← Concat[p, m]. Note the order of p and m!
ApplyPreScale:
PROC [m: Transformation, s:
REAL];
Equivalent to m^ ← Concat[Scale[s], m].
ApplyPreScale2:
PROC [m: Transformation, s:
VEC];
Equivalent to m^ ← Concat[Scale2[s], m].
ApplyPreRotate:
PROC [m: Transformation, r:
REAL];
Equivalent to m^ ← Concat[Rotate[r], m].
ApplyPreTranslate:
PROC [m: Transformation, t:
VEC];
Equivalent to m^ ← Concat[Translate[t], m].
ApplySFToXY:
PROC [m: Transformation, scanMode: ScanMode, sSize, fSize:
INT];
Equivalent to m^ ← Concat[SFToXY[scanMode, sSize, fSize], m].
ApplyPostConcat:
PROC [m, p: Transformation];
Equivalent to m^ ← Concat[m, p].
ApplyPostScale:
PROC [m: Transformation, s:
REAL];
Equivalent to m^ ← Concat[m, Scale[s]].
ApplyPostScale2:
PROC [m: Transformation, s:
VEC];
Equivalent to m^ ← Concat[m, Scale2[s]].
ApplyPostRotate:
PROC [m: Transformation, r:
REAL];
Equivalent to m^ ← Concat[m, Rotate[r]].
ApplyPostTranslate:
PROC [m: Transformation, t:
VEC];
Equivalent to m^ ← Concat[m, Translate[t]].
ApplyXYToSF:
PROC [m: Transformation, scanMode: ScanMode, sSize, fSize:
INT];
Equivalent to m^ ← Concat[m, XYToSF[scanMode, sSize, fSize]].
ApplyTranslateTo:
PROC [m: Transformation, t:
VEC];
Equivalent to m^ ← TranslateTo[m, t].
ApplyCat:
PROC [m: Transformation, m1, m2, m3, m4: Transformation ¬
NIL];
Equivalent to m^ ← Cat[m1, m2, m3, m4]; the initial content of m is ignored.
ApplyInvert:
PROC [m: Transformation];
Equivalent to m^ ← Invert[m].
Applying transformations
Transform:
PROC [m: Transformation, v:
VEC]
RETURNS [
VEC];
"Point" transformation: [m.a*v.x + m.b*v.y + m.c, m.d*v.x + m.e*v.y + m.f].
TransformVec:
PROC [m: Transformation, v:
VEC]
RETURNS [
VEC];
"Vector" transformation: [m.a*v.x + m.b*v.y, m.d*v.x + m.e*v.y].
InverseTransform:
PROC [m: Transformation, v:
VEC]
RETURNS [
VEC];
Equivalent to Transform[Invert[m], v].
InverseTransformVec:
PROC [m: Transformation, v:
VEC]
RETURNS [
VEC];
Equivalent to TransformVec[Invert[m], v].
DRound:
PROC [v:
VEC]
RETURNS [
VEC];
Rounds both components of v to integers.
RoundXY:
PROC [m: Transformation, v:
VEC]
RETURNS [
VEC];
Equivalent to InverseTransform[m, DRound[Transform[m, v]]].
RoundXYVec:
PROC [m: Transformation, v:
VEC]
RETURNS [
VEC];
Equivalent to InverseTransformVec[m, DRound[TransformVec[m, v]]].
Rectangles
TransformRectangle:
PROC [m: Transformation, r: ImagerBox.Rectangle]
RETURNS [ImagerBox.Rectangle];
Returns the smallest rectangle enclosing the transformed vertices of r.
InverseTransformRectangle:
PROC [m: Transformation, r: ImagerBox.Rectangle]
RETURNS [ImagerBox.Rectangle];
Returns the smallest rectangle enclosing the inverse-transformed vertices of r.
Other operations
FactoredTransformation:
TYPE ~
RECORD[r1:
REAL, s:
VEC, r2:
REAL, t:
VEC];
Represents Cat[Rotate[r1], Scale2[s], Rotate[r2], Translate[t]].
Factor:
PROC [m: Transformation]
RETURNS [f: FactoredTransformation];
Returns f such that m=Cat[Rotate[f.r1], Scale2[f.s], Rotate[f.r2], Translate[f.t]].
Note: SingularValues[m] = [MAX[ |f.s.x|, |f.s.y| ], MIN[ |f.s.x|, |f.s.y| ]]
Invert:
PROC [m: Transformation]
RETURNS [Transformation];
Returns the inverse of m.
Singular:
PROC [m: Transformation]
RETURNS [
BOOL];
Returns TRUE if m may not reasonably be inverted.
Equal:
PROC [s, t: Transformation]
RETURNS [
BOOL];
Returns (s.a=t.a AND s.b=t.b AND s.c=t.c AND s.d=t.d AND s.e=t.e AND s.f=t.f).
CloseEnough:
PROC [s, t: Transformation, range:
REAL ¬ 2000.0]
RETURNS [
BOOL];
Returns TRUE if for all points p such that Transform[s, p] is in [0, 0, range, range], Transform[s, p] and Transform[t, p] differ by at most 1/4 in x and y.
CloseToTranslation:
PROC [s, t: Transformation, range:
REAL ¬ 2000.0]
RETURNS [
BOOL];
Returns TRUE if for all points p such that TransformVec[s, p] is in [0, 0, range, range], TransformVec[s, p] and TransformVec[t, p] differ by at most 1/4 in x and y.
SingularValues:
PROC [m: Transformation]
RETURNS [
VEC];
Returns the singular values of the non-translation portion of m. 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 achieve. May raise:
NumericalInstability: SIGNAL [real: REAL];
CISDeg: PROC [degrees: REAL] RETURNS [VEC];