NewtonCustomJoints_Math.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:17k
源码类别:

2D图形编程

开发平台:

Delphi

  1. {*******************************************************************************}
  2. {                                                                               }
  3. {      Math helper unit for NewtonCustomJoints.pas                              }
  4. {                                                                               }
  5. {      Copyright (c) 2005,06 Sascha Willems                                     }
  6. {                                                                               }
  7. {*******************************************************************************}
  8. {                                                                               }
  9. { License :                                                                     }
  10. {                                                                               }
  11. {  The contents of this file are used with permission, subject to               }
  12. {  the Mozilla Public License Version 1.1 (the "License"); you may              }
  13. {  not use this file except in compliance with the License. You may             }
  14. {  obtain a copy of the License at                                              }
  15. {  http://www.mozilla.org/MPL/MPL-1.1.html                                      }
  16. {                                                                               }
  17. {  Software distributed under the License is distributed on an                  }
  18. {  "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or               }
  19. {  implied. See the License for the specific language governing                 }
  20. {  rights and limitations under the License.                                    }
  21. {                                                                               }
  22. {*******************************************************************************}
  23. unit NewtonCustomJoints_Math;
  24. interface
  25. uses
  26.  Math;
  27. type
  28.  TMatrix4f = array[0..3, 0..3] of Single;
  29.  TMatrix4d = array[0..3, 0..3] of Double;
  30.  TVector3f = array[0..2] of Single;
  31.  TVector4f = array[0..3] of Single;
  32. var
  33.  NullMatrix4f   : TMatrix4f = ((0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0));
  34.  IdentityMatrix : TMatrix4f = ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1));
  35.  ZeroVector     : TVector3f = (0, 0, 0);
  36. const
  37.   X = 0;
  38.   Y = 1;
  39.   Z = 2;
  40.   W = 3;
  41.   Epsilon = 0.0001;
  42. function  Matrix_Multiply(m1 : TMatrix4f; m2 : TMatrix4f) : TMatrix4f;
  43. procedure Matrix_SetIdentity(var M : TMatrix4f);
  44. procedure Matrix_SetTransform(var M : TMatrix4f; V : TVector3f);
  45. procedure Matrix_SetRotation(var M : TMatrix4f; V : TVector3f);
  46. procedure Matrix_RotateVect(const M : TMatrix4f; var pVect : TVector3f);
  47. procedure Matrix_Inverse(var M: TMatrix4f);
  48. function  Matrix_TansformVector(const M : TMatrix4f; V : TVector3f) : TVector3f;
  49. function  Matrix_UntransformVector(const M : TMatrix4f; V : TVector3f) : TVector3f;
  50. function  Matrix_UnRotateVect(const M : TMatrix4f; pVect : TVector3f) : TVector3f;
  51. procedure Matrix_SetColumn(var M : TMatrix4f; pColumn : Byte;pVect : TVector4f);
  52. function V4(x,y,z : Single) : TVector4f; overload;
  53. function V4(x,y,z,w : Single) : TVector4f; overload;
  54. function V4(pV3 : TVector3f; w : Single) : TVector4f; overload;
  55. function V4(pMatrix : TMatrix4f; pC : Integer) : TVector4f; overload;
  56. function V3(x,y,z : Single) : TVector3f; overload;
  57. function V3(pMatrix : TMatrix4f; pC : Integer) : TVector3f; overload;
  58. function VCross(pV1, pV2 : TVector3f) : TVector3f; overload;
  59. function VCross(pV1, pV2 : TVector4f) : TVector4f; overload;
  60. function VDot(pV1, pV2 : TVector3f) : Single; overload;
  61. function VDot(pV1, pV2 : TVector4f) : Single; overload;
  62. function VTransform(pV1 : TVector3f; pM : TMatrix4f) : TVector3f;
  63. function VSub(pV1, pV2 : TVector3f) : TVector3f; overload;
  64. function VSub(pV1, pV2 : TVector4f) : TVector4f; overload;
  65. function VAdd(pV1, pV2 : TVector3f) : TVector3f; overload;
  66. function VAdd(pV1, pV2 : TVector4f) : TVector4f; overload;
  67. function VNormalize(pV : TVector3f) : TVector3f;
  68. function VScale(pV : TVector3f; pScale : Single) : TVector3f; overload;
  69. function VScale(pV : TVector4f; pScale : Single) : TVector4f; overload;
  70. function VDistance(pV1, pV2 : TVector3f) : Single;
  71. implementation
  72. // =============================================================================
  73. //  V4
  74. // =============================================================================
  75. function V4(x,y,z : Single) : TVector4f;
  76. begin
  77. Result[0] := x;
  78. Result[1] := y;
  79. Result[2] := z;
  80. Result[3] := 0;
  81. end;
  82. function V4(x,y,z,w : Single) : TVector4f;
  83. begin
  84. Result[0] := x;
  85. Result[1] := y;
  86. Result[2] := z;
  87. Result[3] := w;
  88. end;
  89. function V4(pV3 : TVector3f; w : Single) : TVector4f; overload;
  90. begin
  91. Result[0] := pV3[0];
  92. Result[1] := pV3[1];
  93. Result[2] := pV3[2];
  94. Result[3] := w;
  95. end;
  96. function V4(pMatrix : TMatrix4f; pC : Integer) : TVector4f; overload;
  97. begin
  98. Result[0] := pMatrix[pC, 0];
  99. Result[1] := pMatrix[pC, 1];
  100. Result[2] := pMatrix[pC, 2];
  101. Result[3] := pMatrix[pC, 3];
  102. end;
  103. // =============================================================================
  104. //  V3
  105. // =============================================================================
  106. function V3(x,y,z : Single) : TVector3f;
  107. begin
  108. Result[0] := x;
  109. Result[1] := y;
  110. Result[2] := z;
  111. end;
  112. function V3(pMatrix : TMatrix4f; pC : Integer) : TVector3f; overload;
  113. begin
  114. Result[0] := pMatrix[pC, 0];
  115. Result[1] := pMatrix[pC, 1];
  116. Result[2] := pMatrix[pC, 2];
  117. end;
  118. // =============================================================================
  119. //  VCross
  120. // =============================================================================
  121. function VCross(pV1, pV2 : TVector3f) : TVector3f;
  122. begin
  123. Result[0] := (pV1[1]*pV2[2]) - (pV1[2]*pV2[1]);
  124. Result[1] := (pV1[2]*pV2[0]) - (pV1[0]*pV2[2]);
  125. Result[2] := (pV1[0]*pV2[1]) - (pV1[1]*pV2[0]);
  126. end;
  127. function VCross(pV1, pV2 : TVector4f) : TVector4f;
  128. begin
  129. Result[0] := (pV1[1]*pV2[2]) - (pV1[2]*pV2[1]);
  130. Result[1] := (pV1[2]*pV2[0]) - (pV1[0]*pV2[2]);
  131. Result[2] := (pV1[0]*pV2[1]) - (pV1[1]*pV2[0]);
  132. Result[3] := 0;
  133. end;
  134. // =============================================================================
  135. //  VDot
  136. // =============================================================================
  137. function VDot(pV1, pV2 : TVector3f) : Single;
  138. begin
  139. Result := (pV1[0]*pV2[0]) + (pV1[1]*pV2[1]) + (pV1[2]*pV2[2]);
  140. end;
  141. function VDot(pV1, pV2 : TVector4f) : Single;
  142. begin
  143. Result := (pV1[0]*pV2[0]) + (pV1[1]*pV2[1]) + (pV1[2]*pV2[2]) + (pV1[3]*pV2[3]);
  144. end;
  145. // =============================================================================
  146. //  VTransform
  147. // =============================================================================
  148. function VTransform(pV1 : TVector3f; pM : TMatrix4f) : TVector3f;
  149. var
  150.  TV : TVector3f;
  151. begin
  152. TV[X] := pV1[X] * pM[X, X] + pV1[Y] * pM[Y, X] + pV1[Z] * pM[Z, X] + pM[W, X];
  153. TV[Y] := pV1[X] * pM[X, Y] + pV1[Y] * pM[Y, Y] + pV1[Z] * pM[Z, Y] + pM[W, Y];
  154. TV[Z] := pV1[X] * pM[X, Z] + pV1[Y] * pM[Y, Z] + pV1[Z] * pM[Z, Z] + pM[W, Z];
  155. Result := TV
  156. end;
  157. // =============================================================================
  158. //  VSub
  159. // =============================================================================
  160. function VSub(pV1, pV2 : TVector3f) : TVector3f;
  161. begin
  162. Result := V3(pV1[0]-pV2[0], pV1[1]-pV2[1], pV1[2]-pV2[2]);
  163. end;
  164. function VSub(pV1, pV2 : TVector4f) : TVector4f; overload;
  165. begin
  166. Result := V4(pV1[0]-pV2[0], pV1[1]-pV2[1], pV1[2]-pV2[2], pV1[3]-pV2[3]);
  167. end;
  168. // =============================================================================
  169. //  VAdd
  170. // =============================================================================
  171. function VAdd(pV1, pV2 : TVector3f) : TVector3f;
  172. begin
  173. Result := V3(pV1[0]+pV2[0], pV1[1]+pV2[1], pV1[2]+pV2[2]);
  174. end;
  175. function VAdd(pV1, pV2 : TVector4f) : TVector4f; overload;
  176. begin
  177. Result := V4(pV1[0]+pV2[0], pV1[1]+pV2[1], pV1[2]+pV2[2], pV1[3]+pV2[3]);
  178. end;
  179. // =============================================================================
  180. //  VNormalize
  181. // =============================================================================
  182. function VNormalize(pV : TVector3f) : TVector3f;
  183. var
  184.  l : Single;
  185. begin
  186. l := Sqrt(pV[0]*pV[0] + pV[1]*pV[1] + pV[2]*pV[2]);
  187. if l = 0 then
  188.  exit;
  189. Result[0] := pV[0]/l;
  190. Result[1] := pV[1]/l;
  191. Result[2] := pV[2]/l;
  192. end;
  193. // =============================================================================
  194. //  VScale
  195. // =============================================================================
  196. function VScale(pV : TVector3f; pScale : Single) : TVector3f;
  197. begin
  198. Result[0] := pV[0] * pScale;
  199. Result[1] := pV[1] * pScale;
  200. Result[2] := pV[2] * pScale;
  201. end;
  202. function VScale(pV : TVector4f; pScale : Single) : TVector4f; overload;
  203. begin
  204. Result[0] := pV[0] * pScale;
  205. Result[1] := pV[1] * pScale;
  206. Result[2] := pV[2] * pScale;
  207. Result[3] := pV[3] * pScale;
  208. end;
  209. // =============================================================================
  210. //  VDistance
  211. // =============================================================================
  212. function VDistance(pV1, pV2 : TVector3f) : Single;
  213. begin
  214. Result := Sqrt(Sqr(pV1[0]-pV2[0])+Sqr(pV1[1]-pV2[1])+Sqr(pV1[2]-pV2[2]));
  215. end;
  216. // =============================================================================
  217. //  Matrix_SetIdentity
  218. // =============================================================================
  219. procedure Matrix_SetIdentity(var M : TMatrix4f);
  220. begin
  221. M[0,0] := 1; M[1,0] := 0; M[2,0] := 0; M[3,0] := 0;
  222. M[0,1] := 0; M[1,1] := 1; M[2,1] := 0; M[3,1] := 0;
  223. M[0,2] := 0; M[1,2] := 0; M[2,2] := 1; M[3,2] := 0;
  224. M[0,3] := 0; M[1,3] := 0; M[2,3] := 0; M[3,3] := 1;
  225. end;
  226. // =============================================================================
  227. //  Matrix_SetTransform
  228. // =============================================================================
  229. procedure Matrix_SetTransform(var M : TMatrix4f; V : TVector3f);
  230. begin
  231. M[3][0] := V[0];
  232. M[3][1] := V[1];
  233. M[3][2] := V[2];
  234. end;
  235. // =============================================================================
  236. //  Matrix_SetRotation
  237. // =============================================================================
  238. procedure Matrix_SetRotation(var M : TMatrix4f; V : TVector3f);
  239. var
  240.  cr , sr , cp , sp , cy , sy , srsp , crsp : single;
  241. begin
  242. V[0] := DegToRad(V[0]);
  243. V[1] := DegToRad(V[1]);
  244. V[2] := DegToRad(V[2]);
  245. cr := cos(V[0]);
  246. sr := sin(V[0]);
  247. cp := cos(V[1]);
  248. sp := sin(V[1]);
  249. cy := cos(V[2]);
  250. sy := sin(V[2]);
  251. M[0,0] := cp*cy;
  252. M[1,0] := cp*sy;
  253. M[2,0] := -sp;
  254. srsp := sr*sp;
  255. crsp := cr*sp;
  256. M[0,1] := srsp*cy-cr*sy ;
  257. M[1,1] := srsp*sy+cr*cy ;
  258. M[2,1] := sr*cp ;
  259. M[0,2] := crsp*cy+sr*sy ;
  260. M[1,2] := crsp*sy-sr*cy ;
  261. M[2,2] := cr*cp ;
  262. end;
  263. // =============================================================================
  264. //  Matrix_RotateVect
  265. // =============================================================================
  266. procedure Matrix_RotateVect(const M : TMatrix4f; var pVect : TVector3f);
  267. var
  268.  vec : array [0..2] of single;
  269. begin
  270. vec[0] := pVect[0]*M[0,0] + pVect[1]*M[1,0] + pVect[2]*M[2,0];
  271. vec[1] := pVect[0]*M[0,1] + pVect[1]*M[1,1] + pVect[2]*M[2,1];
  272. vec[2] := pVect[0]*M[0,2] + pVect[1]*M[1,2] + pVect[2]*M[2,2];
  273. pVect[0] := vec[0];
  274. pVect[1] := vec[1];
  275. pVect[2] := vec[2];
  276. end;
  277. // =============================================================================
  278. //  Matrix_UnRotateVect
  279. // =============================================================================
  280. function Matrix_UnRotateVect(const M : TMatrix4f; pVect : TVector3f) : TVector3f;
  281. var
  282.  V : TVector3f;
  283. begin
  284. V := V3(VDot(V, V3(M[0,0], M[0,1], M[0,2])),
  285.         VDot(V, V3(M[1,0], M[1,1], M[1,2])),
  286.         VDot(V, V3(M[2,0], M[2,1], M[2,2])));
  287. Result := V;
  288. end;
  289. // =============================================================================
  290. //  Matrix_Multiply
  291. // =============================================================================
  292. function Matrix_Multiply(m1 : TMatrix4f; m2 : TMatrix4f) : TMatrix4f;
  293. var
  294.   r, c, i: Byte;
  295.   t: TMatrix4f;
  296. begin
  297. // Multiply two matrices.
  298. t := NullMatrix4f;
  299. for r := 0 to 3 do
  300.  for c := 0 to 3 do
  301.   for i := 0 to 3 do
  302.    t[r,c] := t[r,c] + (m1[r,i]*m2[i,c]);
  303. Result := t;
  304. end;
  305. // internal version for the determinant of a 3x3 matrix
  306. function MatrixDetInternal(a1, a2, a3, b1, b2, b3, c1, c2, c3: Single): Single;
  307. begin
  308. Result := a1 * (b2 * c3 - b3 * c2) -
  309.           b1 * (a2 * c3 - a3 * c2) +
  310.           c1 * (a2 * b3 - a3 * b2);
  311. end;
  312. // Determinant of a 4x4 matrix
  313. function MatrixDeterminant(M: TMatrix4f): Single; register;
  314. var a1, a2, a3, a4,
  315.     b1, b2, b3, b4,
  316.     c1, c2, c3, c4,
  317.     d1, d2, d3, d4  : Single;
  318. begin
  319.   a1 := M[X, X];  b1 := M[X, Y];  c1 := M[X, Z];  d1 := M[X, W];
  320.   a2 := M[Y, X];  b2 := M[Y, Y];  c2 := M[Y, Z];  d2 := M[Y, W];
  321.   a3 := M[Z, X];  b3 := M[Z, Y];  c3 := M[Z, Z];  d3 := M[Z, W];
  322.   a4 := M[W, X];  b4 := M[W, Y];  c4 := M[W, Z];  d4 := M[W, W];
  323.   Result := a1 * MatrixDetInternal(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
  324.             b1 * MatrixDetInternal(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
  325.             c1 * MatrixDetInternal(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
  326.             d1 * MatrixDetInternal(a2, a3, a4, b2, b3, b4, c2, c3, c4);
  327. end;
  328. // Adjoint of a 4x4 matrix - used in the computation of the inverse
  329. // of a 4x4 matrix
  330. procedure MatrixAdjoint(var M: TMatrix4f); register;
  331. var a1, a2, a3, a4,
  332.     b1, b2, b3, b4,
  333.     c1, c2, c3, c4,
  334.     d1, d2, d3, d4: Single;
  335. begin
  336.     a1 :=  M[X, X]; b1 :=  M[X, Y];
  337.     c1 :=  M[X, Z]; d1 :=  M[X, W];
  338.     a2 :=  M[Y, X]; b2 :=  M[Y, Y];
  339.     c2 :=  M[Y, Z]; d2 :=  M[Y, W];
  340.     a3 :=  M[Z, X]; b3 :=  M[Z, Y];
  341.     c3 :=  M[Z, Z]; d3 :=  M[Z, W];
  342.     a4 :=  M[W, X]; b4 :=  M[W, Y];
  343.     c4 :=  M[W, Z]; d4 :=  M[W, W];
  344.     // row column labeling reversed since we transpose rows & columns
  345.     M[X, X] :=  MatrixDetInternal(b2, b3, b4, c2, c3, c4, d2, d3, d4);
  346.     M[Y, X] := -MatrixDetInternal(a2, a3, a4, c2, c3, c4, d2, d3, d4);
  347.     M[Z, X] :=  MatrixDetInternal(a2, a3, a4, b2, b3, b4, d2, d3, d4);
  348.     M[W, X] := -MatrixDetInternal(a2, a3, a4, b2, b3, b4, c2, c3, c4);
  349.     M[X, Y] := -MatrixDetInternal(b1, b3, b4, c1, c3, c4, d1, d3, d4);
  350.     M[Y, Y] :=  MatrixDetInternal(a1, a3, a4, c1, c3, c4, d1, d3, d4);
  351.     M[Z, Y] := -MatrixDetInternal(a1, a3, a4, b1, b3, b4, d1, d3, d4);
  352.     M[W, Y] :=  MatrixDetInternal(a1, a3, a4, b1, b3, b4, c1, c3, c4);
  353.     M[X, Z] :=  MatrixDetInternal(b1, b2, b4, c1, c2, c4, d1, d2, d4);
  354.     M[Y, Z] := -MatrixDetInternal(a1, a2, a4, c1, c2, c4, d1, d2, d4);
  355.     M[Z, Z] :=  MatrixDetInternal(a1, a2, a4, b1, b2, b4, d1, d2, d4);
  356.     M[W, Z] := -MatrixDetInternal(a1, a2, a4, b1, b2, b4, c1, c2, c4);
  357.     M[X, W] := -MatrixDetInternal(b1, b2, b3, c1, c2, c3, d1, d2, d3);
  358.     M[Y, W] :=  MatrixDetInternal(a1, a2, a3, c1, c2, c3, d1, d2, d3);
  359.     M[Z, W] := -MatrixDetInternal(a1, a2, a3, b1, b2, b3, d1, d2, d3);
  360.     M[W, W] :=  MatrixDetInternal(a1, a2, a3, b1, b2, b3, c1, c2, c3);
  361. end;
  362. // multiplies all elements of a 4x4 matrix with a factor
  363. procedure MatrixScale(var M: TMatrix4f; Factor: Single); register;
  364. var
  365.  I, J: Integer;
  366. begin
  367.   for I := 0 to 3 do
  368.     for J := 0 to 3 do M[I, J] := M[I, J] * Factor;
  369. end;
  370. // finds the inverse of a 4x4 matrix
  371. procedure Matrix_Inverse(var M: TMatrix4f); register;
  372. var
  373.  Det: Single;
  374. begin
  375.   Det := MatrixDeterminant(M);
  376.   if Abs(Det) < EPSILON then M := IdentityMatrix
  377.                         else
  378.   begin
  379.     MatrixAdjoint(M);
  380.     MatrixScale(M, 1 / Det);
  381.   end;
  382. end;
  383. // =============================================================================
  384. //  Matrix_TansformVector
  385. // =============================================================================
  386. function Matrix_TansformVector(const M : TMatrix4f; V : TVector3f) : TVector3f;
  387. begin
  388. Matrix_RotateVect(M, V);
  389. Result := V3(V[0]+M[3,0], V[1]+M[3,1], V[2]+M[3,2]);
  390. end;
  391. // =============================================================================
  392. //  Matrix_UntransformVector
  393. // =============================================================================
  394. function Matrix_UntransformVector(const M : TMatrix4f; V : TVector3f) : TVector3f;
  395. begin
  396. V := V3(V[0]-M[3,0], V[1]-M[3,1], V[2]-M[3,2]);
  397. V := V3(VDot(V, V3(M[0,0], M[0,1], M[0,2])),
  398.         VDot(V, V3(M[1,0], M[1,1], M[1,2])),
  399.         VDot(V, V3(M[2,0], M[2,1], M[2,2])));
  400. Result := V;
  401. end;
  402. // =============================================================================
  403. //  Matrix_SetColumn
  404. // =============================================================================
  405. procedure Matrix_SetColumn(var M : TMatrix4f; pColumn : Byte;pVect : TVector4f);
  406. begin
  407. M[pColumn, 0] := pVect[0];
  408. M[pColumn, 1] := pVect[1];
  409. M[pColumn, 2] := pVect[2];
  410. M[pColumn, 3] := pVect[3];
  411. end;
  412. end.