2
0

utcmatrix.pp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2023 by Michael Van Canneyt
  4. member of the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit utcmatrix;
  12. {$mode ObjFPC}{$H+}
  13. interface
  14. uses
  15. Classes, SysUtils, fpcunit, testregistry, utmathvectorbase, types, system.math.vectors;
  16. Type
  17. { TTestMatrix }
  18. TTestMatrix = class(TCMathVectorsBase)
  19. Private
  20. FM : Array[1..3] of TMatrix;
  21. procedure ClearMatrices;
  22. function GetM(AIndex: Integer): TMatrix;
  23. procedure SetM(AIndex: Integer; AValue: TMatrix);
  24. Protected
  25. procedure SetUp; override;
  26. procedure TearDown; override;
  27. Property M1 : TMatrix Index 1 Read GetM Write SetM;
  28. Property M2 : TMatrix Index 2 Read GetM Write SetM;
  29. Property M3 : TMatrix Index 3 Read GetM Write SetM;
  30. Published
  31. procedure TestHookUp;
  32. Procedure TestCreateRotation;
  33. Procedure TestCreateScaling;
  34. Procedure TestCreateTranslation;
  35. Procedure TTestEqual;
  36. Procedure TTestMultiply;
  37. Procedure TTestMultiplyPointf;
  38. Procedure TTestMultiplyVector;
  39. Procedure TTestMultiplyPoint3D;
  40. Procedure TTestMultiplyFactor1;
  41. Procedure TTestMultiplyFactor2;
  42. Procedure TTestDiv;
  43. Procedure TTestAdjoint;
  44. Procedure TTestDeterminant;
  45. Procedure TTestEqualsTo;
  46. Procedure TTestExtractScale;
  47. Procedure TTestInverse;
  48. Procedure TTestScale;
  49. end;
  50. implementation
  51. { TTestMatrix }
  52. procedure TTestMatrix.ClearMatrices;
  53. var
  54. I : integer;
  55. begin
  56. For I:=1 to 3 do
  57. FM[I]:=Default(TMatrix);
  58. end;
  59. function TTestMatrix.GetM(AIndex: Integer): TMatrix;
  60. begin
  61. Result:=FM[aIndex];
  62. end;
  63. procedure TTestMatrix.SetM(AIndex: Integer; AValue: TMatrix);
  64. begin
  65. FM[aIndex]:=aValue;
  66. end;
  67. procedure TTestMatrix.SetUp;
  68. begin
  69. inherited SetUp;
  70. ClearMatrices;
  71. end;
  72. procedure TTestMatrix.TearDown;
  73. begin
  74. inherited TearDown;
  75. ClearMatrices;
  76. end;
  77. procedure TTestMatrix.TestHookUp;
  78. var
  79. I,C,R : Integer;
  80. begin
  81. For I:=1 to 3 do
  82. For R:=0 to 2 do
  83. For C:=0 to 2 do
  84. AssertEquals(Format('M%d[%d,%d]',[I,C,R]),0.0,FM[I].M[R].V[C]);
  85. end;
  86. procedure TTestMatrix.TestCreateRotation;
  87. begin
  88. M1:=TMatrix.CreateRotation(0);
  89. AssertMatrix('Create 1',[1,0,0,
  90. 0,1,0,
  91. 0,0,1],M1);
  92. M1:=TMatrix.CreateRotation(Pi/2);
  93. AssertMatrix('Create 2',[0,1,0,
  94. -1,0,0,
  95. 0,0,1],M1);
  96. M1:=TMatrix.CreateRotation(Pi);
  97. AssertMatrix('Create 3',[-1,0,0,
  98. 0,-1,0,
  99. 0,0,1],M1);
  100. end;
  101. procedure TTestMatrix.TestCreateScaling;
  102. begin
  103. M1:=TMatrix.CreateScaling(2,2);
  104. AssertMatrix('Create 1',[2,0,0,
  105. 0,2,0,
  106. 0,0,1],M1);
  107. M1:=TMatrix.CreateScaling(2,3);
  108. AssertMatrix('Create 2',[2,0,0,
  109. 0,3,0,
  110. 0,0,1],M1);
  111. end;
  112. procedure TTestMatrix.TestCreateTranslation;
  113. begin
  114. M1:=TMatrix.CreateTranslation(2,3);
  115. AssertMatrix('Create 1',[1,0,0,
  116. 0,1,0,
  117. 2,3,1],M1);
  118. M1:=TMatrix.CreateTranslation(0,0);
  119. AssertMatrix('Create 2',[1,0,0,
  120. 0,1,0,
  121. 0,0,1],M1);
  122. end;
  123. procedure TTestMatrix.TTestEqual;
  124. begin
  125. M1:=TMatrix.CreateTranslation(2,3);
  126. M2:=TMatrix.CreateTranslation(2,3);
  127. AssertTrue('Equal translation',M1=M2);
  128. M2:=TMatrix.CreateTranslation(0,0);
  129. AssertFalse('NEqual translation',M1=M2);
  130. M1:=TMatrix.CreateScaling(2,3);
  131. M2:=TMatrix.CreateScaling(2,3);
  132. AssertTrue('Equal Scaling',M1=M2);
  133. M2:=TMatrix.CreateScaling(0,0);
  134. AssertFalse('NEqual Scaling',M1=M2);
  135. end;
  136. procedure TTestMatrix.TTestMultiply;
  137. begin
  138. M1:=TMatrix.CreateRotation(Pi/4);
  139. M2:=TMatrix.CreateRotation(Pi/4);
  140. M3:=M1*M2;
  141. AssertMatrix('Multiply',[0,1,0,
  142. -1,0,0,
  143. 0,0,1],M3);
  144. M1:=TMatrix.CreateRotation(Pi/3);
  145. M2:=TMatrix.CreateRotation(Pi/6);
  146. M3:=M1*M2;
  147. AssertMatrix('Multiply',[0,1,0,
  148. -1,0,0,
  149. 0,0,1],M3);
  150. end;
  151. procedure TTestMatrix.TTestMultiplyPointf;
  152. Var
  153. P1,P2 : TPointF;
  154. begin
  155. P1:=PointF(1,0);
  156. M1:=TMatrix.CreateRotation(Pi/2);
  157. P2:=P1*M1;
  158. AssertPointF('Multiplied',0,1,P2);
  159. M1:=TMatrix.CreateRotation(Pi);
  160. P2:=P1*M1;
  161. AssertPointF('Multiplied 2',-1,0,P2);
  162. M1:=TMatrix.CreateTranslation(3,4);
  163. P2:=P1*M1;
  164. AssertPointF('Multiplied 2',4,4,P2);
  165. end;
  166. procedure TTestMatrix.TTestMultiplyVector;
  167. Var
  168. V1,V2 : TVector;
  169. begin
  170. V1:=Vector(1,0);
  171. M1:=TMatrix.CreateRotation(Pi/2);
  172. V2:=V1*M1;
  173. AssertVector('Multiplied',0,1,1,V2);
  174. M1:=TMatrix.CreateRotation(Pi);
  175. V2:=V1*M1;
  176. AssertVector('Multiplied 2',-1,0,1,V2);
  177. end;
  178. procedure TTestMatrix.TTestMultiplyPoint3D;
  179. Var
  180. P1,P2 : TPoint3D;
  181. begin
  182. P1:=Point3D(1,0,0);
  183. M1:=TMatrix.CreateRotation(Pi/2);
  184. P2:=P1*M1;
  185. AssertPoint3D('Multiplied',0,1,0,P2);
  186. M1:=TMatrix.CreateRotation(Pi);
  187. P2:=P1*M1;
  188. AssertPoint3D('Multiplied 2',-1,0,0,P2);
  189. end;
  190. procedure TTestMatrix.TTestMultiplyFactor1;
  191. begin
  192. M1:=TMatrix.CreateRotation(Pi/2);
  193. M2:=M1*2;
  194. AssertMatrix('Multiply',[0,2,0,
  195. -2,0,0,
  196. 0,0,2],M2);
  197. end;
  198. procedure TTestMatrix.TTestMultiplyFactor2;
  199. begin
  200. M1:=TMatrix.CreateRotation(Pi/2);
  201. M2:=2*M1;
  202. AssertMatrix('Multiply',[0,2,0,
  203. -2,0,0,
  204. 0,0,2],M2);
  205. end;
  206. procedure TTestMatrix.TTestDiv;
  207. begin
  208. M1:=TMatrix.CreateRotation(Pi/2);
  209. M2:=M1/2;
  210. AssertMatrix('Divide',[ 0, 1/2,0,
  211. -1/2, 0, 0,
  212. 0, 0, 1/2],M2);
  213. end;
  214. procedure TTestMatrix.TTestAdjoint;
  215. begin
  216. M1:=TMatrix.CreateRotation(Pi/2);
  217. M2:=M1.Adjoint;
  218. AssertMatrix('Adjoint 1',[0,-1,0,
  219. 1,0,0,
  220. 0,0,1],M2);
  221. M1:=TMatrix.CreateRotation(Pi/6);
  222. M2:=M1.Adjoint;
  223. AssertMatrix('Adjoint 2',[ 0.866, -0.5, 0.00,
  224. 0.50, 0.866, 0.00,
  225. -0.00, 0.00, 1.00],M2);
  226. end;
  227. procedure TTestMatrix.TTestDeterminant;
  228. begin
  229. M1:=TMatrix.CreateRotation(Pi/2);
  230. AssertEquals('Det 1',1,M1.Determinant);
  231. M1:=TMatrix.CreateRotation(Pi/3);
  232. AssertEquals('Det 1',1,M1.Determinant);
  233. end;
  234. procedure TTestMatrix.TTestEqualsTo;
  235. begin
  236. M1:=TMatrix.CreateTranslation(2,3);
  237. M2:=TMatrix.CreateTranslation(2,3);
  238. AssertTrue('Equal translation',M1.EqualsTo(M2));
  239. M2:=TMatrix.CreateTranslation(0,0);
  240. AssertFalse('NEqual translation',M1.EqualsTo(M2));
  241. M1:=TMatrix.CreateScaling(2,3);
  242. M2:=TMatrix.CreateScaling(2,3);
  243. AssertTrue('Equal Scaling',M1.EqualsTo(M2));
  244. M2:=TMatrix.CreateScaling(0,0);
  245. AssertFalse('NEqual Scaling',M1.EqualsTo(M2));
  246. end;
  247. procedure TTestMatrix.TTestExtractScale;
  248. begin
  249. M1:=TMatrix.CreateRotation(Pi/2);
  250. AssertPointF('Scale 1',1,1,M1.ExtractScale);
  251. M1:=M1.Scale(2);
  252. AssertPointF('Scale 2',2,2,M1.ExtractScale);
  253. end;
  254. procedure TTestMatrix.TTestInverse;
  255. begin
  256. M1:=TMatrix.CreateRotation(Pi/2);
  257. M2:=M1.Inverse;
  258. M3:=TMatrix.CreateRotation(-Pi/2);
  259. AssertMatrix('Inverse 1',M3,M2);
  260. M1:=TMatrix.CreateRotation(Pi/6);
  261. M2:=M1.Inverse;
  262. M3:=TMatrix.CreateRotation(-Pi/6);
  263. AssertMatrix('Inverse 2',M3,M2);
  264. end;
  265. procedure TTestMatrix.TTestScale;
  266. begin
  267. M1:=TMatrix.CreateRotation(Pi/2);
  268. AssertMatrix('Create',[0,1,0,
  269. -1,0,0,
  270. 0,0,1],M1);
  271. M2:=M1.Scale(2);
  272. AssertMatrix('Scaled',[0,2,0,
  273. -2,0,0,
  274. 0,0,2],M2);
  275. end;
  276. initialization
  277. RegisterTest(TTestMatrix);
  278. end.