ImagerTransformation.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, October 17, 1984 10:28:42 am PDT
Creating new transformation matrices.
Create:
PROC[a, b, c, d, e, f:
REAL]
RETURNS[Transformation];
Create a new transformation.
Copy:
PROC[m: Transformation]
RETURNS[Transformation];
Make a copy of m.
Translate:
PROC[t:
VEC]
RETURNS[Transformation];
Equivalent to Create[1, 0, t.x, 0, 1, t.y].
Scale:
PROC[s:
REAL]
RETURNS[Transformation];
Equivalent to Create[s, 0, 0, 0, s, 0].
Scale2:
PROC[s:
VEC]
RETURNS[Transformation];
Equivalent to Create[s.x, 0, 0, 0, s.y, 0].
Rotate:
PROC[a:
REAL]
RETURNS[Transformation];
Equivalent to Create[cos(a), -sin(a), 0, sin(a), cos(a), 0]. Angle a is in degrees.
Concat:
PROC[m, n: Transformation]
RETURNS[Transformation];
Returns the matrix product mn.
Cat:
PROC[m1, m2, m3, m4, m5, m6: Transformation ←
NIL]
RETURNS[Transformation];
Returns the concatenation of up to six transformations.
Invert:
PROC[m: Transformation]
RETURNS[Transformation];
Returns m's inverse.
Modifying an existing transformation in place.
PreMultiply:
PROC[m, pre: Transformation];
Equivalent to m^ ← Concat[pre, m]^.
PreScale:
PROC[m: Transformation, s:
REAL];
Equivalent to PreMultiply[m, Scale[s]].
PreScale2:
PROC[m: Transformation, s:
VEC];
Equivalent to PreMultiply[m, Scale2[s]].
PreRotate:
PROC[m: Transformation, a:
REAL];
Equivalent to PreMultiply[m, Rotate[a]].
PreTranslate:
PROC[m: Transformation, t:
VEC];
Equivalent to PreMultiply[m, Translate[t]].
PostMultiply:
PROC[m, post: Transformation];
Equivalent to m^ ← Concat[m, post]^.
PostScale:
PROC[m: Transformation, s:
REAL];
Equivalent to PostMultiply[m, Scale[s]].
PostScale2:
PROC[m: Transformation, s:
VEC];
Equivalent to PostMultiply[m, Scale2[s]].
PostRotate:
PROC[m: Transformation, a:
REAL];
Equivalent to PostMultiply[m, Rotate[a]].
PostTranslate:
PROC[m: Transformation, t:
VEC];
Equivalent to PostMultiply[m, Translate[t]].
Get:
PROC[m: Transformation]
RETURNS[TransformationRep] ~
INLINE {
RETURN[m^] };
Get m's contents.
Set:
PROC[m: Transformation, value: TransformationRep] ~
INLINE { m^ ← value };
Set m to a given transformation.
GetTrans:
PROC[m: Transformation]
RETURNS[
VEC] ~
INLINE {
RETURN[[m.c, m.f]] };
Get m's translation part.
SetTrans:
PROC[m: Transformation, t:
VEC] ~
INLINE { m.c ← t.x; m.f ← t.y };
Set m's translation part.
Applying a transformation (or its inverse) to a position or displacement
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].
Rounding
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]]].
Factoring a transformation
FactoredTransformation:
TYPE ~
RECORD[
preRotate: REAL, -- degrees
scale: VEC,
postRotate: REAL, -- degrees
translate: VEC
];
Represents Cat[Rotate[preRotate], Scale2[scale], Rotate[postRotate], Translate[translate]]
Factor:
PROC[Transformation]
RETURNS[FactoredTransformation];
Combine: PROC[FactoredTransformation] RETURNS[Transformation];
These test for transformations that are close to each other.
CloseEnough:
PROC[s, t: Transformation, rangeSize:
REAL ← 2000.0]
RETURNS[
BOOL];
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: Transformation, rangeSize:
REAL ← 2000.0]
RETURNS[
BOOL];
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: Transformation, rect: Rectangle] RETURNS[Rectangle];
TransformIntRectangle: PROC[m: Transformation, rect: Rectangle] RETURNS[IntRectangle];