IF square.parent =
NIL
THEN {
Create square's parent, using square's corner as the center of parent:
NewParent:
PROC [square: Square, q, oppQ: Quadrant]
RETURNS [root: Square] ~ {
l, r, b, t, d: REAL ¬ 2.0*Size[square];
c: Pair ~ square.corners[q].point;
pp: Pair ~ square.corners[oppQ].point;
SELECT oppQ
FROM
lb => {l ¬ pp.x; b ¬ pp.y; r ¬ pp.x+d; t ¬ pp.y+d};
lt => {l ¬ pp.x; t ¬ pp.y; r ¬ pp.x+d; b ¬ pp.y-d};
rb => {r ¬ pp.x; b ¬ pp.y; l ¬ pp.x-d; t ¬ pp.y+d};
rt => {r ¬ pp.x; t ¬ pp.y; l ¬ pp.x-d; b ¬ pp.y-d};
ENDCASE;
root ¬ NEW[SquareRep];
root.corners[oppQ] ¬ square.corners[oppQ];
IF oppQ # lb THEN root.corners[lb] ¬ NewCorner[[l, b]];
IF oppQ # lt THEN root.corners[lt] ¬ NewCorner[[l, t]];
IF oppQ # rb THEN root.corners[rb] ¬ NewCorner[[r, b]];
IF oppQ # rt THEN root.corners[rt] ¬ NewCorner[[r, t]];
};
q: Quadrant ~ SELECT edge FROM l => lb, r => rt, b => rb, ENDCASE => lt;
oppQ: Quadrant ~ OppositeQuadrant[q];
square.parent ¬ root ¬ NewParent[square, q, oppQ];
square.quadrant ¬ oppQ;
root.corners[oppQ] ¬ square.corners[oppQ];
root.kids[oppQ] ¬ square; -- root has a kid, but is not itself truly subdivided
};
{
AddSquareToParent:
PROC [parent: Square, quadrant: Quadrant, size:
REAL] ~ {
new: Square¬ NEW[SquareRep ¬ [quadrant: quadrant, terminal: TRUE, parent: parent]];
c: Corner ¬ parent.corners[quadrant];
l, r: REAL ¬ parent.corners[quadrant].point.x;
b, t: REAL ¬ parent.corners[quadrant].point.y;
SELECT quadrant
FROM
lb => {r ¬ l+size; t ¬ b+size};
lt => {r ¬ l+size; b ¬ t-size};
rb => {l ¬ r-size; t ¬ b+size};
rt => {l ¬ r-size; b ¬ t-size};
ENDCASE;
parent.kids[quadrant] ¬ new;
FOR e: Edge
IN Edge
DO
neighbor: Square ~ EdgeNeighbor[new, e];
IF neighbor #
NIL
THEN {
n: Corners ~ neighbor.corners;
SELECT e
FROM
l => {new.corners[lb] ¬ n[rb]; new.corners[lt] ¬ n[rt]};
r => {new.corners[rb] ¬ n[lb]; new.corners[rt] ¬ n[lt]};
b => {new.corners[lb] ¬ n[lt]; new.corners[rb] ¬ n[rt]};
t => {new.corners[lt] ¬ n[lb]; new.corners[rt] ¬ n[rb]};
ENDCASE;
};
ENDLOOP;
new.corners[quadrant] ¬ parent.corners[quadrant];
FOR q: Quadrant
IN Quadrant
DO
IF new.corners[q] =
NIL
THEN new.corners[q] ¬
NEW[CornerRep ¬
[point: SELECT q FROM lb => [l, b], lt => [l, t], rb => [r, b], ENDCASE => [r, t]]];
ENDLOOP;
};
parent: Square ¬ square.parent;
info: EdgeInfo ~ GetEdgeInfo[square, edge];
IF info.recurse
THEN {
neighborOfParent: Square ¬ EdgeNeighbor[square.parent, edge];
IF neighborOfParent = NIL THEN root ¬ AddSquare[square.parent, edge];
IF (neighborOfParent ¬ EdgeNeighbor[square.parent, edge]) = NIL THEN ERROR;
parent ¬ neighborOfParent;
};
parent.terminal ¬ FALSE;
AddSquareToParent[parent, info.nQuadrant, Size[square]];
};