G3dBoxImpl.mesa
Copyright Ó 1985, 1992 by Xerox Corporation. All rights reserved.
Glassner, February 18, 1991 8:06 pm PST
Jules Bloomenthal July 14, 1992 2:09 pm PDT
Ken Fishkin, August 25, 1992 1:58 pm PDT
DIRECTORY G3dBasic, G3dShape, G3dBox, G3dVector;
G3dBoxImpl: CEDAR PROGRAM
IMPORTS G3dVector
EXPORTS G3dBox
~ BEGIN
Imported Types
Box:     TYPE ~ G3dBasic.Box;
NatSequence:   TYPE ~ G3dBasic.NatSequence;
Surface:    TYPE ~ G3dBasic.Surface;
Triple:    TYPE ~ G3dBasic.Triple;
TripleSequence:  TYPE ~ G3dBasic.TripleSequence;
VertexSequence:  TYPE ~ G3dShape.VertexSequence;
Creation
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;
};
Tests
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];
};
Combination
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];
};
Modification
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];
};
Derived Data
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[G3dVector.Abs[G3dVector.Sub[box.max, box.min]]];
RETURN[Abs[G3dVector.Sub[box.max, box.min]]];
};
Utility Procs
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.