<<>> <> <> <> <> <> <<>> DIRECTORY ImagerBox USING [Rectangle], SF USING [Box], Vector2 USING [VEC]; ImagerTransformation: CEDAR DEFINITIONS ~ BEGIN OPEN Vector2; <> 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 d 0 || || b e 0 || || c f 1 ||>> <> <> <<[ x y 1 ]>> <> <<[ ax+by+c dx+ey+f 1 ].>> <> <<>> Create: PROC [a, b, c, d, e, f: REAL] RETURNS [Transformation]; <> <<|| a d 0 || || b e 0 || || c f 1 ||>> <<>> Destroy: PROC [m: Transformation]; <> <<>> Copy: PROC [m: Transformation] RETURNS [Transformation]; <> <<>> Scale: PROC [s: REAL] RETURNS [Transformation]; <> <<|| s 0 0 || || 0 s 0 || || 0 0 1 ||>> Scale2: PROC [s: VEC] RETURNS [Transformation]; <> <<|| s.x 0 0 || || 0 s.y 0 || || 0 0 1 ||>> <<>> Rotate: PROC [r: REAL] RETURNS [Transformation]; <> <<|| cos r sin r 0 || || -sin r cos r 0 || || 0 0 1 ||>> <<>> Translate: PROC [t: VEC] RETURNS [Transformation]; <> <<|| 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]; <> <<>> XYToSF: PROC [scanMode: ScanMode, sSize, fSize: INT] RETURNS [Transformation]; <> <<>> <> Concat: PROC [m, n: Transformation] RETURNS [Transformation]; <> << 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]; <> <<>> PreScale: PROC [m: Transformation, s: REAL] RETURNS [Transformation]; <> <<>> PreScale2: PROC [m: Transformation, s: VEC] RETURNS [Transformation]; <> <<>> PreRotate: PROC [m: Transformation, r: REAL] RETURNS [Transformation]; <> <<>> PreTranslate: PROC [m: Transformation, t: VEC] RETURNS [Transformation]; <> <<>> PostScale: PROC [m: Transformation, s: REAL] RETURNS [Transformation]; <> <<>> PostScale2: PROC [m: Transformation, s: VEC] RETURNS [Transformation]; <> <<>> PostRotate: PROC [m: Transformation, r: REAL] RETURNS [Transformation]; <> <<>> PostTranslate: PROC [m: Transformation, t: VEC] RETURNS [Transformation]; <> <<>> TranslateTo: PROC [m: Transformation, t: VEC] RETURNS [Transformation]; <> <<|| m.a m.d 0 || || m.b m.e 0 || || t.x t.y 1 ||>> <> <> <> <<>> ApplyPreConcat: PROC [m, p: Transformation]; <> <<>> ApplyPreScale: PROC [m: Transformation, s: REAL]; <> <<>> ApplyPreScale2: PROC [m: Transformation, s: VEC]; <> <<>> ApplyPreRotate: PROC [m: Transformation, r: REAL]; <> <<>> ApplyPreTranslate: PROC [m: Transformation, t: VEC]; <> <<>> ApplySFToXY: PROC [m: Transformation, scanMode: ScanMode, sSize, fSize: INT]; <> <<>> ApplyPostConcat: PROC [m, p: Transformation]; <> <<>> ApplyPostScale: PROC [m: Transformation, s: REAL]; <> <<>> ApplyPostScale2: PROC [m: Transformation, s: VEC]; <> <<>> ApplyPostRotate: PROC [m: Transformation, r: REAL]; <> <<>> ApplyPostTranslate: PROC [m: Transformation, t: VEC]; <> <<>> ApplyXYToSF: PROC [m: Transformation, scanMode: ScanMode, sSize, fSize: INT]; <> <<>> ApplyTranslateTo: PROC [m: Transformation, t: VEC]; <> <<>> ApplyCat: PROC [m: Transformation, m1, m2, m3, m4: Transformation ¬ NIL]; <> ApplyInvert: PROC [m: Transformation]; <> <<>> <<>> <> 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]; <> <<>> InverseTransformVec: PROC [m: Transformation, v: VEC] RETURNS [VEC]; <> <<>> DRound: PROC [v: VEC] RETURNS [VEC]; <> RoundXY: PROC [m: Transformation, v: VEC] RETURNS [VEC]; <> <<>> RoundXYVec: PROC [m: Transformation, v: VEC] RETURNS [VEC]; <> <<>> <> TransformRectangle: PROC [m: Transformation, r: ImagerBox.Rectangle] RETURNS [ImagerBox.Rectangle]; <> <<>> InverseTransformRectangle: PROC [m: Transformation, r: ImagerBox.Rectangle] RETURNS [ImagerBox.Rectangle]; <> <<>> <> <> <<>> EasyTransformation: PROC [m: Transformation] RETURNS [BOOL]; EasyTransformBox: PROC [m: Transformation, x, y, w, h: INTEGER, clip: SF.Box] RETURNS [SF.Box]; <> <> FactoredTransformation: TYPE ~ RECORD[r1: REAL, s: VEC, r2: REAL, t: VEC]; <> <<>> Factor: PROC [m: Transformation] RETURNS [f: FactoredTransformation]; <> <> Invert: PROC [m: Transformation] RETURNS [Transformation]; <> <<>> Singular: PROC [m: Transformation] RETURNS [BOOL]; <> Equal: PROC [s, t: Transformation] RETURNS [BOOL]; <> CloseEnough: PROC [s, t: Transformation, range: REAL ¬ 2000.0] RETURNS [BOOL]; <> CloseToTranslation: PROC [s, t: Transformation, range: REAL ¬ 2000.0] RETURNS [BOOL]; <> <<>> SingularValues: PROC [m: Transformation] RETURNS [VEC]; <> NumericalInstability: SIGNAL [real: REAL]; CISDeg: PROC [degrees: REAL] RETURNS [VEC]; END.