GGTransformImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last edited by Bier on July 29, 1986 0:32:47 am PDT
Contents: A layer on top of ImagerTransformation for use in Gargoyle.
Pier, May 30, 1986 4:27:26 pm PDT
DIRECTORY
ImagerTransformation,
GGBasicTypes,
GGTransform;
GGTransformImpl: CEDAR PROGRAM
IMPORTS ImagerTransformation
EXPORTS GGTransform =
BEGIN
Point: TYPE = GGBasicTypes.Point;
Identity: PUBLIC PROC RETURNS [id: ImagerTransformation.Transformation] = {
id ← ImagerTransformation.Translate[[0, 0]];
};
Transform: PUBLIC PROC [m: ImagerTransformation.Transformation, p: Point] RETURNS [newP: Point] = {
result: ImagerTransformation.VEC;
result ← ImagerTransformation.Transform[m, [p.x, p.y] ];
newP ← [result.x, result.y];
};
RotateAboutPoint: PUBLIC PROC [origin: Point, degrees: REAL] RETURNS [m: ImagerTransformation.Transformation] = {
m ← ImagerTransformation.Translate[ [-origin.x, -origin.y] ];
m ← ImagerTransformation.PostRotate[m, degrees];
m ← ImagerTransformation.PostTranslate[m, [origin.x, origin.y]];
};
ScaleAboutPoint: PUBLIC PROC [origin: Point, scalar: REAL] RETURNS [m: ImagerTransformation.Transformation] = {
m ← ImagerTransformation.Translate[ [-origin.x, -origin.y] ];
m ← ImagerTransformation.PostScale[m, scalar];
m ← ImagerTransformation.PostTranslate[m, [origin.x, origin.y]];
};
ScaleUnevenAboutPoint: PUBLIC PROC [origin: Point, scalarX: REAL, scalarY: REAL] RETURNS [m: ImagerTransformation.Transformation] = {
m ← ImagerTransformation.Translate[ [-origin.x, -origin.y] ];
m ← ImagerTransformation.PostScale2[m, [scalarX, scalarY]];
m ← ImagerTransformation.PostTranslate[m, [origin.x, origin.y]];
};
Thanks to Maureen
SixPoints: PUBLIC PROC[pts: ARRAY [0..5] OF Point] RETURNS[transform: ImagerTransformation.Transformation] = {
dpts: ARRAY [0..3] OF Point;
a,b,d,e: REAL;
del: REAL;
xform: ImagerTransformation.Transformation;
dpts[0].x ← pts[1].x-pts[0].x;
dpts[0].y ← pts[1].y-pts[0].y;
dpts[1].x ← pts[2].x-pts[0].x;
dpts[1].y ← pts[2].y-pts[0].y;
dpts[2].x ← pts[4].x-pts[3].x;
dpts[2].y ← pts[4].y-pts[3].y;
dpts[3].x ← pts[5].x-pts[3].x;
dpts[3].y ← pts[5].y-pts[3].y;
del ← dpts[0].x*dpts[1].y-dpts[1].x*dpts[0].y;
IF del=0 THEN ERROR;
a ← (dpts[2].x*dpts[1].y-dpts[3].x*dpts[0].y)/del;
b ← (dpts[0].x*dpts[3].x-dpts[1].x*dpts[2].x)/del;
d ← (dpts[2].y*dpts[1].y-dpts[3].y*dpts[0].y)/del;
e ← (dpts[0].x*dpts[3].y-dpts[1].x*dpts[2].y)/del;
xform ← ImagerTransformation.Create[a: a, b: b, c: 0, d: d, e: e, f: 0];
xform ← ImagerTransformation.PostTranslate[xform, [x: pts[3].x, y: pts[3].y]];
xform ← ImagerTransformation.PreTranslate[xform, [x: -pts[0].x, y: -pts[0].y]];
RETURN[xform];
};
FourPoints: PUBLIC PROC[pts: ARRAY [0..3] OF Point] RETURNS[transform: ImagerTransformation.Transformation] = {
xform: ImagerTransformation.Transformation;
a,b,d,e: REAL;
x1: REAL ← pts[1].x-pts[0].x;
x2: REAL ← pts[3].x-pts[2].x;
y1: REAL ← pts[1].y-pts[0].y;
y2: REAL ← pts[3].y-pts[2].y;
del: REAL ← x1*x1+y1*y1;
ax1+by1=x2;
dx1+ey1=y2;
but a=e and b=-d so
ax1-dy1=x2;
ay1+dx1=y2;
IF del=0 THEN ERROR;
a ← (x1*x2+y1*y2)/del;
e ← a;
d ← (x1*y2-y1*x2)/del;
b ← -d ;
c ← pts[2].x-pts[0].x;
f ← pts[2].y-pts[0].y;
xform ← ImagerTransformation.Create[a: a, b: b, c: 0, d: d, e: e, f: 0];
xform ← ImagerTransformation.PostTranslate[xform, [x: pts[2].x, y: pts[2].y]];
xform ← ImagerTransformation.PreTranslate[xform, [x: -pts[0].x, y: -pts[0].y]];
RETURN[xform]
};
END.