tv.dpr 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  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. {
  12. Tests were made to determine where delphi implementation differs
  13. from standards and glscene, and adapt the implementation
  14. The numbers of tests done here can also be found in the unit tests.
  15. run this application with number of test to run only that test.
  16. }
  17. {$IFDEF FPC}
  18. {$mode delphi}
  19. uses SysUtils, System.Math.Vectors;
  20. {$ELSE}
  21. uses System.SysUtils, System.Math.Vectors;
  22. {$ENDIF}
  23. {$IFNDEF FPC}
  24. Function MIdentity : TMatrix;
  25. begin
  26. Result:=TMatrix.Identity;
  27. end;
  28. Function M3DIdentity : TMatrix3D;
  29. begin
  30. Result:=TMatrix3D.Identity;
  31. end;
  32. // Delphi does not have ToString, use helper to implement it.
  33. // We cannot inherit record helpers in Delphi,
  34. // so we define this after the above functions to have Identity.
  35. Type
  36. TVHelper = record Helper for TVector
  37. Function ToString: String;
  38. end;
  39. TPHelper = record Helper for TPoint3D
  40. Function ToString: String;
  41. end;
  42. TMHelper = record Helper {(TMatrixConstants)} for TMatrix
  43. function ToString(Multiline: Boolean = True): String;
  44. class function Identity : TMatrix; static;
  45. end;
  46. TM3DHelper = record Helper {(TMatrixConstants)} for TMatrix3D
  47. function ToString(Multiline: Boolean = True): String;
  48. class function Identity : TMatrix3D; static;
  49. end;
  50. TQ3DHelper = record Helper {(TMatrixConstants)} for TQuaternion3D
  51. function ToString(Multiline: Boolean = True): String;
  52. end;
  53. Function TVHelper.ToString: String;
  54. begin
  55. Result:=Format('(%7.4f,%7.4f W:%7.4f)',[X,Y,W]);
  56. end;
  57. Function TPHelper.ToString: String;
  58. begin
  59. Result:=Format('(%7.4f,%7.4f,%7.4f)',[X,Y,Z]);
  60. end;
  61. class function TMHelper.Identity : TMatrix;
  62. begin
  63. Result:=Midentity;
  64. end;
  65. function TMHelper.ToString(Multiline: Boolean): String;
  66. var
  67. S,Sep : String;
  68. begin
  69. Sep:='';
  70. if MultiLine then
  71. Sep:=sLineBreak;
  72. S:='['+Format('%7.4f,%7.4f,%7.4f',[m11,m12,m13]);
  73. Result:=S+','+Sep;
  74. S:=Format('%7.4f,%7.4f,%7.4f',[m21,m22,m23]);
  75. Result:=Result+S+Sep;
  76. S:=Format('%7.4f,%7.4f,%7.4f',[m31,m32,m33]);
  77. Result:=Result+S+']';
  78. end;
  79. class function TM3DHelper.Identity : TMatrix3D;
  80. begin
  81. Result:=M3Didentity;
  82. end;
  83. function TM3DHelper.ToString(Multiline: Boolean): String;
  84. var
  85. S,Sep : String;
  86. begin
  87. Sep:='';
  88. if MultiLine then
  89. Sep:=sLineBreak;
  90. S:='['+Format('%7.4f,%7.4f,%7.4f,%7.4f',[m11,m12,m13,m14]);
  91. Result:=S+','+Sep;
  92. S:=Format('%7.4f,%7.4f,%7.4f,%7.4f',[m21,m22,m23,m24]);
  93. Result:=Result+S+','+Sep;
  94. S:=Format('%7.4f,%7.4f,%7.4f,%7.4f',[m31,m32,m33,m34]);
  95. Result:=Result+S+','+Sep;
  96. S:=Format('%7.4f,%7.4f,%7.4f,%7.4f',[m41,m42,m43,m44]);
  97. Result:=Result+S+']';
  98. end;
  99. function TQ3DHelper.ToString(Multiline: Boolean = True): String;
  100. begin
  101. Result:=Format('(%7.4f,i: %7.4f,j: %7.4f, k: %7.4f)',[Realpart,ImagPart.X,ImagPart.Y,ImagPart.Z]);
  102. end;
  103. {$ENDIF}
  104. Function DoTest(aId : integer; const aCaption : String) : boolean;
  105. var
  106. cID : Integer;
  107. begin
  108. cID:=StrToIntDef(Paramstr(1),-1);
  109. Result:=(aId=cID) or (Cid=-1);
  110. if Result then
  111. Writeln('[',aID,'] ',aCaption);
  112. end;
  113. Procedure TV;
  114. var
  115. V1,V2,V3 : TVector;
  116. begin
  117. if DoTest(1,'Vector CrossProduct') then
  118. begin
  119. V1:=TVector.Create(1,0,0);
  120. V2:=TVector.Create(0,1,0);
  121. V3:=V2.CrossProduct(V1);
  122. With V3 do
  123. Writeln('1: V3 ',V3.ToString);
  124. end;
  125. end;
  126. Procedure TP;
  127. var
  128. P1,P2,P3 : TPoint3D;
  129. begin
  130. P1:=TPoint3D.Create(1,0,0);
  131. P2:=TPoint3D.Create(0,0,1); // Z-axis
  132. if DoTest(101,'Rotate Z axis') then
  133. begin
  134. P3:=P1.Rotate(P2,Pi/2);
  135. Writeln('P3 = ',P3.ToString);
  136. end;
  137. if DoTest(102,'Rotate Y axis') then
  138. begin
  139. P2:=TPoint3D.Create(0,1,0); // Y-axis
  140. P3:=P1.Rotate(P2,Pi/2);
  141. Writeln('P3 = ',P3.ToString);
  142. end;
  143. end;
  144. Procedure TM;
  145. var
  146. M,M2 : TMatrix;
  147. begin
  148. if DoTest(11,'Identity') then
  149. begin
  150. M:=TMatrix.Identity;
  151. Writeln(M.ToString);
  152. end;
  153. If DoTest(12,'Rotation (Pi/2)') then
  154. begin
  155. M:=TMatrix.CreateRotation(Pi/2);
  156. Writeln(M.ToString);
  157. end;
  158. if DoTest(13,'Rotation Pi') then
  159. begin
  160. M:=TMatrix.CreateRotation(Pi);
  161. Writeln(M.ToString);
  162. end;
  163. If DoTest(14,'Scaling 2') then
  164. begin
  165. M:=TMatrix.CreateScaling(2,3);
  166. Writeln(M.ToString);
  167. end;
  168. If DoTest(15,'Translation (3,4)') then
  169. begin
  170. M:=TMatrix.CreateTranslation(3,4);
  171. Writeln(M.ToString);
  172. end;
  173. If DoTest(16,'Adjoint') then
  174. begin
  175. M:=TMatrix.CreateRotation(Pi/6);
  176. M2:=M.Adjoint;
  177. Writeln(M2.ToString);
  178. end;
  179. end;
  180. Procedure Params(const ASource, ATarget, ACeiling: TPoint3D);
  181. var
  182. ZAxis, XAxis, YAxis: TPoint3D;
  183. begin
  184. Writeln('aSource: ',aSource.ToString);
  185. Writeln('aTarget: ',aTarget.ToString);
  186. Writeln('aCeiling: ',aCeiling.ToString);
  187. ZAxis := (ASource - ATarget).Normalize;
  188. Writeln('Zaxis: ',ZAxis.ToString);
  189. XAxis := ACeiling.CrossProduct(ZAxis).Normalize;
  190. Writeln('Xaxis: ',XAxis.ToString);
  191. YAxis := ZAxis.CrossProduct(XAxis);
  192. Writeln('Yaxis: ',YAxis.ToString);
  193. end;
  194. Procedure TM3D;
  195. var
  196. M,M2,M3 : TMatrix3D;
  197. begin
  198. if DoTest(31,'M3D.Identity') then
  199. begin
  200. M:=TMatrix3D.Identity;
  201. Writeln(M.ToString);
  202. end;
  203. if DoTest(32,'M3D.Rotation ((1,0,0),Pi/2)') then
  204. begin
  205. M:=TMatrix3D.CreateRotation(Point3D(1,0,0),Pi/2);
  206. Writeln(M.ToString);
  207. end;
  208. if DoTest(33,'M3D.Rotation ((0,1,0),Pi/2)') then
  209. begin
  210. M:=TMatrix3D.CreateRotation(Point3D(0,1,0),Pi/2);
  211. Writeln(M.ToString);
  212. end;
  213. if DoTest(34,'M3D.Rotation ((0,0,1),Pi/2)') then
  214. begin
  215. M:=TMatrix3D.CreateRotation(Point3D(0,0,1),pi/2);
  216. Writeln(M.ToString);
  217. end;
  218. if DoTest(35,'M3D.Scaling (1,2,3)') then
  219. begin
  220. M:=TMatrix3D.CreateScaling(Point3D(1,2,3));
  221. Writeln(M.ToString);
  222. end;
  223. if DoTest(36,'MD3D.Translation (3,4,5)') then
  224. begin
  225. M:=TMatrix3d.CreateTranslation(Point3D(3,4,5));
  226. Writeln(M.ToString);
  227. end;
  228. if DoTest(37,'M3D.HeadingPitchBank(Pi/2,0,0)') then
  229. begin
  230. M:=TMatrix3D.CreateRotationHeadingPitchBank(Pi/2,0,0);
  231. Writeln(M.ToString);
  232. end;
  233. if DoTest(38,'M3D.HeadingPitchBank(0,Pi/2,0)') then
  234. begin
  235. M:=TMatrix3D.CreateRotationHeadingPitchBank(0,Pi/2,0);
  236. Writeln(M.ToString);
  237. end;
  238. if DoTest(39,'M3D.HeadingPitchBank(0,0,Pi/2)') then
  239. begin
  240. M:=TMatrix3D.CreateRotationHeadingPitchBank(0,0,Pi/2);
  241. Writeln(M.ToString);
  242. end;
  243. if DoTest(40,'M3D.RotationX(Pi/2)') then
  244. begin
  245. M:=TMatrix3D.CreateRotationX(Pi/2);
  246. Writeln(M.ToString);
  247. end;
  248. if DoTest(41,'M3D.RotationY(Pi/2)') then
  249. begin
  250. M:=TMatrix3D.CreateRotationY(Pi/2);
  251. Writeln(M.ToString);
  252. end;
  253. if DoTest(42,'M3D.RotationZ(Pi/2)') then
  254. begin
  255. M:=TMatrix3D.CreateRotationZ(Pi/2);
  256. Writeln(M.ToString);
  257. end;
  258. if DoTest(43,'M3D.YawPitchRoll(Pi/2,0,0)') then
  259. begin
  260. M:=TMatrix3D.CreateRotationYawPitchRoll(Pi/2,0,0);
  261. Writeln(M.ToString);
  262. end;
  263. if DoTest(44,'M3D.YawPitchRoll(0,Pi/2,0)') then
  264. begin
  265. M:=TMatrix3D.CreateRotationYawPitchRoll(0,Pi/2,0);
  266. Writeln(M.ToString);
  267. end;
  268. if DoTest(45,'M3D.YawPitchRoll(0,0,Pi/2)') then
  269. begin
  270. M:=TMatrix3D.CreateRotationYawPitchRoll(0,0,Pi/2);
  271. Writeln(M.ToString);
  272. end;
  273. if DoTest(46,'M3D.LookAtDirLH((0,0,0),(0,0,1),(0,0,1)') then
  274. begin
  275. M:=TMatrix3D.CreateLookAtDirLH(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
  276. Writeln(M.ToString);
  277. end;
  278. if DoTest(47,'M3D.LookAtDirLH((0,0,0),(0,1,0),(0,0,1)') then
  279. begin
  280. M:=TMatrix3D.CreateLookAtDirLH(Point3D(0,0,0),Point3D(0,1,0),Point3D(0,0,1));
  281. Writeln(M.ToString);
  282. end;
  283. if DoTest(48,'M3D.LookAtDirLH((0,0,0),(1,0,0),(0,0,1)') then
  284. begin
  285. M:=TMatrix3D.CreateLookAtDirLH(Point3D(0,0,0),Point3D(1,0,0),Point3D(0,0,1));
  286. Writeln(M.ToString);
  287. end;
  288. if DoTest(49,'M3D.LookAtDirRH((0,0,0),(0,0,1),(0,0,1)') then
  289. begin
  290. M:=TMatrix3D.CreateLookAtDirRH(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
  291. Writeln(M.ToString);
  292. end;
  293. if DoTest(50,'M3D.LookAtDirRH((0,0,0),(0,1,0),(0,0,1)') then
  294. begin
  295. M:=TMatrix3D.CreateLookAtDirRH(Point3D(0,0,0),Point3D(0,1,0),Point3D(0,0,1));
  296. Writeln(M.ToString);
  297. end;
  298. if DoTest(51,'M3D.LookAtDirRH((0,0,0),(1,0,0),(0,0,1)') then
  299. begin
  300. M:=TMatrix3D.CreateLookAtDirRH(Point3D(0,0,0),Point3D(1,0,0),Point3D(0,0,1));
  301. Writeln(M.ToString);
  302. end;
  303. if DoTest(52,'M3D.LookAtLH((0,0,0),(0,0,1),(0,0,1)') then
  304. begin
  305. M:=TMatrix3D.CreateLookAtLH(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
  306. Writeln(M.ToString);
  307. end;
  308. if DoTest(53,'M3D.LookAtLH((0,0,0),(0,1,0),(0,0,1)') then
  309. begin
  310. M:=TMatrix3D.CreateLookAtLH(Point3D(0,0,0),Point3D(0,1,0),Point3D(0,0,1));
  311. Writeln(M.ToString);
  312. end;
  313. if DoTest(54,'M3D.LookAtLH((0,0,0),(1,0,0),(0,0,1)') then
  314. begin
  315. M:=TMatrix3D.CreateLookAtLH(Point3D(0,0,0),Point3D(1,0,0),Point3D(0,0,1));
  316. Writeln(M.ToString);
  317. end;
  318. if DoTest(55,'M3D.LookAtRH((0,0,0),(0,0,1),(0,0,1)') then
  319. begin
  320. Params(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
  321. M:=TMatrix3D.CreateLookAtRH(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
  322. Writeln(M.ToString);
  323. end;
  324. if DoTest(56,'M3D.LookAtRH((0,0,0),(0,1,0),(0,0,1)') then
  325. begin
  326. M:=TMatrix3D.CreateLookAtRH(Point3D(0,0,0),Point3D(0,1,0),Point3D(0,0,1));
  327. Writeln(M.ToString);
  328. end;
  329. if DoTest(57,'M3D.LookAtRH((0,0,0),(1,0,0),(0,0,1)') then
  330. begin
  331. M:=TMatrix3D.CreateLookAtRH(Point3D(0,0,0),Point3D(1,0,0),Point3D(0,0,1));
  332. Writeln(M.ToString);
  333. end;
  334. if DoTest(58,'M3D.CreateOrthoLH(1,1,0,1)') then
  335. begin
  336. M:=TMatrix3D.CreateOrthoLH(1,1,0,1);
  337. Writeln(M.ToString);
  338. end;
  339. if DoTest(59,'M3D.CreateOrthoLH(1,1,0,2)') then
  340. begin
  341. M:=TMatrix3D.CreateOrthoLH(1,1,0,2);
  342. Writeln(M.ToString);
  343. end;
  344. if DoTest(60,'M3D.CreateOrthoRH(1,1,0,1)') then
  345. begin
  346. M:=TMatrix3D.CreateOrthoRH(1,1,0,1);
  347. Writeln(M.ToString);
  348. end;
  349. if DoTest(61,'M3D.CreateOrthoRH(1,1,0,2)') then
  350. begin
  351. M:=TMatrix3D.CreateOrthoRH(1,1,0,2);
  352. Writeln(M.ToString);
  353. end;
  354. if DoTest(62,'M3D.CreateOrthoOffCenterLH(0,0,1,1,0,1)') then
  355. begin
  356. M:=TMatrix3D.CreateOrthoOffCenterLH(0,0,1,1,0,1);
  357. Writeln(M.ToString);
  358. end;
  359. if DoTest(63,'M3D.CreateOrthoOffCenterLH(0,0,1,1,0,2)') then
  360. begin
  361. M:=TMatrix3D.CreateOrthoOffCenterLH(0,0,1,1,0,2);
  362. Writeln(M.ToString);
  363. end;
  364. if DoTest(64,'M3D.CreateOrthoOffCenterRH(0,0,1,1,0,1)') then
  365. begin
  366. M:=TMatrix3D.CreateOrthoOffCenterRH(0,0,1,1,0,1);
  367. Writeln(M.ToString);
  368. end;
  369. if DoTest(65,'M3D.CreateOrthoOffCenterRH(0,0,1,1,0,2)') then
  370. begin
  371. M:=TMatrix3D.CreateOrthoOffCenterRH(0,0,1,1,0,2);
  372. Writeln(M.ToString);
  373. end;
  374. if DoTest(66,'M3D.CreatePerspectiveFovLH(pi/2,1,0,1)') then
  375. begin
  376. M:=TMatrix3D.CreatePerspectiveFovLH(pi/2,1,0,1);
  377. Writeln(M.ToString);
  378. end;
  379. if DoTest(67,'M3D.CreatePerspectiveFovLH(pi/21,0,1,True)') then
  380. begin
  381. M:=TMatrix3D.CreatePerspectiveFovLH(pi/2,1,0,1,True);
  382. Writeln(M.ToString);
  383. end;
  384. if DoTest(68,'M3D.CreatePerspectiveFovRH(pi/2,1,0,1)') then
  385. begin
  386. M:=TMatrix3D.CreatePerspectiveFovRH(pi/2,1,0,1);
  387. Writeln(M.ToString);
  388. end;
  389. if DoTest(69,'M3D.CreatePerspectiveFovRH(pi/2,1,0,1,True)') then
  390. begin
  391. M:=TMatrix3D.CreatePerspectiveFovRH(pi/2,1,0,1,True);
  392. Writeln(M.ToString);
  393. end;
  394. if DoTest(70,'M3D.Create(array)') then
  395. begin
  396. M:=TMatrix3D.Create([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
  397. Writeln(M.ToString);
  398. end;
  399. if DoTest(71,'M3D.CreateScaling(Point3D(1,2,3))') then
  400. begin
  401. M:=TMatrix3D.CreateScaling(Point3D(1,2,3));
  402. Writeln(M.ToString);
  403. end;
  404. if DoTest(72,'M3D.CreateTranslation(Point3D(1,2,3))') then
  405. begin
  406. M:=TMatrix3D.CreateTranslation(Point3D(1,2,3));
  407. Writeln(M.ToString);
  408. end;
  409. if DoTest(73,'M3D*M3D') then
  410. begin
  411. M:=TMatrix3D.Create( [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
  412. M2:=TMatrix3D.Create([16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]);
  413. M3:=M*M2;
  414. Writeln(M3.ToString);
  415. end;
  416. if DoTest(74,'M3D.Adjoint') then
  417. begin
  418. M:=TMatrix3D.CreateRotationZ(Pi/3);
  419. M2:=M.Adjoint;
  420. Writeln(M2.ToString);
  421. end;
  422. if DoTest(75,'M3D.Determinant') then
  423. begin
  424. M:=TMatrix3D.CreateRotationZ(Pi/3);
  425. Writeln(M.Determinant);
  426. end;
  427. if DoTest(76,'M3D.Determinant') then
  428. begin
  429. M:=TMatrix3D.Create(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
  430. // M:=TMatrix3D.Create(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);
  431. Writeln(M.Determinant);
  432. end;
  433. if DoTest(77,'M3D.Rotation.EyePosition') then
  434. begin
  435. M:=TMatrix3D.CreateRotationZ(Pi/2);
  436. Writeln(M.EyePosition.ToString);
  437. end;
  438. if DoTest(78,'M3D.Translation.EyePosition') then
  439. begin
  440. M:=TMatrix3D.CreateRotationZ(Pi/3)*TMatrix3D.CreateTranslation(Point3D(1,0,0));
  441. Writeln(M.EyePosition.ToString);
  442. end;
  443. if DoTest(79,'M3D.Inverse') then
  444. begin
  445. M:=TMatrix3D.CreateRotationZ(Pi/3);
  446. Writeln(M.Inverse.ToString);
  447. end;
  448. end;
  449. Procedure TQ;
  450. var
  451. Q1,Q2 : TQuaternion3D;
  452. begin
  453. {$IFDEF FPC}
  454. If DoTest(201,'TQuaternion3D.Create(Point3D(1,0,0),Point3D(0,1,0))') then
  455. begin
  456. Q1:=TQuaternion3D.Create(Point3D(1,0,0),Point3D(0,1,0));
  457. Writeln('Q = ',Q1.ToString);
  458. end;
  459. {$ENDIF}
  460. If DoTest(202,'TQuaternion3D.Create(Point3D(1,0,0),Pi/2)') then
  461. begin
  462. Q1:=TQuaternion3D.Create(Point3D(1,0,0),Pi/2);
  463. Writeln('Q = ',Q1.ToString);
  464. end;
  465. If DoTest(203,'TQuaternion3D.Create(Point3D(0,1,0),Pi/2)') then
  466. begin
  467. Q1:=TQuaternion3D.Create(Point3D(0,1,0),Pi/2);
  468. Writeln('Q = ',Q1.ToString);
  469. end;
  470. If DoTest(204,'TQuaternion3D.Create(Point3D(0,0,1),Pi/2)') then
  471. begin
  472. Q1:=TQuaternion3D.Create(Point3D(0,0,1),Pi/2);
  473. Writeln('Q = ',Q1.ToString);
  474. end;
  475. If DoTest(205,'TQuaternion3D.Create(Pi/2,0,0)') then
  476. begin
  477. Q1:=TQuaternion3D.Create(Pi/2,0,0);
  478. Writeln('Q = ',Q1.ToString);
  479. end;
  480. If DoTest(206,'TQuaternion3D.Create(0,Pi/2,0)') then
  481. begin
  482. Q1:=TQuaternion3D.Create(0,Pi/2,0);
  483. Writeln('Q = ',Q1.ToString);
  484. end;
  485. If DoTest(207,'TQuaternion3D.Create(0,0,Pi/2)') then
  486. begin
  487. Q1:=TQuaternion3D.Create(0,0,Pi/2);
  488. Writeln('Q = ',Q1.ToString);
  489. end;
  490. If DoTest(208,'TQuaternion3D.Multiply (yawpitchroll)') then
  491. begin
  492. Q1:=TQuaternion3D.Create(0,0,Pi/2);
  493. Q2:=TQuaternion3D.Create(0,Pi/2,0);
  494. Writeln('Q1*Q2 = ',(Q1*Q2).ToString);
  495. end;
  496. If DoTest(209,'TQuaternion3D.Multiply (angle/vector)') then
  497. begin
  498. Q1:=TQuaternion3D.Create(Point3D(1,0,0),Pi/2);
  499. Q2:=TQuaternion3D.Create(Point3D(0,1,0),Pi/2);
  500. Writeln('Q1*Q2 = ',(Q1*Q2).ToString);
  501. end;
  502. end;
  503. begin
  504. TV;
  505. TP;
  506. TM;
  507. TM3D;
  508. TQ;
  509. end.