<*PRAGMA LL*> INTERFACEA PolyRegion.T represents a set of points as a list of Region.T's. If n rectangles are joined together into a PolyRegion.T with the JoinRect procedure below, the PolyRegion will contain about lg n Regions, and the total cost of the join is likely to be about n (lg n)^2 instead of n^2, assuming the rectangles don't overlap too badly.PolyRegion ; IMPORT Rect, Region, Point;
The procedures modify the data structure pointed to by the private field of a PolyRegion; therefore, you must not assign PolyRegions.
TYPE T = RECORD r: Rect.T; p: Private END; (* pr.r is the bounding rectangle of the PolyRegion pr. *) Private <: REFANY; PROCEDURE JoinRect(VAR pr: T; READONLY rect: Rect.T);
pr := Union(pr, rect).
PROCEDURE JoinRgn(VAR pr: T; READONLY rgn: Region.T);
pr := Union(pr, rgn).
PROCEDURE ToRegion(READONLY pr: T): Region.T;
Return pr as a region.
PROCEDURE OverlapRect(READONLY pr: T; READONLY rect: Rect.T): BOOLEAN;
Return whether pr and rect have a non-empty intersection.
PROCEDURE Complement(READONLY pr: T; READONLY rgn: Region.T): Region.T;
Return rgn-pr as a region.
PROCEDURE Meet(READONLY pr: T; READONLY rgn: Region.T): Region.T;
Return the intersection of pr and rgn as a region.
CONST Empty = T{Rect.Empty, NIL};The following procedure belongs in Region
PROCEDURE Factor(READONLY t: Region.T; READONLY r: Rect.T; READONLY delta: Point.T; VAR rl: REF ARRAY OF Rect.T): CARDINAL;
Set rl to a list of disjoint rectangles which partition t meetrect r, modifying rl^ if possible. Return the number of rectangles, n, in the partition; only the first n rectangles in rl^ are meaningful. The order of rl^ is such that if i<j then rl[i] translated by delta doesn't intersect rl[j]. If the intersection is empty, 0 is returned.
END PolyRegion.