ThreeDPackageImpl.mesa
Last Edited by: Crow, December 5, 1983 7:51 pm
DIRECTORY
RealFns    USING [CosDeg, SinDeg, SqRt],
ThreeDPackage;
ThreeDPackageImpl: CEDAR PROGRAM
IMPORTS RealFns
EXPORTS ThreeDPackage
= BEGIN OPEN ThreeDPackage;
Sqr: PROCEDURE [number: REAL] RETURNS [REAL] ~ INLINE { RETURN[number * number]; };
SumTriple: PUBLIC PROCEDURE [t1, t2: Triple] RETURNS [Triple] ~ {
RETURN[ [t1.x + t2.x, t1.y + t2.y, t1.z + t2.z] ]; };
DiffTriple: PUBLIC PROCEDURE [t1, t2: Triple] RETURNS [Triple] ~ {
RETURN[ [t1.x - t2.x, t1.y - t2.y, t1.z - t2.z] ]; };
ScaleTriple: PUBLIC PROCEDURE [t: Triple, s: REAL] RETURNS [Triple] ~ {
RETURN[ [t.x * s, t.y * s, t.z * s] ]; };
Normalize: PUBLIC PROC[v: Triple] RETURNS[Triple] ~ {
mag: REAL ← RealFns.SqRt[v.x * v.x + v.y * v.y + v.z * v.z];
IF mag <= 0. THEN mag ← 1.;
RETURN [ [v.x/mag, v.y/mag, v.z/mag] ];
};
DotProd: PUBLIC PROC[v1, v2: Triple] RETURNS [REAL] ~ {
RETURN [v1.x * v2.x + v1.y * v2.y + v1.z * v2.z];
};
CrossProd: PUBLIC PROC[v1, v2: Triple] RETURNS [vOut: Triple] ~ {
vOut.x ← v1.y*v2.z - v1.z*v2.y;
vOut.y ← v1.z*v2.x - v1.x*v2.z;
vOut.z ← v1.x*v2.y - v1.y*v2.x;
};
GetIDTransform: PUBLIC PROC[] RETURNS[id: Transformation3D] ~ {
id.a ← [1., 0., 0., 0.];
id.b ← [0., 1., 0., 0.];
id.c ← [0., 0., 1., 0.];
id.d ← [0., 0., 0., 1.];
};
ConcatT: PUBLIC PROC[xfm1, xfm2: Transformation3D] RETURNS[xfmOut: Transformation3D] ~{
QuadProd: PROC[q1, q2: Quad] RETURNS [REAL] = INLINE {
RETURN [q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w]; };
col2x, col2y, col2z, col2w: Quad;
col2x ← [xfm2.a.x, xfm2.b.x, xfm2.c.x, xfm2.d.x];
col2y ← [xfm2.a.y, xfm2.b.y, xfm2.c.y, xfm2.d.y];
col2z ← [xfm2.a.z, xfm2.b.z, xfm2.c.z, xfm2.d.z];
col2w ← [xfm2.a.w, xfm2.b.w, xfm2.c.w, xfm2.d.w];
xfmOut.a.x ← QuadProd[xfm1.a, col2x];  xfmOut.a.y ← QuadProd[xfm1.a, col2y];
xfmOut.a.z ← QuadProd[xfm1.a, col2z];    xfmOut.a.w ← QuadProd[xfm1.a, col2w];
xfmOut.b.x ← QuadProd[xfm1.b, col2x]; xfmOut.b.y ← QuadProd[xfm1.b, col2y];
xfmOut.b.z ← QuadProd[xfm1.b, col2z];    xfmOut.b.w ← QuadProd[xfm1.b, col2w];
xfmOut.c.x ← QuadProd[xfm1.c, col2x];  xfmOut.c.y ← QuadProd[xfm1.c, col2y];
xfmOut.c.z ← QuadProd[xfm1.c, col2z];    xfmOut.c.w ← QuadProd[xfm1.c, col2w];
xfmOut.d.x ← QuadProd[xfm1.d, col2x]; xfmOut.d.y ← QuadProd[xfm1.d, col2y];
xfmOut.d.z ← QuadProd[xfm1.d, col2z];    xfmOut.d.w ← QuadProd[xfm1.d, col2w];
};
Transform3D: PUBLIC PROC[ vtx: Triple, xfm: Transformation3D] RETURNS [t: Triple] ~ {
t.x ← xfm.a.x * vtx.x + xfm.b.x * vtx.y + xfm.c.x * vtx.z + xfm.d.x;
t.y ← xfm.a.y * vtx.x + xfm.b.y * vtx.y + xfm.c.y * vtx.z + xfm.d.y;
t.z ← xfm.a.z * vtx.x + xfm.b.z * vtx.y + xfm.c.z * vtx.z + xfm.d.z;
};
TransformVec3D: PUBLIC PROC[ vtx: Triple, xfm: Transformation3D] RETURNS [t: Triple] ~ {
t.x ← xfm.a.x * vtx.x + xfm.b.x * vtx.y + xfm.c.x * vtx.z;
t.y ← xfm.a.y * vtx.x + xfm.b.y * vtx.y + xfm.c.y * vtx.z;
t.z ← xfm.a.z * vtx.x + xfm.b.z * vtx.y + xfm.c.z * vtx.z;
};
Translate3D: PUBLIC PROC[ delta: Triple] RETURNS [xfm: Transformation3D] ~ {
xfm ← GetIDTransform[];
xfm.d ← [delta.x, delta.y, delta.z, 1.];
};
Rotate3D: PUBLIC PROC[base, axis: Triple, theta: REAL] RETURNS[Transformation3D] ~ {
xfm, mtx: Transformation3D ← GetIDTransform[];
cosTheta: REAL ← RealFns.CosDeg[theta];
sinTheta: REAL ← RealFns.SinDeg[theta];
xfm.d.x ← -base.x; xfm.d.y ← -base.y; xfm.d.z ← -base.z;
axis ← Normalize[axis];
mtx.a.x ← Sqr[axis.x] + (1.0 - Sqr[axis.x]) * cosTheta;
mtx.b.y ← Sqr[axis.y] + (1.0 - Sqr[axis.y]) * cosTheta;
mtx.c.z ← Sqr[axis.z] + (1.0 - Sqr[axis.z]) * cosTheta;
mtx.b.x ← axis.x * axis.y * (1.0 - cosTheta) + axis.z * sinTheta;
mtx.a.y ← axis.x * axis.y * (1.0 - cosTheta) - axis.z * sinTheta;
mtx.c.x ← axis.x * axis.z * (1.0 - cosTheta) - axis.y * sinTheta;
mtx.a.z ← axis.x * axis.z * (1.0 - cosTheta) + axis.y * sinTheta;
mtx.c.y ← axis.y * axis.z * (1.0 - cosTheta) + axis.x * sinTheta;
mtx.b.z ← axis.y * axis.z * (1.0 - cosTheta) - axis.x * sinTheta;
xfm ← ConcatT[xfm, mtx];
mtx ← GetIDTransform[];
mtx.d.x ← base.x; mtx.d.y ← base.y; mtx.d.z ← base.z;
xfm ← ConcatT[xfm, mtx];
RETURN[xfm];
};
END.