ImagerManhattan.mesa
Michael Plass, December 30, 1983 2:22 pm
Provides operations on manhattan polygons. The coordinates are given in terms of s and f (for slow and fast).
DIRECTORY ImagerBasic USING [Visibility, DeviceRectangle];
ImagerManhattan: CEDAR DEFINITIONS ~ BEGIN
Data types
DeviceRectangle:
TYPE ~ ImagerBasic.DeviceRectangle;
RECORD [sMin, fMin: INTEGER, sSize, fSize: NAT];
Visibility:
TYPE ~ ImagerBasic.Visibility;
{visible, partlyVisible, invisible};
Polygon:
TYPE ~
LIST
OF DeviceRectangle;
If a and b are consecutive boxes in the list, must have either
a.sMin = b.sMin AND a.sSize = b.sSize AND a.fMin+a.fSize <= b.fMin
OR
a.sMin+a.sSize <= b.sMin
Validate:
PROC [polygon: Polygon]
RETURNS [Polygon];
Checks that the above invariant is satisfied.
InvalidManhattanPolygon: ERROR;
Polygon Creation
CreateFromRuns:
PROC [
runs:
PROC[
-- Create calls this back
run: PROC[sMin, fMin: INTEGER, fSize: NAT], -- client calls this from inside runs.
repeat: PROC[timesToRepeatScanline: NAT] -- client calls this to repeat a scanline
]
] RETURNS [Polygon];
The runs proc should call run for each run, in non-descreasing s. It may call repeat to duplicate a scanline just entered.
CreateFromBox: PROC [deviceRectangle: DeviceRectangle] RETURNS [Polygon];
Polygon Destruction
Destroy:
PROC [rectangleList:
LIST
OF DeviceRectangle];
Puts the nodes on an avail list to be re-used; much faster than letting the garbage collector do the work, but don't destroy a list unless you are sure nobody is depending on it. (The avail list nodes will get garbage collected eventually if they are unneeded.)
Making new Polygons from old
Copy:
PROC [polygon
: Polygon]
RETURNS [Polygon];
Union:
PROC [a, b: Polygon]
RETURNS [Polygon];
Intersection:
PROC [a, b: Polygon]
RETURNS [Polygon];
Difference:
PROC [a, b: Polygon]
RETURNS [Polygon];
Modifying existing Polygons
Shift:
PROC [polygon: Polygon, sShift, fShift:
INTEGER];
Canonicalize:
PROC [rectangleList:
LIST
OF DeviceRectangle]
RETURNS [Polygon];
Turns a list of arbitrary rectangles into a valid Polygon. Re-uses the storage, so copy first if rectangleList might be shared.
Extracting info from Polygons
BoundingBox:
PROC [polygon: Polygon]
RETURNS [DeviceRectangle];
CountBoxes:
PROC [polygon: Polygon]
RETURNS [
INT];
CountRuns:
PROC [polygon: Polygon]
RETURNS [
INT];
MapRuns:
PROC [polygon: Polygon, run:
PROC [sMin, fMin:
INTEGER, fSize:
NAT]];
IsVisible:
PROC [mask, clipper: Polygon]
RETURNS [Visibility];
SELECT Intersection[mask, clipper] FROM
= empty => invisible,
= mask => visible,
ENDCASE => partlyVisible;
N. B. will return invisible if mask is empty.
END.