<> <> <> <> <<[nx ox ax px] where n = [nx ny nz]T is the "normal" column vector,>> <<[ny oy ay py] o = [ox oy oz]T is the "orthogonal" column vector>> <<[nz oz az pz] a = [ax ay az]T is the "axial" column vector,>> <<[0 0 0 1] and p = [px, py, pz]T is the "position" column >> <> DIRECTORY SV2d, SV3d, SVVector3d; SVMatrix3d: CEDAR DEFINITIONS = BEGIN Matrix4by4: TYPE = SV3d.Matrix4by4; Plane: TYPE = SV3d.Plane; Point3d: TYPE = SV3d.Point3d; Point2d: TYPE = SV2d.Point2d; Vector3d: TYPE = SVVector3d.Vector3d; Identity: PROC [] RETURNS [identityMat: Matrix4by4]; Update: PROC [point: Point3d, mat: Matrix4by4] RETURNS [newPoint: Point3d]; UpdateDisplacement: PROC [mat: Matrix4by4, vec: Vector3d] RETURNS [newVec: Vector3d]; <> UpdateVectorWithInverse: PROC [inverse: Matrix4by4, vec: Vector3d] RETURNS [newVec: Vector3d]; <> UpdateVectorComputeInverse: PROC [vec: Vector3d, mat: Matrix4by4] RETURNS [newVec: Vector3d]; UpdateVectorEvenScaling: PROC [vec: Vector3d, mat: Matrix4by4] RETURNS [newVec: Vector3d]; UpdatePlaneWithInverse: PROC [plane: Plane, inverse: Matrix4by4] RETURNS [newPlane: Plane]; UpdatePlaneComputeInverse: PROC [plane: Plane, mat: Matrix4by4] RETURNS [newPlane: Plane]; PerspectiveTrans: PROC [oldPoint: Point3d, focalDistance: REAL _ 1800] RETURNS [newPoint: Point2d]; IllegalDepth: SIGNAL; <> Scale: PROC [mat: Matrix4by4, sx, sy, sz: REAL] RETURNS [transMat: Matrix4by4]; Translate: PROC [mat: Matrix4by4, dx, dy, dz: REAL] RETURNS [transMat: Matrix4by4]; Rotate: PROC [mat: Matrix4by4, axis: [1..3], degrees: REAL] RETURNS [transMat: Matrix4by4]; <> RotateX: PROC [mat: Matrix4by4, degrees: REAL] RETURNS [transMat: Matrix4by4]; RotateY: PROC [mat: Matrix4by4, degrees: REAL] RETURNS [transMat: Matrix4by4]; RotateZ: PROC [mat: Matrix4by4, degrees: REAL] RETURNS [transMat: Matrix4by4]; RotateAxis: PROC [mat: Matrix4by4, axis: Vector3d, degrees: REAL] RETURNS [transMat: Matrix4by4]; SetOrigin: PROC [mat: Matrix4by4, origin: Point3d] RETURNS [newMat: Matrix4by4]; <> <> LocalScale: PROC [mat: Matrix4by4, sx, sy, sz: REAL] RETURNS [transMat: Matrix4by4]; LocalTranslate: PROC [mat: Matrix4by4, dx, dy, dz: REAL] RETURNS [transMat: Matrix4by4]; LocalRotate: PROC [mat: Matrix4by4, axis: [1..3], degrees: REAL] RETURNS [transMat: Matrix4by4]; <> LocalRotateX: PROC [mat: Matrix4by4, degrees: REAL] RETURNS [transMat: Matrix4by4]; LocalRotateY: PROC [mat: Matrix4by4, degrees: REAL] RETURNS [transMat: Matrix4by4]; LocalRotateZ: PROC [mat: Matrix4by4, degrees: REAL] RETURNS [transMat: Matrix4by4]; LocalRotateAxis: PROC [mat: Matrix4by4, axis: Vector3d, degrees: REAL] RETURNS [transMat: Matrix4by4]; << The next six procedures allow the user direct access to the transform matrices and their manipulation. >> MatMult: PROC [left, right: Matrix4by4] RETURNS [transMat: Matrix4by4]; <> Mult: PROC [ab, bc: Matrix4by4] RETURNS [ac: Matrix4by4]; <> Cat: PROC [ab, bc, cd: Matrix4by4] RETURNS [ad: Matrix4by4]; <> <<>> MakeScaleMat: PROC [sx, sy, sz: REAL] RETURNS [scale: Matrix4by4]; MakeTranslateMat: PROC [dx, dy, dz: REAL] RETURNS [trans: Matrix4by4]; MakeRotateMat: PROC [axis: [1..3], degrees: REAL] RETURNS [rotMat: Matrix4by4]; MakeRotateXMat: PROC [degrees: REAL] RETURNS [rotx: Matrix4by4]; MakeRotateYMat: PROC [degrees: REAL] RETURNS [roty: Matrix4by4]; MakeRotateZMat: PROC [degrees: REAL] RETURNS [rotz: Matrix4by4]; MakeRotateAxisMat: PROC [axis: Vector3d, degrees: REAL] RETURNS [rotMat: Matrix4by4]; MakeMatFromZandXAxis: PROC [zAxis, xAxis: Vector3d, origin: Point3d] RETURNS [mat: Matrix4by4]; MakeMatFromYandXAxis: PROC [yAxis, xAxis: Vector3d, origin: Point3d] RETURNS [mat: Matrix4by4]; <> MakeHorizontalMatFromZAxis: PROC [zAxis: Vector3d, origin: Point3d] RETURNS [mat: Matrix4by4]; <> MakeMatFromAxes: PROC [xAxis, yAxis, zAxis: Vector3d, origin: Point3d] RETURNS [mat: Matrix4by4]; <> ScaleFromMatrix: PROC [mat: Matrix4by4] RETURNS [sx, sy, sz: REAL]; <> OriginOfMatrix: PROC [mat: Matrix4by4] RETURNS [origin: Point3d]; XAxisOfMatrix: PROC [mat: Matrix4by4] RETURNS [xAxis: Vector3d]; YAxisOfMatrix: PROC [mat: Matrix4by4] RETURNS [yAxis: Vector3d]; ZAxisOfMatrix: PROC [mat: Matrix4by4] RETURNS [zAxis: Vector3d]; << Because of the orthogonality of the transform matrices, matrix inversion is relatively easy.>> InverseNoScaling: PROC [mat: Matrix4by4] RETURNS [inverse: Matrix4by4]; DegenerateInverse: SIGNAL; <> Cofactor: PROC [mat: Matrix4by4, row, col: NAT] RETURNS [cof: REAL]; <> Determinant: PROC [mat: Matrix4by4] RETURNS [det: REAL]; Transpose: PROC [mat: Matrix4by4] RETURNS [MatT: Matrix4by4]; <> Inverse: PROC [mat: Matrix4by4] RETURNS [inverse: Matrix4by4]; <> << Once you can create and manipulate objects in the world (reference) coordinate system, it is useful to be able to express one coordinate system in terms of another. Consider a solar system example. If you have the center of the sun as world coordinate system, and earth and moon, as two other coordinate system expressed in terms of world coordinates (recall that a 4 by 4 matrix represents the relationship between coordinate systems), then if you want the moon to rotate around the earth, you might try:>> << MoonInTermsOfEarth _ WorldToLocal[earth,moon]; FOREVER DO: MoonInTermsOfEarth _ RotateAboutY[MoonInTermsOfEarth, degrees]; moon _ MatMult[earth, MoonInTermsOfEarth]; DrawSphereCenteredAt[moon]; ENDLOOP;>> AInTermsOfB: PROC [aWORLD, bWORLD: Matrix4by4] RETURNS [ab: Matrix4by4]; <> UnitNormalize: PROC [mat: Matrix4by4] RETURNS [unitMat: Matrix4by4]; <> Normalize: PROC [mat: Matrix4by4] RETURNS [normMat: Matrix4by4]; <> NormalizeUniformScale: PROC [mat: Matrix4by4] RETURNS [normMat: Matrix4by4]; <> NormalizeNoRotation: PROC [mat: Matrix4by4] RETURNS [normMat: Matrix4by4]; <> NormalizeNoTranslation: PROC [mat: Matrix4by4] RETURNS [normMat: Matrix4by4]; <> TidyUpVector: PROC [vec: Vector3d] RETURNS [fixedVec: Vector3d]; <> TidyUpMatrix: PROC [mat: Matrix4by4] RETURNS [fixedMat: Matrix4by4]; <> END.