-- File: SVMatrix2d.mesa
-- Last edited by Bier on December 18, 1982 1:05 am
-- Author: Eric Bier on November 18, 1982 8:40 pm
-- Contents: My own package for manipulating Homogenous 3 x 3 matrices. Parallels Matrix3d in many places

DIRECTORY
 SV2d,
 SVVector2d;

SVMatrix2d: DEFINITIONS =
BEGIN

Matrix3by3: TYPE = ARRAY [1..3] OF ARRAY [1..3] OF REAL;
Point2d: TYPE = SV2d.Point2d;
Vector2d: TYPE = SVVector2d.Vector2d;

Identity: PROC [] RETURNS [identityMat: Matrix3by3];

Update: PROC [mat: Matrix3by3, point: Point2d] RETURNS [newPoint: Point2d];
UpdateVector: PROC [mat: Matrix3by3, vec: Vector2d] RETURNS [newVec: Vector2d];
-- vectors can be rotated and scaled, but not translated

-- The next three procedures perform an efficient matrix multiplication as though mat were being multiplied to its left (a transform in reference coordinates) by a matrix which translates or rotates respectively (See Paul).
Scale: PROC [mat: Matrix3by3, sx, sy: REAL] RETURNS [transMat: Matrix3by3];
Translate: PROC [mat: Matrix3by3, dx, dy: REAL] RETURNS [transMat: Matrix3by3];
RotateCCW: PROC [mat: Matrix3by3, degrees: REAL] RETURNS [transMat: Matrix3by3];

-- The next three procedures perform an efficient matrix multiplication as though mat were being multiplied on its right (a transform in local coordinates) by a matrix which translates or rotates respectively (See Paul).
LocalScale: PROC [mat: Matrix3by3, sx, sy: REAL] RETURNS [transMat: Matrix3by3];
LocalTranslate: PROC [mat: Matrix3by3, dx, dy: REAL] RETURNS [transMat: Matrix3by3];
LocalRotateCCW: PROC [mat: Matrix3by3, degrees: REAL] RETURNS [transMat: Matrix3by3];


MatMult: PROC [left, right: Matrix3by3] RETURNS [transMat: Matrix3by3];
-- MatMult is almost a general 3 by 3 matrix operation. However, it assumes that the last row of each matrix is [0 0 1].

MakeScaleMat: PROC [sx, sy: REAL] RETURNS [scale: Matrix3by3];
MakeTranslateMat: PROC [dx, dy: REAL] RETURNS [trans: Matrix3by3];
MakeRotateCCWMat: PROC [degrees: REAL] RETURNS [rot: Matrix3by3];

MakeMatFromXAxis: PROC [xAxis: Vector2d, origin: Point2d] RETURNS [mat: Matrix3by3];
-- not yet implemented
MakeMatFromYAxis: PROC [yAxis: Vector2d, origin: Point2d] RETURNS [mat: Matrix3by3];
-- not yet implemented
MakeMatFromAxes: PROC [xAxis, yAxis: Vector2d, origin: Point2d] RETURNS [mat: Matrix3by3];
-- uses the axes directly. Doesn't even check to see if they are orthogonal

ScaleFromMatrix: PROC [mat: Matrix3by3] RETURNS [sx, sy: REAL];
-- finds out how much this matrix will scale an object it is applied to
OriginOfMatrix: PROC [mat: Matrix3by3] RETURNS [origin: Point2d];
XAxisOfMatrix: PROC [mat: Matrix3by3] RETURNS [xAxis: Vector2d];
YAxisOfMatrix: PROC [mat: Matrix3by3] RETURNS [yAxis: Vector2d];
RotationOfMatrix: PROC [mat: Matrix3by3] RETURNS [degrees: REAL];

Cofactor: PROC [mat: Matrix3by3, row, col: NAT] RETURNS [cof: REAL];
Determinant: PROC [mat: Matrix3by3] RETURNS [det: REAL];
Transpose: PROC [mat: Matrix3by3] RETURNS [MatT: Matrix3by3];
Inverse: PROC [mat: Matrix3by3] RETURNS [inverse: Matrix3by3];
-- inverts any matrix of the given form (even with scaling)
DegenerateInverse: SIGNAL;

WorldToLocal: PROC [AinWorld,BinWorld: Matrix3by3] RETURNS [BinTermsOfA: Matrix3by3];

END.