<> <> <> <> DIRECTORY Basics, CD, CDBasics, CDBasicsInline, Imager, ImagerTransformation; CDBasicsImpl: CEDAR PROGRAM IMPORTS Basics, ImagerTransformation, CDBasicsInline EXPORTS CDBasics, CDBasicsInline = BEGIN <<>> Skip: PUBLIC PROC[CD.Rect] = { }; DecomposeRect: PUBLIC PROC [r, test: CD.Rect, inside, outside: PROC[CD.Rect]_Skip] = { IF r.x1> <<-- obtained by first doing itemInCell and then>> <<-- doing cellInWorld. It uses the observation>> <<-- that a reflection in x followed by a z-degree clockwise>> <<-- rotation is the same as a (360-z)-degree clockwise rotation>> <<-- followed by a reflection in x. Thus if itemInCell>> <<-- contains a final reflection, then cellInWorld's rotation>> <<-- operates in reverse.>> itemInWorld _ composeTable[itemInCell][cellInWorld] }; ReallyInverseOrient: PROC [orient: CD.Orientation] RETURNS [inverse: CD.Orientation] = { <<-- For all orientationIndexes o1, ComposeOrient[o1, InverseOrient[o1]] = 0.>> <<-- A reflection in x followed by a z-degree clockwise>> <<-- rotation is the same as a (360-z)-degree clockwise rotation>> <<-- followed by a reflection in x. Thus if orient>> <<-- contains a final reflection, then the inverse rotation>> <<-- operates in the same direction as the forward one.>> refl: [0..1] ~ Basics.BITAND[ORD[orient], 1]; rot: [0..6] _ Basics.BITAND[ORD[orient], 6]; IF refl=0 AND rot#0 THEN rot _ 8-rot; inverse _ VAL[rot+refl]; }; InverseOrient: PUBLIC PROC [orient: CD.Orientation] RETURNS [CD.Orientation] = { RETURN [inverseTable[orient]] }; DecomposeOrient: PUBLIC PROC [itemInWorld, cellInWorld: CD.Orientation] RETURNS [itemInCell: CD.Orientation] = { RETURN[ composeTable[itemInWorld][inverseTable[cellInWorld]] ] }; ReallyComposeOrient: PROC [itemInCell, cellInWorld: CD.Orientation] RETURNS [itemInWorld: CD.Orientation] = { <<-- This procedure produces the composite orientation>> <<-- obtained by first doing itemInCell and then>> <<-- doing cellInWorld. It uses the observation>> <<-- that a reflection in x followed by a z-degree clockwise>> <<-- rotation is the same as a (360-z)-degree clockwise rotation>> <<-- followed by a reflection in x. Thus if itemInCell>> <<-- contains a final reflection, then cellInWorld's rotation>> <<-- operates in reverse.>> refl1: [0..1] ~ Basics.BITAND[ORD[itemInCell], 1]; rot2: [0..6] _ Basics.BITAND[ORD[cellInWorld], 6]; IF refl1#0 AND rot2#0 THEN rot2 _ 8-rot2; itemInWorld _ VAL[Basics.BITAND[ Basics.BITAND[ORD[itemInCell], 6] + rot2 + Basics.BITXOR[refl1, Basics.BITAND[ORD[cellInWorld], 1]], 7]]; }; <<>> ComposeTransform: PUBLIC PROC [itemInCell, cellInWorld: CD.Transformation] RETURNS [itemInWorld: CD.Transformation] = { RETURN [CDBasicsInline.ComposeTransform[itemInCell, cellInWorld]] }; InverseTransform: PUBLIC PROC [trans: CD.Transformation] RETURNS [CD.Transformation] = { ERROR; <> <> }; DecomposeTransform: PUBLIC PROC [itemInWorld, cellInWorld: CD.Transformation] RETURNS [itemInCell: CD.Transformation] = { itemInCell.off _ DeMapPoint[itemInWorld.off, cellInWorld]; itemInCell.orient _ DecomposeOrient[itemInWorld.orient, cellInWorld.orient] }; ImagerTransform: PUBLIC PROC [trans: CD.Transformation] RETURNS [Imager.Transformation] = { RETURN [CDBasicsInline.ImagerTransform[trans]] }; composeTable: PUBLIC ARRAY CD.Orientation OF ARRAY CD.Orientation OF CD.Orientation; inverseTable: PUBLIC ARRAY CD.Orientation OF CD.Orientation; <<--set up>> FOR o1: CD.Orientation IN CD.Orientation DO inverseTable[o1] _ ReallyInverseOrient[o1]; FOR o2: CD.Orientation IN CD.Orientation DO composeTable[o1][o2] _ ReallyComposeOrient[o1, o2]; ENDLOOP; ENDLOOP; END.