unit ugluMatrix; { Package: OpenGLCore Prefix: glu - OpenGL Utils Beschreibung: diese Unit enthält Matrix-Typen und Methoden um diese zu erstellen und zu manipulieren } {$mode objfpc}{$H+} interface uses Classes, SysUtils, ugluVector; type //Matrixtypen TgluMatrix2ub = array[0..1] of TgluVector2ub; TgluMatrix2i = array[0..1] of TgluVector2i; TgluMatrix2f = array[0..1] of TgluVector2f; TgluMatrix2d = array[0..1] of TgluVector2d; TgluMatrix3ub = array[0..2] of TgluVector3ub; TgluMatrix3i = array[0..2] of TgluVector3i; TgluMatrix3f = array[0..2] of TgluVector3f; TgluMatrix3d = array[0..2] of TgluVector3d; TgluMatrix4ub = array[0..3] of TgluVector4ub; TgluMatrix4i = array[0..3] of TgluVector4i; TgluMatrix4f = array[0..3] of TgluVector4f; TgluMatrix4d = array[0..3] of TgluVector4d; //MatrixPointer PgluMatrix2ub = ^TgluMatrix2ub; PgluMatrix2i = ^TgluMatrix2i; PgluMatrix2f = ^TgluMatrix2f; PgluMatrix2d = ^TgluMatrix2d; PgluMatrix3ub = ^TgluMatrix3ub; PgluMatrix3i = ^TgluMatrix3i; PgluMatrix3f = ^TgluMatrix3f; PgluMatrix3d = ^TgluMatrix3d; PgluMatrix4ub = ^TgluMatrix4ub; PgluMatrix4i = ^TgluMatrix4i; PgluMatrix4f = ^TgluMatrix4f; PgluMatrix4d = ^TgluMatrix4d; //Konstructoren function gluMatrix4d(const m: TgluMatrix4f): TgluMatrix4d; //Matrixfunktionen function gluMatrixTranslate(const v: TgluVector3f): TgluMatrix4f; function gluMatrixScale(const v: TgluVector3f): TgluMatrix4f; overload; function gluMatrixScale(const s: Single): TgluMatrix4f; overload; function gluMatrixRotate(axis: TgluVector3f; const angle: Single): TgluMatrix4f; function gluMatrixMult(const m1, m2: TgluMatrix4f): TgluMatrix4f; function gluMatrixMultVec(const m: TgluMatrix4f; const v: TgluVector4f): TgluVector4f; function gluMatrixTranspose(const m: TgluMatrix3f): TgluMatrix3f; overload; function gluMatrixTranspose(const m: TgluMatrix4f): TgluMatrix4f; overload; function gluMatrixSubMatrix(const m:TgluMatrix4f; const s, z: Integer): TgluMatrix3f; function gluMatrixDeterminant(const m: TgluMatrix3f): Single; overload; function gluMatrixDeterminant(const m: TgluMatrix4f): Single; overload; function gluMatrixAdjoint(const m: TgluMatrix4f): TgluMatrix4f; function gluMatrixInvert(const m: TgluMatrix4f): TgluMatrix4f; operator * (const m1, m2: TgluMatrix4f): TgluMatrix4f; operator * (const m: TgluMatrix4f; const v: TgluVector4f): TgluVector4f; operator * (const m: TgluMatrix4f; const v: TgluVector3f): TgluVector3f; const maAxisX = 0; maAxisY = 1; maAxisZ = 2; maPos = 3; gluMatrixIdentity: TgluMatrix4f = ((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1)); implementation uses Math; operator * (const m1, m2: TgluMatrix4f): TgluMatrix4f; begin result := gluMatrixMult(m1, m2); end; operator * (const m: TgluMatrix4f; const v: TgluVector4f): TgluVector4f; begin result := gluMatrixMultVec(m, v); end; operator * (const m: TgluMatrix4f; const v: TgluVector3f): TgluVector3f; begin result := gluVector3f(gluMatrixMultVec(m, gluVEctor4f(v, 1.0))); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function gluMatrix4d(const m: TgluMatrix4f): TgluMatrix4d; var i, j: Integer; begin for i := 0 to 3 do for j := 0 to 3 do result[i, j] := m[i, j]; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //erstellt eine Translationsmatrix //@v: Vektor der Translationsmatrix; function gluMatrixTranslate(const v: TgluVector3f): TgluMatrix4f; var i: Integer; begin result := gluMatrixIdentity; for i := 0 to 2 do result[3, i] := v[i]; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //erstellt eine Skalierungsmatrix //@v: Vektor der Skalierungsmatrix; function gluMatrixScale(const v: TgluVector3f): TgluMatrix4f; var i: Integer; begin result := gluMatrixIdentity; for i := 0 to 2 do result[i, i] := v[i]; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function gluMatrixScale(const s: Single): TgluMatrix4f; var i: Integer; begin result := gluMatrixIdentity; for i := 0 to 2 do result[i, i] := s; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //erstellt eine Rotationsmatrix; //@axis: Achse um die gedreht werden soll; //@angle: Winkel mit dem gedreht werden soll; function gluMatrixRotate(axis: TgluVector3f; const angle: Single): TgluMatrix4f; var X, Y, Z, a, s, c: Single; begin axis := gluVectorNormalize(axis); X := axis[0]; Y := axis[1]; Z := axis[2]; a := angle/180*Pi; s := sin(a); c := cos(a); result := gluMatrixIdentity; result[maAxisX] := gluVector4f( SQR(X) + (1-SQR(X))*c, X*Y*(1-c) + Z*s, X*Z*(1-c) - Y*s, 0); result[maAxisY] := gluVector4f( X*Y*(1-c) - Z*s, SQR(Y) + (1-SQR(Y))*c, Y*Z*(1-c) + X*s, 0); result[maAxisZ] := gluVector4f( X*Z*(1-c) + Y*s, Y*Z*(1-c) - X*s, SQR(Z) + (1-SQR(Z))*c, 0); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Mutlipliziert Matrix1 mit Matrix2 //@Matrix1: 1. Multiplikator; //@Matrix2: 2. Multiplikator; //@result: Matrix1 * Matrix2 function gluMatrixMult(const m1, m2: TgluMatrix4f): TgluMatrix4f; var x, y, i: Integer; sum: Single; begin for x := 0 to 3 do begin for y := 0 to 3 do begin sum := 0; for i := 0 to 3 do sum := sum + m1[i, y] * m2[x, i]; result[x, y] := sum; end; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Multiplizerit eine Matrix mit einem Vektor //@m: Matrix mit der multipliziert werden soll; //@v: Vektor mit dem multipliziert werden soll; //@result: Ergebnis der Multiplikation function gluMatrixMultVec(const m: TgluMatrix4f; const v: TgluVector4f): TgluVector4f; var i, j: Integer; sum: Single; begin for i := 0 to 3 do begin sum := 0; for j := 0 to 3 do sum := sum + m[j,i] * v[j]; result[i] := sum; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //berechnet die Transponierte Matrix //@m: Matrix die Transponiert werden soll; //@result: Transponierte Matrix; function gluMatrixTranspose(const m: TgluMatrix3f): TgluMatrix3f; var i, j: Integer; begin for i := 0 to 2 do for j := 0 to 2 do result[i, j] := m[j, i]; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //berechnet die Transponierte Matrix //@m: Matrix die Transponiert werden soll; //@result: Transponierte Matrix; function gluMatrixTranspose(const m: TgluMatrix4f): TgluMatrix4f; var i, j: Integer; begin for i := 0 to 3 do for j := 0 to 3 do result[i, j] := m[j, i]; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //ermittelt die Untermatrix einer Matrix //@m: Matrix derren Untermatrix berechnet werden soll; //@s: Spalte die gelöscht werden soll; //@z: Zeile die gelöscht werden soll; //@result: Untermatrix von m function gluMatrixSubMatrix(const m: TgluMatrix4f; const s, z: Integer): TgluMatrix3f; var x, y, i, j: Integer; begin for i := 0 to 2 do for j := 0 to 2 do begin x := i; y := j; if (i >= s) then inc(x); if (j >= z) then inc(y); result[i, j] := m[x, y]; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //berechnet die Determinante einer Matrix //@m: Matrix derren Determinaten berechnet werden soll; //@result: Determinante von m function gluMatrixDeterminant(const m: TgluMatrix3f): Single; begin result := m[0,0] * m[1,1] * m[2,2] + m[1,0] * m[2,1] * m[0,2] + m[2,0] * m[0,1] * m[1,2] - m[2,0] * m[1,1] * m[0,2] - m[1,0] * m[0,1] * m[2,2] - m[0,0] * m[2,1] * m[1,2]; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //berechnet die Determinante einer Matrix //@m: Matrix derren Determinaten berechnet werden soll; //@result: Determinante von m function gluMatrixDeterminant(const m: TgluMatrix4f): Single; var i: Integer; begin result := 0; for i := 0 to 3 do result := result + power(-1, i) * m[i, 0] * gluMatrixDeterminant(gluMatrixSubMatrix(m, i, 0)); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //berechnet die Adjunkte einer Matrix //@m: Matrix derren Adjunkte berechnet werden soll; //@result: Adjunkte von m function gluMatrixAdjoint(const m: TgluMatrix4f): TgluMatrix4f; var i, j: Integer; begin for i := 0 to 3 do for j := 0 to 3 do result[i, j] := power(-1, i+j) * gluMatrixDeterminant(gluMatrixSubMatrix(m, i, j)); result := gluMatrixTranspose(result); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //berechnet die inverse Matrix einer Matrix //@m: Matrix derren Inverse berechnet werden soll; //@result: Inverse Matrix von m; function gluMatrixInvert(const m: TgluMatrix4f): TgluMatrix4f; var d: Single; i, j: Integer; begin d := gluMatrixDeterminant(m); result := gluMatrixAdjoint(m); for i := 0 to 3 do for j := 0 to 3 do result[i,j] := result[i,j] / d; end; end.