You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
10 KiB

  1. unit ugluMatrix;
  2. { Package: OpenGLCore
  3. Prefix: glu - OpenGL Utils
  4. Beschreibung: diese Unit enthält Matrix-Typen und Methoden um diese zu erstellen und zu manipulieren }
  5. {$mode objfpc}{$H+}
  6. interface
  7. uses
  8. Classes, SysUtils, ugluVector;
  9. type
  10. //Matrixtypen
  11. TgluMatrix2ub = array[0..1] of TgluVector2ub;
  12. TgluMatrix2i = array[0..1] of TgluVector2i;
  13. TgluMatrix2f = array[0..1] of TgluVector2f;
  14. TgluMatrix2d = array[0..1] of TgluVector2d;
  15. TgluMatrix3ub = array[0..2] of TgluVector3ub;
  16. TgluMatrix3i = array[0..2] of TgluVector3i;
  17. TgluMatrix3f = array[0..2] of TgluVector3f;
  18. TgluMatrix3d = array[0..2] of TgluVector3d;
  19. TgluMatrix4ub = array[0..3] of TgluVector4ub;
  20. TgluMatrix4i = array[0..3] of TgluVector4i;
  21. TgluMatrix4f = array[0..3] of TgluVector4f;
  22. TgluMatrix4d = array[0..3] of TgluVector4d;
  23. //MatrixPointer
  24. PgluMatrix2ub = ^TgluMatrix2ub;
  25. PgluMatrix2i = ^TgluMatrix2i;
  26. PgluMatrix2f = ^TgluMatrix2f;
  27. PgluMatrix2d = ^TgluMatrix2d;
  28. PgluMatrix3ub = ^TgluMatrix3ub;
  29. PgluMatrix3i = ^TgluMatrix3i;
  30. PgluMatrix3f = ^TgluMatrix3f;
  31. PgluMatrix3d = ^TgluMatrix3d;
  32. PgluMatrix4ub = ^TgluMatrix4ub;
  33. PgluMatrix4i = ^TgluMatrix4i;
  34. PgluMatrix4f = ^TgluMatrix4f;
  35. PgluMatrix4d = ^TgluMatrix4d;
  36. //Konstructoren
  37. function gluMatrix4d(const m: TgluMatrix4f): TgluMatrix4d;
  38. //Matrixfunktionen
  39. function gluMatrixTranslate(const v: TgluVector3f): TgluMatrix4f;
  40. function gluMatrixScale(const v: TgluVector3f): TgluMatrix4f; overload;
  41. function gluMatrixScale(const s: Single): TgluMatrix4f; overload;
  42. function gluMatrixRotate(axis: TgluVector3f; const angle: Single): TgluMatrix4f;
  43. function gluMatrixMult(const m1, m2: TgluMatrix4f): TgluMatrix4f;
  44. function gluMatrixMultVec(const m: TgluMatrix4f; const v: TgluVector4f): TgluVector4f;
  45. function gluMatrixTranspose(const m: TgluMatrix3f): TgluMatrix3f; overload;
  46. function gluMatrixTranspose(const m: TgluMatrix4f): TgluMatrix4f; overload;
  47. function gluMatrixSubMatrix(const m:TgluMatrix4f; const s, z: Integer): TgluMatrix3f;
  48. function gluMatrixDeterminant(const m: TgluMatrix3f): Single; overload;
  49. function gluMatrixDeterminant(const m: TgluMatrix4f): Single; overload;
  50. function gluMatrixAdjoint(const m: TgluMatrix4f): TgluMatrix4f;
  51. function gluMatrixInvert(const m: TgluMatrix4f): TgluMatrix4f;
  52. operator * (const m1, m2: TgluMatrix4f): TgluMatrix4f;
  53. operator * (const m: TgluMatrix4f; const v: TgluVector4f): TgluVector4f;
  54. operator * (const m: TgluMatrix4f; const v: TgluVector3f): TgluVector3f;
  55. const
  56. maAxisX = 0;
  57. maAxisY = 1;
  58. maAxisZ = 2;
  59. maPos = 3;
  60. gluMatrixIdentity: TgluMatrix4f = ((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1));
  61. implementation
  62. uses
  63. Math;
  64. operator * (const m1, m2: TgluMatrix4f): TgluMatrix4f;
  65. begin
  66. result := gluMatrixMult(m1, m2);
  67. end;
  68. operator * (const m: TgluMatrix4f; const v: TgluVector4f): TgluVector4f;
  69. begin
  70. result := gluMatrixMultVec(m, v);
  71. end;
  72. operator * (const m: TgluMatrix4f; const v: TgluVector3f): TgluVector3f;
  73. begin
  74. result := gluVector3f(gluMatrixMultVec(m, gluVEctor4f(v, 1.0)));
  75. end;
  76. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  77. function gluMatrix4d(const m: TgluMatrix4f): TgluMatrix4d;
  78. var
  79. i, j: Integer;
  80. begin
  81. for i := 0 to 3 do
  82. for j := 0 to 3 do
  83. result[i, j] := m[i, j];
  84. end;
  85. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  86. //erstellt eine Translationsmatrix
  87. //@v: Vektor der Translationsmatrix;
  88. function gluMatrixTranslate(const v: TgluVector3f): TgluMatrix4f;
  89. var
  90. i: Integer;
  91. begin
  92. result := gluMatrixIdentity;
  93. for i := 0 to 2 do
  94. result[3, i] := v[i];
  95. end;
  96. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. //erstellt eine Skalierungsmatrix
  98. //@v: Vektor der Skalierungsmatrix;
  99. function gluMatrixScale(const v: TgluVector3f): TgluMatrix4f;
  100. var
  101. i: Integer;
  102. begin
  103. result := gluMatrixIdentity;
  104. for i := 0 to 2 do
  105. result[i, i] := v[i];
  106. end;
  107. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  108. function gluMatrixScale(const s: Single): TgluMatrix4f;
  109. var
  110. i: Integer;
  111. begin
  112. result := gluMatrixIdentity;
  113. for i := 0 to 2 do
  114. result[i, i] := s;
  115. end;
  116. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  117. //erstellt eine Rotationsmatrix;
  118. //@axis: Achse um die gedreht werden soll;
  119. //@angle: Winkel mit dem gedreht werden soll;
  120. function gluMatrixRotate(axis: TgluVector3f; const angle: Single): TgluMatrix4f;
  121. var
  122. X, Y, Z, a, s, c: Single;
  123. begin
  124. axis := gluVectorNormalize(axis);
  125. X := axis[0];
  126. Y := axis[1];
  127. Z := axis[2];
  128. a := angle/180*Pi;
  129. s := sin(a);
  130. c := cos(a);
  131. result := gluMatrixIdentity;
  132. result[maAxisX] := gluVector4f(
  133. SQR(X) + (1-SQR(X))*c,
  134. X*Y*(1-c) + Z*s,
  135. X*Z*(1-c) - Y*s,
  136. 0);
  137. result[maAxisY] := gluVector4f(
  138. X*Y*(1-c) - Z*s,
  139. SQR(Y) + (1-SQR(Y))*c,
  140. Y*Z*(1-c) + X*s,
  141. 0);
  142. result[maAxisZ] := gluVector4f(
  143. X*Z*(1-c) + Y*s,
  144. Y*Z*(1-c) - X*s,
  145. SQR(Z) + (1-SQR(Z))*c,
  146. 0);
  147. end;
  148. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  149. //Mutlipliziert Matrix1 mit Matrix2
  150. //@Matrix1: 1. Multiplikator;
  151. //@Matrix2: 2. Multiplikator;
  152. //@result: Matrix1 * Matrix2
  153. function gluMatrixMult(const m1, m2: TgluMatrix4f): TgluMatrix4f;
  154. var
  155. x, y, i: Integer;
  156. sum: Single;
  157. begin
  158. for x := 0 to 3 do begin
  159. for y := 0 to 3 do begin
  160. sum := 0;
  161. for i := 0 to 3 do
  162. sum := sum + m1[i, y] * m2[x, i];
  163. result[x, y] := sum;
  164. end;
  165. end;
  166. end;
  167. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  168. //Multiplizerit eine Matrix mit einem Vektor
  169. //@m: Matrix mit der multipliziert werden soll;
  170. //@v: Vektor mit dem multipliziert werden soll;
  171. //@result: Ergebnis der Multiplikation
  172. function gluMatrixMultVec(const m: TgluMatrix4f; const v: TgluVector4f): TgluVector4f;
  173. var
  174. i, j: Integer;
  175. sum: Single;
  176. begin
  177. for i := 0 to 3 do begin
  178. sum := 0;
  179. for j := 0 to 3 do
  180. sum := sum + m[j,i] * v[j];
  181. result[i] := sum;
  182. end;
  183. end;
  184. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  185. //berechnet die Transponierte Matrix
  186. //@m: Matrix die Transponiert werden soll;
  187. //@result: Transponierte Matrix;
  188. function gluMatrixTranspose(const m: TgluMatrix3f): TgluMatrix3f;
  189. var
  190. i, j: Integer;
  191. begin
  192. for i := 0 to 2 do
  193. for j := 0 to 2 do
  194. result[i, j] := m[j, i];
  195. end;
  196. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  197. //berechnet die Transponierte Matrix
  198. //@m: Matrix die Transponiert werden soll;
  199. //@result: Transponierte Matrix;
  200. function gluMatrixTranspose(const m: TgluMatrix4f): TgluMatrix4f;
  201. var
  202. i, j: Integer;
  203. begin
  204. for i := 0 to 3 do
  205. for j := 0 to 3 do
  206. result[i, j] := m[j, i];
  207. end;
  208. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  209. //ermittelt die Untermatrix einer Matrix
  210. //@m: Matrix derren Untermatrix berechnet werden soll;
  211. //@s: Spalte die gelöscht werden soll;
  212. //@z: Zeile die gelöscht werden soll;
  213. //@result: Untermatrix von m
  214. function gluMatrixSubMatrix(const m: TgluMatrix4f; const s, z: Integer): TgluMatrix3f;
  215. var
  216. x, y, i, j: Integer;
  217. begin
  218. for i := 0 to 2 do
  219. for j := 0 to 2 do begin
  220. x := i;
  221. y := j;
  222. if (i >= s) then
  223. inc(x);
  224. if (j >= z) then
  225. inc(y);
  226. result[i, j] := m[x, y];
  227. end;
  228. end;
  229. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  230. //berechnet die Determinante einer Matrix
  231. //@m: Matrix derren Determinaten berechnet werden soll;
  232. //@result: Determinante von m
  233. function gluMatrixDeterminant(const m: TgluMatrix3f): Single;
  234. begin
  235. result :=
  236. m[0,0] * m[1,1] * m[2,2] +
  237. m[1,0] * m[2,1] * m[0,2] +
  238. m[2,0] * m[0,1] * m[1,2] -
  239. m[2,0] * m[1,1] * m[0,2] -
  240. m[1,0] * m[0,1] * m[2,2] -
  241. m[0,0] * m[2,1] * m[1,2];
  242. end;
  243. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  244. //berechnet die Determinante einer Matrix
  245. //@m: Matrix derren Determinaten berechnet werden soll;
  246. //@result: Determinante von m
  247. function gluMatrixDeterminant(const m: TgluMatrix4f): Single;
  248. var
  249. i: Integer;
  250. begin
  251. result := 0;
  252. for i := 0 to 3 do
  253. result := result + power(-1, i) * m[i, 0] * gluMatrixDeterminant(gluMatrixSubMatrix(m, i, 0));
  254. end;
  255. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  256. //berechnet die Adjunkte einer Matrix
  257. //@m: Matrix derren Adjunkte berechnet werden soll;
  258. //@result: Adjunkte von m
  259. function gluMatrixAdjoint(const m: TgluMatrix4f): TgluMatrix4f;
  260. var
  261. i, j: Integer;
  262. begin
  263. for i := 0 to 3 do
  264. for j := 0 to 3 do
  265. result[i, j] := power(-1, i+j) * gluMatrixDeterminant(gluMatrixSubMatrix(m, i, j));
  266. result := gluMatrixTranspose(result);
  267. end;
  268. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  269. //berechnet die inverse Matrix einer Matrix
  270. //@m: Matrix derren Inverse berechnet werden soll;
  271. //@result: Inverse Matrix von m;
  272. function gluMatrixInvert(const m: TgluMatrix4f): TgluMatrix4f;
  273. var
  274. d: Single;
  275. i, j: Integer;
  276. begin
  277. d := gluMatrixDeterminant(m);
  278. result := gluMatrixAdjoint(m);
  279. for i := 0 to 3 do
  280. for j := 0 to 3 do
  281. result[i,j] := result[i,j] / d;
  282. end;
  283. end.