File: IntTransDefs.mesa
Written by Martin Newell, July 1979
Last edited June 10, 1981 11:12 AM
Last Edited by: McCreight, January 30, 1985 3:15:41 pm PST
IntTransDefs: CEDAR DEFINITIONS =
*************************************************************************************
This package of transformation procedures is designed to support the processing of
CalTech Intermediate Form files on an Alto computer. The impact of these requirements
are threefold: 1) nesting of transformations involves post-multiplication of the
incremental transformation and premultiplication of the current transformation;
2) input parameters specified in (long) integers (no reals); and 3) slow floating point
support.
The package supports the tree structure of transformations found in nested calls to CIF
symbols by implementing a stack of transformations. In addition to the stack there is
a "Current Transformation" and a "Local Transformation". The Current transformation
represents the accumulated effect of all the transformations invoked. The Local
transformation describes the relationship of the current transformation, or coordinate
system, to the previous one.
A new coordinate system is started by calling Push. This pushes the Current
transformation onto the stack, and sets the Local transformation to the identity; the
Current transformation is not changed yet. Subsequent calls to transformation
procedures such as Rotate, Translate, etc. cause the Local transformation to be
post-multiplied by appropriate matrices. As soon as a call is made to a procedure
that needs to use the Current transformation (e.g. TransformPoint) the Current
transformation is pre-multiplied by the Local transformation to yield a new Current
transformation describing the current coordinate system. The current coordinate system
is terminated by a call to Pop which simply pops the top of the stack into the Current
transformation.
Calls to procedures in the package must be arranged (sequentially) into nested "Blocks",
where a Block has the form:
Push;
<Calls that affect the local transformation(e.g. Rotate, Translate...)>;
<Calls that use the current transformation(e.g. TransformPoint, ... other Blocks)>;
Pop;
Failure to conform to this sequence will result in the ERROR TransformationBadContext,
e.g. by calling Rotate after TransformPoint without an intervening Push.
The only other ERROR generated by the package is TransformationStackUnderflow.
For use with CIF it is expected that direct execution of a call to a CIF symbol would
result in a Push, calls to the relevant transformations in the same order as they are
given in the CIF line, invocation of the CIF symbol, Pop. e.g. the CIF statement:
CS100 MX R-1,1 T10,20
would be executed by:
Push; Mirror[x]; Rotate[-1,1]; Translate[10,20]; "InvokeSymbol[100]"; Pop;
For generating the compiled form of a symbol, the above statement would generate:
Push; Mirror[x]; Rotate[-1,1]; Translate[10,20]; T←GetLocal[];
"SaveCompiledFormOfInvokeSymbol[100]WithTransformation[T]";
Pop;
The compiled form would then be executed by the sequence:
Push; ApplyLocal[@T]; "InvokeSymbol[100]"; Pop;
New addition - March 1980 - Contexts
The package supports multiple transformation contexts, for use in processing CIF
files in an order different from a walk of the symbol structure. This is for use
with an Interpreter that does sorting based on geometry. The current
transformation can be "frozen" to produce a new context, on which the usual Push,
Pop, Rotate etc. operations can be performed. See FreezeContext and SwapContext.
*************************************************************************************
BEGIN
ContextStack: TYPE = LIST OF Transform ← NIL;
Transform: TYPE = REF TransformRecord;
TransformRecord: TYPE = RECORD[
type: [ident..translate+rotscale],
a11,a21,a31,a12,a22,a32,a33: REAL];
ident: INTEGER = 0;
translate: INTEGER = 1;
rotscale: INTEGER = 2;
CoordName: TYPE = {x,y};
InitTransformation: PUBLIC PROCEDURE RETURNS [BOOL];
Initialize (or re-initialize) Transformations package
FinishTransformation: PUBLIC PROCEDURE RETURNS [BOOL];
FreezeContext: PUBLIC PROCEDURE RETURNS [cs: ContextStack];
Create new context based on existing context state
SwapContext: PUBLIC PROCEDURE [cs: ContextStack];
Change context to cs, formerly returned by FreezeContext
Push: PUBLIC PROCEDURE;
Push current transformation - start a new relative coordinate system
Pop: PUBLIC PROCEDURE;
Pop current transformation - return to previous coordinate system
Rotate: PUBLIC PROCEDURE[xRot,yRot: INT];
Rotate x axis to direction of (xRot,yRot)
Translate: PUBLIC PROCEDURE[xTrans,yTrans: INT];
Translate by (xTrans,yTrans)
Mirror: PUBLIC PROCEDURE[coord: CoordName];
Mirror the indicated coordinates
Scale: PUBLIC PROCEDURE[numerator,denominator: INT];
Scale by numerator/denominator
GetLocal: PUBLIC PROCEDURE RETURNS[localTransform: TransformRecord];
Return incremental transformation built since last Push
ApplyLocal: PUBLIC PROCEDURE[transform: TransformRecord];
Apply transformation to current local transformation
GetCurrent: PUBLIC PROCEDURE RETURNS[currentTransform: TransformRecord];
Return current cumulative transformation
TransformPoint: PUBLIC PROCEDURE[x,y: INT] RETURNS[xT,yT: INT];
Transform the point (x,y) by current cumulative transformation
TransformVector: PUBLIC PROCEDURE[x,y: INT] RETURNS[xT,yT: INT];
Transform the direction (x,y) by current cumulative transformation
RTransformPoint: PUBLIC PROCEDURE[x,y: REAL] RETURNS[xT,yT: REAL];
Transform the point (x,y) by current cumulative transformation - in REALs
RTransformVector: PUBLIC PROCEDURE[x,y: REAL] RETURNS[xT,yT: REAL];
Transform the direction (x,y) by current cumulative transformation - in REALs
TransformationStackUnderflow: PUBLIC ERROR;
TransformationBadContext: PUBLIC ERROR;
END.