<<>> <> <> <> <> <> <<>> DIRECTORY G3dBasic, G3dShape, G3dBox, G3dVector; G3dBoxImpl: CEDAR PROGRAM IMPORTS G3dVector EXPORTS G3dBox ~ BEGIN <> Box: TYPE ~ G3dBasic.Box; NatSequence: TYPE ~ G3dBasic.NatSequence; Surface: TYPE ~ G3dBasic.Surface; Triple: TYPE ~ G3dBasic.Triple; TripleSequence: TYPE ~ G3dBasic.TripleSequence; VertexSequence: TYPE ~ G3dShape.VertexSequence; <> BoxFromPoints: PUBLIC PROC [p0, p1: Triple] RETURNS [box: Box] ~ { box.min ¬ Min3d[p0, p1]; box.max ¬ Max3d[p0, p1]; }; BoxFromSurface: PUBLIC PROC [surf: Surface, verts: VertexSequence] RETURNS [box: Box] ~ { RETURN[BoxFromVertices[surf.vertices, verts]]; }; BoxFromVertices: PUBLIC PROC [nats: NatSequence, verts: VertexSequence] RETURNS [box: Box] ~ { IF nats=NIL OR nats.length=0 OR verts=NIL OR verts.length=0 THEN RETURN; box.min ¬ box.max ¬ verts[nats[0]].point; FOR i: INT IN [0 .. nats.length) DO box ¬ BoxUnionPoint[box, verts[nats[i]].point]; ENDLOOP; }; BoxFromTripleSequence: PUBLIC PROC [ts: TripleSequence] RETURNS [box: Box] ~ { IF ts=NIL THEN RETURN; box.min ¬ box.max ¬ ts[0]; FOR i: INT IN [0 .. ts.length) DO box ¬ BoxUnionPoint[box, ts[i]]; ENDLOOP; }; <> Intersect: PUBLIC PROC [box1, box2: Box] RETURNS [has: BOOL, intersection: Box] ~ { intersection.min ¬ Max3d[box1.min, box2.min]; intersection.max ¬ Min3d[box1.max, box2.max]; has ¬ intersection.min.x <= intersection.max.x AND intersection.min.y <= intersection.max.y AND intersection.min.z <= intersection.max.z; }; PointInBox: PUBLIC PROC [box: Box, pt: Triple] RETURNS [BOOL] ~ { IF pt.x < box.min.x OR pt.x > box.max.x THEN RETURN [FALSE]; IF pt.y < box.min.y OR pt.y > box.max.y THEN RETURN [FALSE]; IF pt.z < box.min.z OR pt.z > box.max.z THEN RETURN [FALSE]; RETURN [TRUE]; }; <> BoxUnionBox: PUBLIC PROC [b1, b2: Box] RETURNS [union: Box] ~ { union.min ¬ Min3d[b1.min, b2.min]; union.max ¬ Max3d[b1.max, b2.max]; }; BoxUnionPoint: PUBLIC PROC [box: Box, point: Triple] RETURNS [new: Box] ~ { new.min ¬ Min3d[box.min, point]; new.max ¬ Max3d[box.max, point]; }; <> BoxMap: PUBLIC PROC [rel, abs: Box] RETURNS [map: Box] ~ { map.min.x ¬ Lerp[rel.min.x, abs.min.x, abs.max.x]; map.min.y ¬ Lerp[rel.min.y, abs.min.y, abs.max.y]; map.min.z ¬ Lerp[rel.min.z, abs.min.z, abs.max.z]; map.max.x ¬ Lerp[rel.max.x, abs.min.x, abs.max.x]; map.max.y ¬ Lerp[rel.max.y, abs.min.y, abs.max.y]; map.max.z ¬ Lerp[rel.max.z, abs.min.z, abs.max.z]; }; <> BoxCenter: PUBLIC PROC [box: Box] RETURNS [Triple] ~ { RETURN[G3dVector.Midpoint[box.min, box.max]]; }; BoxEdges: PUBLIC PROC [box: Box] RETURNS [Triple] ~ { Abs: PROC [v: Triple] RETURNS [Triple] ~ { RETURN[[ABS[v.x], ABS[v.y], ABS[v.z]]]; }; <> RETURN[Abs[G3dVector.Sub[box.max, box.min]]]; }; <> Lerp: PUBLIC PROC [alpha, low, high: REAL] RETURNS [REAL] ~ { RETURN[low+(alpha*(high-low))]; }; Min3d: PUBLIC PROC [p0, p1: Triple] RETURNS [Triple] ~ { RETURN[[MIN[p0.x, p1.x], MIN[p0.y, p1.y], MIN[p0.z, p1.z]]]; }; Max3d: PUBLIC PROC [p0, p1: Triple] RETURNS [Triple] ~ { RETURN[[MAX[p0.x, p1.x], MAX[p0.y, p1.y], MAX[p0.z, p1.z]]]; }; END.