GLS.VectorTypesExt.pas 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398
  1. //
  2. // The graphics platform GLScene https://github.com/glscene
  3. //
  4. unit GLS.VectorTypesExt;
  5. interface
  6. { .$I GLScene.inc }
  7. uses
  8. System.Types,
  9. System.TypInfo,
  10. System.SysUtils,
  11. System.Rtti,
  12. System.Math,
  13. System.Math.Vectors,
  14. GLS.VectorTypes;
  15. type
  16. // Extended may be replaced with BigDecimals
  17. TIntegerArray = array of Integer;
  18. TVertexArray = array of TVector3f;
  19. TDoubleArray = array of Double;
  20. TVectorExt = array of Extended;
  21. TMatrixExt = array of array of Extended;
  22. TArray3DExt = array of array of array of Extended;
  23. TQuaternionRec = record
  24. private
  25. FData: array [0 .. 3] of Extended;
  26. procedure SetElement(Index: Byte; Value: Extended);
  27. function GetElement(Index: Byte): Extended;
  28. public
  29. constructor Create(Q: TVectorExt);
  30. class operator Multiply(Q1, Q2: TQuaternionRec): TQuaternionRec;
  31. class operator Multiply(Q: TQuaternionRec; Sc: Extended): TQuaternionRec;
  32. class operator Multiply(Scalar: Extended; Q: TQuaternionRec)
  33. : TQuaternionRec;
  34. class operator Implicit(V: TVectorExt): TQuaternionRec;
  35. function Inv: TQuaternionRec;
  36. function TruncateSTI: TQuaternionRec;
  37. property Element[index: Byte]: Extended read GetElement
  38. write SetElement; default;
  39. end;
  40. PVectorRec = ^TVectorRec;
  41. TVectorRec = record
  42. private
  43. FData: TVectorExt;
  44. FCount: Word;
  45. procedure SetElement(Index: Word; Value: Extended);
  46. function GetElement(Index: Word): Extended;
  47. procedure CheckUnique;
  48. public
  49. constructor Create(ElementsCount: Word); overload;
  50. constructor Create(V: TVectorExt); overload;
  51. class operator Add(V1, V2: TVectorRec): TVectorRec;
  52. class operator Add(V: TVectorRec; Scalar: Extended): TVectorRec;
  53. class operator Add(Scalar: Extended; V: TVectorRec): TVectorRec;
  54. class operator Subtract(V1, V2: TVectorRec): TVectorRec;
  55. class operator Subtract(Scalar: Extended; V: TVectorRec): TVectorRec;
  56. class operator Subtract(V: TVectorRec; Scalar: Extended): TVectorRec;
  57. class operator Multiply(V1, V2: TVectorRec): TVectorRec;
  58. class operator Multiply(V: TVectorRec; Scalar: Extended): TVectorRec;
  59. class operator Multiply(Scalar: Extended; V: TVectorRec): TVectorRec;
  60. class operator Divide(V: TVectorRec; Scalar: Extended): TVectorRec;
  61. class operator Divide(V1, V2: TVectorRec): TVectorRec;
  62. class operator Implicit(V: TVectorExt): TVectorRec;
  63. function Norm: Extended;
  64. function SumOfSquares: Extended;
  65. function SumOfElments: Extended;
  66. function TruncateSTI: TVectorRec;
  67. function ToQuat: TQuaternionRec;
  68. procedure Fill(Value: Extended);
  69. function ScalarMult(V: TVectorRec): Extended;
  70. property Count: Word read FCount;
  71. property Elements[index: Word]: Extended read GetElement
  72. write SetElement; default;
  73. end;
  74. PMatrixRec = ^TMatrixRec;
  75. TMatrixRec = record
  76. private
  77. FData: TMatrixExt;
  78. FRowsCount: Word;
  79. FColsCount: Word;
  80. procedure SetElement(Row, Col: Word; Value: Extended);
  81. function GetElement(Row, Col: Word): Extended;
  82. function GetRow(Row: Word): TVectorRec;
  83. procedure SetRow(Row: Word; Value: TVectorRec);
  84. function GetCol(Col: Word): TVectorRec;
  85. procedure SetCol(Col: Word; Value: TVectorRec);
  86. function Del(A: TMatrixRec; I, J: Integer; M: Integer): TMatrixRec;
  87. function Det(A: TMatrixRec; M: Integer): Extended;
  88. procedure CheckUnique;
  89. public
  90. constructor Create(RowsCount, ColsCount: Word); overload;
  91. constructor CreateDiag(Dim: Word; Value: Extended = 1.0);
  92. constructor Create(M: TMatrixExt); overload;
  93. class operator Add(M1, M2: TMatrixRec): TMatrixRec;
  94. class operator Subtract(M1, M2: TMatrixRec): TMatrixRec;
  95. class operator Multiply(M1, M2: TMatrixRec): TMatrixRec;
  96. class operator Multiply(M: TMatrixRec; V: TVectorRec): TVectorRec;
  97. class operator Multiply(V: TVectorRec; M: TMatrixRec): TVectorRec;
  98. class operator Multiply(M: TMatrixRec; Scalar: Extended): TMatrixRec;
  99. class operator Multiply(Scalar: Extended; M: TMatrixRec): TMatrixRec;
  100. class operator Multiply(M: TMatrixRec; Q: TQuaternionRec): TQuaternionRec;
  101. class operator Implicit(M: TMatrixExt): TMatrixRec;
  102. function Transp: TMatrixRec;
  103. function Inv: TMatrixRec;
  104. function ToQuat: TQuaternionRec;
  105. function Determinant: Extended;
  106. function TruncateSTI: TMatrixRec;
  107. function Trace: Extended; // sum on diagonal elements
  108. procedure Fill(Scalar: Extended);
  109. property RowCount: Word read FRowsCount;
  110. property ColCount: Word read FColsCount;
  111. property Row[Row: Word]: TVectorRec read GetRow write SetRow;
  112. property Col[Col: Word]: TVectorRec read GetCol write SetCol;
  113. property Elements[Row, Col: Word]: Extended read GetElement
  114. write SetElement; default;
  115. end;
  116. TQuaternionHelper = record helper for TQuaternionRec
  117. function ToMatrix: TMatrixRec;
  118. end;
  119. TVectorHelper = record helper for TVectorRec
  120. function ToDiagMatrix: TMatrixRec;
  121. end;
  122. TDim = class(TCustomAttribute)
  123. private
  124. FRowCount: Integer;
  125. FColCount: Integer;
  126. public
  127. constructor Create(ARowCount: Integer; AColCount: Integer = 0); overload;
  128. property RowCount: Integer read FRowCount;
  129. property ColCount: Integer read FColCount;
  130. end;
  131. function GetVectorRec(V: TVectorExt): TVectorRec;
  132. function GetMatrixRec(M: TMatrixExt): TMatrixRec;
  133. function GetQuaternionRec(Q: TVectorExt): TQuaternionRec;
  134. procedure Init(Obj, TypeInfoOfObj: Pointer; Offset: Integer = 0);
  135. // -----------------------
  136. // Point types
  137. // -----------------------
  138. type
  139. TGLScalarValue = Extended;
  140. TGLScalarField = function(X, Y, Z: Extended): TGLScalarValue;
  141. // if data are made on integer XYZ index may be replaced with BigIntegers
  142. TGLScalarFieldInt = function(iX, iY, iZ: Integer): TGLScalarValue of object;
  143. TVertexRec = record
  144. P, N: TVector3f; // Position and Normal
  145. Density: Extended;
  146. end;
  147. TFaceRec = record
  148. Normal: TVector3f;
  149. V1: TVector3f; // vertex 1
  150. V2: TVector3f; // vertex 2
  151. V3: TVector3f; // vertex 3
  152. Padding: array [0 .. 1] of Byte;
  153. end;
  154. PPoint2DRec = ^TPoint2DRec;
  155. TPoint2DRec = record
  156. X: Extended;
  157. Y: Extended;
  158. public
  159. function Create(X, Y: Extended): TPoint2DRec;
  160. procedure SetPosition(const X, Y: Extended);
  161. function Add(const APoint2D: TPoint2DRec): TPoint2DRec;
  162. function Length: Extended; // distance to origin
  163. function Distance(const APoint2D: TPoint2DRec): Extended;
  164. class function PointInCircle(const Point, Center: TPoint2DRec;
  165. const Radius: Integer): Boolean; static; inline;
  166. procedure Offset(const ADeltaX, ADeltaY: Extended);
  167. end;
  168. PPoint3DRec = ^TPoint3DRec;
  169. TPoint3DRec = record
  170. X: Extended;
  171. Y: Extended;
  172. Z: Extended;
  173. public
  174. function Create(X, Y, Z: Extended): TPoint3DRec;
  175. procedure SetPosition(const X, Y, Z: Extended);
  176. function Add(const AGLPoint3D: TPoint3DRec): TPoint3DRec;
  177. function Length: Single; // distance to origin
  178. function Distance(const APoint3D: TPoint3DRec): Extended;
  179. procedure Offset(const ADeltaX, ADeltaY, ADeltaZ: Extended);
  180. end;
  181. TPoint2DArray = array of TPoint2DRec;
  182. TPoint3DArray = array of TPoint3DRec;
  183. // Voxel types
  184. TVoxelStatus = (bpExternal, bpInternal);
  185. PVoxelRec = ^TVoxelRec;
  186. TVoxelRec = record
  187. P: TVector3f;
  188. Density: TGLScalarValue;
  189. Status: TVoxelStatus;
  190. end;
  191. TVoxelData = array [0 .. (MaxInt shr 8)] of TVoxelRec;
  192. PVoxelData = ^TVoxelData;
  193. // -----------------------
  194. // Vector types
  195. // -----------------------
  196. TVector2DType = array [0 .. 1] of Extended;
  197. TVector3DType = array [0 .. 2] of Extended;
  198. TVector2DRec = record
  199. function Create(const AX, AY, AW: Single): TVector2DRec;
  200. function Add(const AVector2D: TVector2DRec): TVector2DRec;
  201. function Length: Extended;
  202. function Norm: Extended;
  203. function Normalize: TVector2DRec;
  204. function CrossProduct(const AVector: TVector2DRec): TVector2DRec;
  205. function DotProduct(const AVector: TVector2DRec): Extended;
  206. case Integer of
  207. 0:
  208. (V: TVector2DType;);
  209. 1:
  210. (X: Extended;
  211. Y: Extended;
  212. W: Extended;)
  213. end;
  214. TVector3DRec = record
  215. function Create(const AX, AY, AZ, AW: Single): TVector3DRec;
  216. function Add(const AVector3D: TVector3DRec): TVector3DRec;
  217. function Length: Single;
  218. function Norm: Single;
  219. function Normalize: TVector3DRec;
  220. function CrossProduct(const AVector3D: TVector3D): TVector3D;
  221. function DotProduct(const AVector3D: TVector3D): Single; inline;
  222. case Integer of
  223. 0:
  224. (V: TVector3DType;);
  225. 1:
  226. (X: Extended;
  227. Y: Extended;
  228. Z: Extended;
  229. W: Extended;)
  230. end;
  231. // Vector Arrays
  232. TVector2DArray = array of TVector2DRec;
  233. TVector3DArray = array of TVector3DRec;
  234. // -----------------------
  235. // Matrix types
  236. // -----------------------
  237. TMatrix2DType = array [0 .. 3] of TVector2DRec;
  238. TMatrix3DType = array [0 .. 3] of TVector3DRec;
  239. TMatrix2DRec = record
  240. private
  241. public
  242. case Integer of
  243. 0:
  244. (M: TMatrix2DType;);
  245. 1:
  246. (e11, e12, e13: Single;
  247. e21, e22, e23: Single;
  248. e31, e32, e33: Single);
  249. end;
  250. TMatrix3DRec = record
  251. private
  252. public
  253. case Integer of
  254. 0:
  255. (M: TMatrix3DType;);
  256. 1:
  257. (e11, e12, e13, e14: Single;
  258. e21, e22, e23, e24: Single;
  259. e31, e32, e33, e34: Single;
  260. e41, e42, e43, e44: Single);
  261. end;
  262. // Matrix Arrays
  263. TMatrix2DArray = array of TMatrix2DRec;
  264. TMatrix3DArray = array of TMatrix3DRec;
  265. // -----------------------
  266. // Polygon types
  267. // -----------------------
  268. TPolygon2D = TPoint2DArray;
  269. TPolygon3D = TPoint3DArray;
  270. (*
  271. TPolygon3D = record
  272. Vertices: array of TPoint3DRec;
  273. function Length;
  274. end;
  275. *)
  276. const
  277. ClosedPolygon2D: TPoint2DRec = (X: $FFFF; Y: $FFFF);
  278. ClosedPolygon3D: TPoint3DRec = (X: $FFFF; Y: $FFFF; Z: $FFFF);
  279. type
  280. PVertArray = ^TVertArray;
  281. TVertArray = array [0 .. (MaxInt shr 8)] of TVertexRec;
  282. type
  283. TTriangleRec = record
  284. V1, V2, V3: Integer;
  285. /// Vertices: array[0..2] of TPoint3DRec;
  286. /// function Area;
  287. end;
  288. PTriangleRecArray = ^TTriangleRecArray;
  289. TTriangleRecArray = array [0 .. (MaxInt shr 8)] of TTriangleRec;
  290. // -----------------------
  291. // Polyhedron types
  292. // -----------------------
  293. type
  294. TPolyhedronArray = array of TPolygon3D;
  295. (*
  296. TPolyhedron = record
  297. Facets: array of TGLPolygon3D;
  298. function NetLength;
  299. function Area;
  300. function Volume;
  301. end;
  302. *)
  303. // --------------------------
  304. // Mesh simple record types
  305. // --------------------------
  306. type
  307. TMesh2DVert = record
  308. X, Y: Single;
  309. NX, NY: Single;
  310. tU, tV: Single;
  311. end;
  312. TMesh3DVert = packed record
  313. X, Y, Z: Single;
  314. NX, NY, NZ: Single;
  315. tU, tV: Single;
  316. end;
  317. TMesh2DArray = array of TMesh2DVert;
  318. TMesh3DArray = array of TMesh3DVert;
  319. // --------------------------
  320. // Quaternion simple record types
  321. // --------------------------
  322. type
  323. TQuat3DRec = record
  324. ImPart: TVector3DRec;
  325. RePart: Single;
  326. end;
  327. TQuatArray = array of TQuat3DRec;
  328. type
  329. TBoxRec = record
  330. ALeft, ATop, ANear, ARight, ABottom, AFar: Single;
  331. end;
  332. const
  333. sWRONG_ELEMENT = 'Wrong element';
  334. sWRONG_SIZE = 'Wrong size';
  335. sNOT_QUAD = 'Matrix not quadratic';
  336. sSINGULAR = 'Singular matrix founded';
  337. // ---------------------------------------------------------------
  338. implementation
  339. // ---------------------------------------------------------------
  340. function GetVectorRec(V: TVectorExt): TVectorRec;
  341. begin
  342. Result.Create(V);
  343. end;
  344. function GetMatrixRec(M: TMatrixExt): TMatrixRec;
  345. begin
  346. Result.Create(M);
  347. end;
  348. function GetQuaternionRec(Q: TVectorExt): TQuaternionRec;
  349. begin
  350. Result.Create(Q);
  351. end;
  352. {$POINTERMATH ON}
  353. function NotUnique(PArr: PCardinal): Boolean;
  354. begin
  355. Result := (PArr - 2)^ > 1;
  356. end;
  357. // -------------------------------------
  358. // TMatrixRec
  359. // -------------------------------------
  360. // Removing i-th row and j-th col
  361. function TMatrixRec.Del(A: TMatrixRec; I, J: Integer; M: Integer): TMatrixRec;
  362. var
  363. K, G: Integer;
  364. begin
  365. for G := I to M - 1 do
  366. for K := 1 to M do
  367. A[G, K] := A[G + 1, K];
  368. for G := J to M - 1 do
  369. for K := 1 to M - 1 do
  370. A[K, G] := A[K, G + 1];
  371. Result := A;
  372. end;
  373. // Recursive calculation of det for matrix
  374. function TMatrixRec.Det(A: TMatrixRec; M: Integer): Extended;
  375. var
  376. I: Integer;
  377. Buf: Extended;
  378. begin
  379. Buf := 0;
  380. if M = 1 then
  381. Buf := A[1, 1]
  382. else
  383. for I := 1 to M do
  384. Buf := Buf + Power10(-1, I + 1) * A[I, 1] * Det(Del(A, I, 1, M), M - 1);
  385. Result := Buf;
  386. end;
  387. class operator TMatrixRec.Add(M1, M2: TMatrixRec): TMatrixRec;
  388. var
  389. I, J: Integer;
  390. begin
  391. if (M1.FRowsCount <> M2.FRowsCount) or (M1.FColsCount <> M2.FColsCount) then
  392. raise EMathError.Create(sWRONG_SIZE);
  393. Result.Create(M1.FRowsCount, M1.FColsCount);
  394. for I := 0 to M1.FRowsCount - 1 do
  395. for J := 0 to M1.FColsCount - 1 do
  396. Result.FData[I, J] := M1.FData[I, J] + M2.FData[I, J];
  397. end;
  398. procedure TMatrixRec.CheckUnique;
  399. var
  400. I: Integer;
  401. begin
  402. if NotUnique(@FData) then
  403. begin
  404. FData := Copy(FData);
  405. for I := 0 to Pred(FRowsCount) do
  406. FData[I] := Copy(FData[I]);
  407. end;
  408. end;
  409. constructor TMatrixRec.Create(RowsCount, ColsCount: Word);
  410. begin
  411. FRowsCount := RowsCount;
  412. FColsCount := ColsCount;
  413. FData := nil;
  414. SetLength(FData, FRowsCount, FColsCount);
  415. end;
  416. constructor TMatrixRec.Create(M: TMatrixExt);
  417. var
  418. I: Integer;
  419. begin
  420. FRowsCount := Length(M);
  421. FColsCount := Length(M[0]);
  422. FData := nil;
  423. SetLength(FData, FRowsCount, FColsCount);
  424. for I := 0 to Pred(FRowsCount) do
  425. begin
  426. if Length(M[I]) <> FColsCount then
  427. raise EMathError.Create('Wrong matrix proportions');
  428. FData[I] := Copy(M[I]);
  429. end;
  430. end;
  431. constructor TMatrixRec.CreateDiag(Dim: Word; Value: Extended = 1.0);
  432. var
  433. I: Integer;
  434. begin
  435. Create(Dim, Dim);
  436. for I := 0 to Dim - 1 do
  437. FData[I, I] := Value;
  438. end;
  439. function TMatrixRec.Determinant: Extended;
  440. begin
  441. if (FRowsCount <> FColsCount) then
  442. raise EMathError.Create(sNOT_QUAD);
  443. Result := Det(Self, FRowsCount);
  444. end;
  445. procedure TMatrixRec.Fill(Scalar: Extended);
  446. var
  447. I, J: Integer;
  448. begin
  449. if Scalar = 0 then
  450. begin
  451. FData := nil;
  452. SetLength(FData, FRowsCount, FColsCount);
  453. end
  454. else
  455. for I := 0 to FRowsCount - 1 do
  456. for J := 0 to FColsCount - 1 do
  457. FData[I, J] := Scalar;
  458. end;
  459. function TMatrixRec.GetCol(Col: Word): TVectorRec;
  460. var
  461. I: Integer;
  462. begin
  463. if (Col = 0) or (Col > FColsCount) then
  464. raise EMathError.Create(sWRONG_ELEMENT);
  465. Result.Create(FRowsCount);
  466. for I := 0 to FRowsCount - 1 do
  467. Result.FData[I] := FData[I, Col - 1];
  468. end;
  469. function TMatrixRec.GetElement(Row, Col: Word): Extended;
  470. begin
  471. {$R+}
  472. Result := FData[Pred(Row), Pred(Col)];
  473. end;
  474. function TMatrixRec.GetRow(Row: Word): TVectorRec;
  475. var
  476. I: Integer;
  477. begin
  478. if (Row = 0) or (Row > FRowsCount) then
  479. raise EMathError.Create(sWRONG_ELEMENT);
  480. Result.Create(FColsCount);
  481. for I := 0 to FColsCount - 1 do
  482. Result.FData[I] := FData[Row - 1, I];
  483. end;
  484. class operator TMatrixRec.Implicit(M: TMatrixExt): TMatrixRec;
  485. begin
  486. Result.Create(M);
  487. end;
  488. // --------------------------------------------------------
  489. function TMatrixRec.Inv: TMatrixRec;
  490. var
  491. Ipiv, Indxr, Indxc: array of Integer;
  492. DimMat, I, J, K, L, N, ICol, IRow: Integer;
  493. Big, Dum, Pivinv: Extended;
  494. begin
  495. // Jordan algorithm
  496. if (FRowsCount <> FColsCount) then
  497. raise EMathError.Create(sNOT_QUAD);
  498. Result := Self;
  499. DimMat := FRowsCount;
  500. SetLength(Ipiv, DimMat);
  501. SetLength(Indxr, DimMat);
  502. SetLength(Indxc, DimMat);
  503. IRow := 1;
  504. ICol := 1;
  505. for I := 1 to DimMat do
  506. begin
  507. Big := 0;
  508. for J := 1 to DimMat do
  509. if (Ipiv[J - 1] <> 1) then
  510. for K := 1 to DimMat do
  511. if (Ipiv[K - 1] = 0) then
  512. if (Abs(Result[J, K]) >= Big) then
  513. begin
  514. Big := Abs(Result[J, K]);
  515. IRow := J;
  516. ICol := K;
  517. end;
  518. Ipiv[ICol - 1] := Ipiv[ICol - 1] + 1;
  519. if (IRow <> ICol) then
  520. for L := 1 to DimMat do
  521. begin
  522. Dum := Result[IRow, L];
  523. Result[IRow, L] := Result[ICol, L];
  524. Result[ICol, L] := Dum;
  525. end;
  526. Indxr[I - 1] := IRow;
  527. Indxc[I - 1] := ICol;
  528. if Result[ICol, ICol] = 0 then
  529. raise EMathError.Create(sSINGULAR);
  530. Pivinv := 1.0 / Result[ICol, ICol];
  531. Result[ICol, ICol] := 1.0;
  532. for L := 1 to DimMat do
  533. Result[ICol, L] := Result[ICol, L] * Pivinv;
  534. for N := 1 to DimMat do
  535. if (N <> ICol) then
  536. begin
  537. Dum := Result[N, ICol];
  538. Result[N, ICol] := 0.0;
  539. for L := 1 to DimMat do
  540. Result[N, L] := Result[N, L] - Result[ICol, L] * Dum;
  541. end;
  542. end;
  543. for L := DimMat downto 1 do
  544. if (Indxr[L - 1] <> Indxc[L - 1]) then
  545. for K := 1 to DimMat do
  546. begin
  547. Dum := Result[K, Indxr[L - 1]];
  548. Result[K, Indxr[L - 1]] := Result[K, Indxc[L - 1]];
  549. Result[K, Indxc[L - 1]] := Dum;
  550. end;
  551. end;
  552. function TMatrixRec.ToQuat: TQuaternionRec;
  553. begin
  554. Result[0] := 0.5 * Sqrt(Abs(1 + Self[1, 1] + Self[2, 2] + Self[3, 3]));
  555. Result[1] := 0.5 * Sqrt(Abs(1 + Self[1, 1] - Self[2, 2] - Self[3, 3]));
  556. if Self[3, 2] < Self[2, 3] then
  557. Result[1] := -Result[1];
  558. Result[2] := 0.5 * Sqrt(Abs(1 - Self[1, 1] + Self[2, 2] - Self[3, 3]));
  559. if Self[1, 3] < Self[3, 1] then
  560. Result[2] := -Result[2];
  561. Result[3] := 0.5 * Sqrt(Abs(1 - Self[1, 1] - Self[2, 2] + Self[3, 3]));
  562. if Self[2, 1] < Self[1, 2] then
  563. Result[3] := -Result[3];
  564. end;
  565. class operator TMatrixRec.Multiply(M: TMatrixRec; Q: TQuaternionRec)
  566. : TQuaternionRec;
  567. var
  568. I, J: Integer;
  569. begin
  570. if (M.FRowsCount <> 4) or (M.FRowsCount <> M.FColsCount) then
  571. raise EMathError.Create(sWRONG_SIZE);
  572. FillChar(Result.FData, SizeOf(Result.FData), 0);
  573. for I := 0 to 3 do
  574. for J := 0 to 3 do
  575. Result.FData[I] := Result.FData[I] + M.FData[I, J] * Q.FData[J];
  576. end;
  577. class operator TMatrixRec.Multiply(Scalar: Extended; M: TMatrixRec): TMatrixRec;
  578. begin
  579. Result := M * Scalar;
  580. end;
  581. class operator TMatrixRec.Multiply(V: TVectorRec; M: TMatrixRec): TVectorRec;
  582. var
  583. I, J: Integer;
  584. begin
  585. if (V.FCount <> M.FRowsCount) then
  586. raise EMathError.Create(sWRONG_SIZE);
  587. Result.Create(V.FCount);
  588. for I := 0 to V.FCount - 1 do
  589. for J := 0 to V.FCount - 1 do
  590. Result.FData[I] := Result.FData[I] + V.FData[J] * M.FData[J, I];
  591. end;
  592. class operator TMatrixRec.Multiply(M: TMatrixRec; V: TVectorRec): TVectorRec;
  593. var
  594. I, J: Integer;
  595. begin
  596. if (M.FColsCount <> V.FCount) then
  597. raise EMathError.Create(sWRONG_SIZE);
  598. Result.Create(M.FRowsCount);
  599. for I := 0 to M.FRowsCount - 1 do
  600. for J := 0 to M.FColsCount - 1 do
  601. Result.FData[I] := Result.FData[I] + M.FData[I, J] * V.FData[J];
  602. end;
  603. class operator TMatrixRec.Multiply(M: TMatrixRec; Scalar: Extended): TMatrixRec;
  604. var
  605. I, J: Integer;
  606. begin
  607. Result.Create(M.FRowsCount, M.FColsCount);
  608. for I := 0 to M.FRowsCount - 1 do
  609. for J := 0 to M.FColsCount - 1 do
  610. Result.FData[I, J] := M.FData[I, J] * Scalar;
  611. end;
  612. class operator TMatrixRec.Multiply(M1, M2: TMatrixRec): TMatrixRec;
  613. var
  614. I, J, K: Integer;
  615. begin
  616. if (M1.FColsCount <> M2.FRowsCount) then
  617. raise EMathError.Create(sWRONG_SIZE);
  618. Result.Create(M1.FRowsCount, M2.FColsCount);
  619. for I := 0 to M1.FRowsCount - 1 do
  620. for J := 0 to M2.FColsCount - 1 do
  621. for K := 0 to M1.FColsCount - 1 do
  622. Result.FData[I, J] := Result.FData[I, J] + M1.FData[I, K] *
  623. M2.FData[K, J];
  624. end;
  625. procedure TMatrixRec.SetCol(Col: Word; Value: TVectorRec);
  626. var
  627. I: Integer;
  628. begin
  629. if (Col = 0) or (Col > FColsCount) then
  630. raise EMathError.Create(sWRONG_ELEMENT);
  631. if (Value.Count <> FRowsCount) then
  632. raise EMathError.Create(sWRONG_SIZE);
  633. for I := 0 to FRowsCount - 1 do
  634. FData[I, Col - 1] := Value.FData[I];
  635. end;
  636. procedure TMatrixRec.SetElement(Row, Col: Word; Value: Extended);
  637. begin
  638. {$R+}
  639. CheckUnique;
  640. FData[Pred(Row), Pred(Col)] := Value;
  641. end;
  642. procedure TMatrixRec.SetRow(Row: Word; Value: TVectorRec);
  643. var
  644. I: Integer;
  645. begin
  646. if (Row = 0) or (Row > FRowsCount) then
  647. raise EMathError.Create(sWRONG_ELEMENT);
  648. if (Value.Count <> FColsCount) then
  649. raise EMathError.Create(sWRONG_SIZE);
  650. for I := 0 to FColsCount - 1 do
  651. FData[Row - 1, I] := Value.FData[I];
  652. end;
  653. class operator TMatrixRec.Subtract(M1, M2: TMatrixRec): TMatrixRec;
  654. var
  655. I, J: Integer;
  656. begin
  657. if (M1.FColsCount <> M2.FColsCount) or (M1.FRowsCount <> M2.FRowsCount) then
  658. raise EMathError.Create(sWRONG_SIZE);
  659. Result.Create(M1.FRowsCount, M1.FColsCount);
  660. for I := 0 to M1.FRowsCount - 1 do
  661. for J := 0 to M1.FColsCount - 1 do
  662. Result.FData[I, J] := M1.FData[I, J] - M2.FData[I, J];
  663. end;
  664. function TMatrixRec.Trace: Extended;
  665. var
  666. I: Integer;
  667. begin
  668. Result := 0;
  669. if FColsCount <> FRowsCount then
  670. raise EMathError.Create(sNOT_QUAD);
  671. for I := 0 to FColsCount - 1 do
  672. Result := Result + FData[I, I];
  673. end;
  674. function TMatrixRec.Transp: TMatrixRec;
  675. var
  676. I, J: Integer;
  677. begin
  678. Result.Create(FColsCount, FRowsCount);
  679. for I := 0 to FColsCount - 1 do
  680. for J := 0 to FRowsCount - 1 do
  681. Result.FData[I, J] := FData[J, I];
  682. end;
  683. function TMatrixRec.TruncateSTI: TMatrixRec;
  684. const
  685. Int32Max: Double = Integer.MaxValue;
  686. Int32Min: Double = Integer.MinValue;
  687. var
  688. I, J: Integer;
  689. begin
  690. Result.Create(FRowsCount, FColsCount);
  691. for I := 0 to FRowsCount - 1 do
  692. for J := 0 to FColsCount - 1 do
  693. begin
  694. if (FData[I, J] >= Int32Min) and (FData[I, J] <= Int32Max) then
  695. Result.FData[I, J] := Trunc(FData[I, J])
  696. else if (FData[I, J] < Int32Min) then
  697. Result.FData[I, J] := Int32Min
  698. else
  699. Result.FData[I, J] := Int32Max;
  700. end;
  701. end;
  702. // -----------------------------
  703. // TVectorRec
  704. // -----------------------------
  705. constructor TVectorRec.Create(V: TVectorExt);
  706. begin
  707. FCount := Length(V);
  708. FData := Copy(V);
  709. end;
  710. constructor TVectorRec.Create(ElementsCount: Word);
  711. begin
  712. FCount := ElementsCount;
  713. FData := nil;
  714. SetLength(FData, FCount);
  715. end;
  716. class operator TVectorRec.Add(V1, V2: TVectorRec): TVectorRec;
  717. var
  718. I: Integer;
  719. begin
  720. if (V1.FCount <> V2.FCount) then
  721. raise EMathError.Create(sWRONG_SIZE);
  722. Result := TVectorRec.Create(V1.FCount);
  723. for I := 0 to V1.FCount - 1 do
  724. Result.FData[I] := V1.FData[I] + V2.FData[I];
  725. end;
  726. class operator TVectorRec.Add(V: TVectorRec; Scalar: Extended): TVectorRec;
  727. var
  728. I: Integer;
  729. begin
  730. Result.Create(V.FCount);
  731. for I := 0 to V.FCount - 1 do
  732. Result.FData[I] := V.FData[I] + Scalar;
  733. end;
  734. class operator TVectorRec.Add(Scalar: Extended; V: TVectorRec): TVectorRec;
  735. begin
  736. Result := V + Scalar;
  737. end;
  738. procedure TVectorRec.CheckUnique;
  739. begin
  740. if NotUnique(@FData) then
  741. FData := Copy(FData);
  742. end;
  743. class operator TVectorRec.Divide(V1, V2: TVectorRec): TVectorRec;
  744. var
  745. I: Integer;
  746. begin
  747. if (V1.FCount <> V2.FCount) then
  748. raise EMathError.Create(sWRONG_SIZE);
  749. Result.Create(V1.FCount);
  750. for I := 0 to V1.FCount - 1 do
  751. Result.FData[I] := V1.FData[I] / V2.FData[I];
  752. end;
  753. class operator TVectorRec.Divide(V: TVectorRec; Scalar: Extended): TVectorRec;
  754. begin
  755. Result := V * (1 / Scalar);
  756. end;
  757. class operator TVectorRec.Implicit(V: TVectorExt): TVectorRec;
  758. begin
  759. Result.Create(V);
  760. end;
  761. procedure TVectorRec.Fill(Value: Extended);
  762. var
  763. I: Integer;
  764. begin
  765. if Value = 0 then
  766. begin
  767. FData := nil;
  768. SetLength(FData, FCount);
  769. end
  770. else
  771. for I := 0 to FCount - 1 do
  772. FData[I] := Value;
  773. end;
  774. function TVectorRec.GetElement(Index: Word): Extended;
  775. begin
  776. if (Index = 0) or (Index > FCount) then
  777. raise EMathError.Create(sWRONG_ELEMENT);
  778. Result := FData[Pred(Index)];
  779. end;
  780. class operator TVectorRec.Multiply(V: TVectorRec; Scalar: Extended): TVectorRec;
  781. var
  782. I: Integer;
  783. begin
  784. Result.Create(V.FCount);
  785. for I := 0 to V.FCount - 1 do
  786. Result.FData[I] := V.FData[I] * Scalar;
  787. end;
  788. class operator TVectorRec.Multiply(Scalar: Extended; V: TVectorRec): TVectorRec;
  789. begin
  790. Result := V * Scalar;
  791. end;
  792. function TVectorRec.Norm: Extended;
  793. begin
  794. Result := System.Math.Norm(FData);
  795. end;
  796. class operator TVectorRec.Multiply(V1, V2: TVectorRec): TVectorRec;
  797. begin
  798. if (V1.FCount <> 3) or (V2.FCount <> 3) then
  799. raise EMathError.Create(sWRONG_SIZE);
  800. Result.Create(V1.FCount);
  801. Result.FData[0] := V1.FData[1] * V2.FData[2] - V1.FData[2] * V2.FData[1];
  802. Result.FData[1] := V1.FData[2] * V2.FData[0] - V1.FData[0] * V2.FData[2];
  803. Result.FData[2] := V1.FData[0] * V2.FData[1] - V1.FData[1] * V2.FData[0];
  804. end;
  805. function TVectorRec.ScalarMult(V: TVectorRec): Extended;
  806. var
  807. I: Integer;
  808. begin
  809. if V.FCount <> FCount then
  810. raise EMathError.Create(sWRONG_SIZE);
  811. Result := 0.0;
  812. for I := 0 to FCount - 1 do
  813. Result := Result + FData[I] * V.FData[I];
  814. end;
  815. procedure TVectorRec.SetElement(Index: Word; Value: Extended);
  816. begin
  817. if (Index = 0) or (Index > FCount) then
  818. raise EMathError.Create(sWRONG_ELEMENT);
  819. CheckUnique;
  820. FData[Pred(Index)] := Value;
  821. end;
  822. class operator TVectorRec.Subtract(V1, V2: TVectorRec): TVectorRec;
  823. var
  824. I: Integer;
  825. begin
  826. if (V1.FCount <> V2.FCount) then
  827. raise EMathError.Create(sWRONG_SIZE);
  828. Result.Create(V1.FCount);
  829. for I := 0 to V1.FCount - 1 do
  830. Result.FData[I] := V1.FData[I] - V2.FData[I];
  831. end;
  832. class operator TVectorRec.Subtract(Scalar: Extended; V: TVectorRec): TVectorRec;
  833. var
  834. I: Integer;
  835. begin
  836. Result.Create(V.FCount);
  837. for I := 0 to V.FCount - 1 do
  838. Result.FData[I] := Scalar - V.FData[I];
  839. end;
  840. class operator TVectorRec.Subtract(V: TVectorRec; Scalar: Extended): TVectorRec;
  841. var
  842. I: Integer;
  843. begin
  844. Result.Create(V.FCount);
  845. for I := 0 to V.Count - 1 do
  846. Result.FData[I] := V.FData[I] - Scalar;
  847. end;
  848. function TVectorRec.SumOfElments: Extended;
  849. begin
  850. Result := Sum(FData);
  851. end;
  852. function TVectorRec.SumOfSquares: Extended;
  853. begin
  854. Result := System.Math.SumOfSquares(FData);
  855. end;
  856. function TVectorRec.ToQuat: TQuaternionRec;
  857. var
  858. ModVec: Extended;
  859. C1, C2: Extended;
  860. begin
  861. if (FCount <> 3) then
  862. raise EMathError.Create(sWRONG_SIZE);
  863. ModVec := Norm;
  864. C1 := Cos(ModVec / 2);
  865. if ModVec > 1E-15 then
  866. C2 := Sin(ModVec / 2) / ModVec
  867. else
  868. C2 := 1;
  869. Result := [C1, FData[0] * C2, FData[1] * C2, FData[2] * C2];
  870. end;
  871. function TVectorRec.TruncateSTI: TVectorRec;
  872. const
  873. Int32Max: Double = Integer.MaxValue;
  874. Int32Min: Double = Integer.MinValue;
  875. var
  876. I: Integer;
  877. begin
  878. Result.Create(FCount);
  879. for I := 0 to FCount - 1 do
  880. begin
  881. if (FData[I] >= Int32Min) and (FData[I] <= Int32Max) then
  882. Result.FData[I] := Trunc(FData[I])
  883. else if (FData[I] < Int32Min) then
  884. Result.FData[I] := Int32Min
  885. else
  886. Result.FData[I] := Int32Max;
  887. end;
  888. end;
  889. // -----------------------------
  890. // TQuaternionHelper
  891. // -----------------------------
  892. function TQuaternionHelper.ToMatrix: TMatrixRec;
  893. begin
  894. Result.Create(3, 3);
  895. Result[1, 1] := Sqr(FData[0]) + Sqr(FData[1]) - Sqr(FData[2]) - Sqr(FData[3]);
  896. Result[1, 2] := 2 * (FData[1] * FData[2] - FData[0] * FData[3]);
  897. Result[1, 3] := 2 * (FData[1] * FData[3] + FData[0] * FData[2]);
  898. Result[2, 1] := 2 * (FData[1] * FData[2] + FData[0] * FData[3]);
  899. Result[2, 2] := Sqr(FData[0]) - Sqr(FData[1]) + Sqr(FData[2]) - Sqr(FData[3]);
  900. Result[2, 3] := 2 * (FData[2] * FData[3] - FData[0] * FData[1]);
  901. Result[3, 1] := 2 * (FData[1] * FData[3] - FData[0] * FData[2]);
  902. Result[3, 2] := 2 * (FData[2] * FData[3] + FData[0] * FData[1]);
  903. Result[3, 3] := Sqr(FData[0]) - Sqr(FData[1]) - Sqr(FData[2]) + Sqr(FData[3]);
  904. end;
  905. // -----------------------------
  906. // TVectorHelper
  907. // -----------------------------
  908. function TVectorHelper.ToDiagMatrix: TMatrixRec;
  909. var
  910. I: Integer;
  911. begin
  912. Result.Create(FCount, FCount);
  913. for I := 0 to FCount - 1 do
  914. Result.FData[I, I] := FData[I];
  915. end;
  916. procedure Init(Obj, TypeInfoOfObj: Pointer; Offset: Integer = 0);
  917. const
  918. DefaultRowCount = 3;
  919. DefaultColCount = 3;
  920. VectorTypeName = 'TVectorRec';
  921. MatrixTypeName = 'TMatrixRec';
  922. var
  923. RTTIContext: TRttiContext;
  924. Field: TRttiField;
  925. ArrFld: TRttiArrayType;
  926. I: Integer;
  927. Dim: TCustomAttribute;
  928. RowCount, ColCount: Integer;
  929. OffsetFromArray: Integer;
  930. begin
  931. for Field in RTTIContext.GetType(TypeInfoOfObj).GetFields do
  932. begin
  933. if Field.FieldType <> nil then
  934. begin
  935. RowCount := DefaultRowCount;
  936. ColCount := DefaultColCount;
  937. for Dim in Field.GetAttributes do
  938. begin
  939. RowCount := (Dim as TDim).RowCount;
  940. ColCount := (Dim as TDim).ColCount;
  941. end;
  942. if Field.FieldType.TypeKind = tkArray then
  943. begin
  944. ArrFld := TRttiArrayType(Field.FieldType);
  945. if ArrFld.ElementType.TypeKind = tkRecord then
  946. begin
  947. for I := 0 to ArrFld.TotalElementCount - 1 do
  948. begin
  949. OffsetFromArray := I * ArrFld.ElementType.TypeSize;
  950. if ArrFld.ElementType.Name = VectorTypeName then
  951. PVectorRec(Integer(Obj) + Field.Offset + OffsetFromArray + Offset)
  952. ^ := TVectorRec.Create(RowCount)
  953. else if ArrFld.ElementType.Name = MatrixTypeName then
  954. PMatrixRec(Integer(Obj) + Field.Offset + OffsetFromArray + Offset)
  955. ^ := TMatrixRec.Create(RowCount, ColCount)
  956. else
  957. Init(Obj, ArrFld.ElementType.Handle,
  958. Field.Offset + OffsetFromArray);
  959. end;
  960. end;
  961. end
  962. else if Field.FieldType.TypeKind = tkRecord then
  963. begin
  964. if Field.FieldType.Name = VectorTypeName then
  965. PVectorRec(Integer(Obj) + Field.Offset + Offset)^ :=
  966. TVectorRec.Create(RowCount)
  967. else if Field.FieldType.Name = MatrixTypeName then
  968. PMatrixRec(Integer(Obj) + Field.Offset + Offset)^ :=
  969. TMatrixRec.Create(RowCount, ColCount)
  970. else
  971. Init(Obj, Field.FieldType.Handle, Field.Offset)
  972. end;
  973. end;
  974. end;
  975. end;
  976. // -----------------------------
  977. // TDim
  978. // -----------------------------
  979. constructor TDim.Create(ARowCount: Integer; AColCount: Integer = 0);
  980. begin
  981. FRowCount := ARowCount;
  982. FColCount := AColCount;
  983. end;
  984. // -----------------------------
  985. // TPoint2DRec
  986. // -----------------------------
  987. function TPoint2DRec.Create(X, Y: Extended): TPoint2DRec;
  988. begin
  989. Result.X := X;
  990. Result.Y := Y;
  991. end;
  992. procedure TPoint2DRec.SetPosition(const X, Y: Extended);
  993. begin
  994. Self.X := X;
  995. Self.Y := Y;
  996. end;
  997. function TPoint2DRec.Length: Extended;
  998. begin
  999. Result := Sqrt(Self.X * Self.X + Self.Y * Self.Y);
  1000. end;
  1001. function TPoint2DRec.Add(const APoint2D: TPoint2DRec): TPoint2DRec;
  1002. begin
  1003. Result.SetPosition(Self.X + APoint2D.X, Self.Y + APoint2D.Y);
  1004. end;
  1005. function TPoint2DRec.Distance(const APoint2D: TPoint2DRec): Extended;
  1006. begin
  1007. Result := Sqrt(Sqr(Self.X - APoint2D.X) + Sqr(Self.Y - APoint2D.Y));
  1008. end;
  1009. procedure TPoint2DRec.Offset(const ADeltaX, ADeltaY: Extended);
  1010. begin
  1011. Self.X := Self.X + ADeltaX;
  1012. Self.Y := Self.Y + ADeltaY;
  1013. end;
  1014. class function TPoint2DRec.PointInCircle(const Point, Center: TPoint2DRec;
  1015. const Radius: Integer): Boolean;
  1016. begin
  1017. Result := Point.Distance(Center) <= Radius;
  1018. end;
  1019. // -----------------------------
  1020. // TPoint3DRec
  1021. // -----------------------------
  1022. function TPoint3DRec.Create(X, Y, Z: Extended): TPoint3DRec;
  1023. begin
  1024. Result.X := X;
  1025. Result.Y := Y;
  1026. Result.Z := Z;
  1027. end;
  1028. function TPoint3DRec.Add(const AGLPoint3D: TPoint3DRec): TPoint3DRec;
  1029. begin
  1030. Result.X := Self.X + AGLPoint3D.X;
  1031. Result.Y := Self.Y + AGLPoint3D.Y;
  1032. Result.Z := Self.Z + AGLPoint3D.Z;
  1033. end;
  1034. function TPoint3DRec.Distance(const APoint3D: TPoint3DRec): Extended;
  1035. begin
  1036. Result := Self.Length - APoint3D.Length;
  1037. end;
  1038. function TPoint3DRec.Length: Single;
  1039. begin
  1040. Result := Sqrt(Self.X * Self.X + Self.Y * Self.Y + Self.Z * Self.Z);
  1041. end;
  1042. procedure TPoint3DRec.Offset(const ADeltaX, ADeltaY, ADeltaZ: Extended);
  1043. begin
  1044. Self.X := Self.X + ADeltaX;
  1045. Self.Y := Self.Y + ADeltaY;
  1046. Self.Z := Self.Z + ADeltaZ;
  1047. end;
  1048. procedure TPoint3DRec.SetPosition(const X, Y, Z: Extended);
  1049. begin
  1050. Self.X := X;
  1051. Self.Y := Y;
  1052. Self.Z := Z;
  1053. end;
  1054. // -----------------------------
  1055. // TVector2DRec
  1056. // -----------------------------
  1057. function TVector2DRec.Create(const AX, AY, AW: Single): TVector2DRec;
  1058. begin
  1059. Result.X := AX;
  1060. Result.Y := AY;
  1061. Result.W := AW;
  1062. end;
  1063. function TVector2DRec.CrossProduct(const AVector: TVector2DRec): TVector2DRec;
  1064. begin
  1065. Result.X := (Self.Y * AVector.W) - (Self.W * AVector.Y);
  1066. Result.Y := (Self.W * AVector.X) - (Self.X * AVector.W);
  1067. Result.W := (Self.X * AVector.Y) - (Self.Y * AVector.X);
  1068. end;
  1069. function TVector2DRec.DotProduct(const AVector: TVector2DRec): Extended;
  1070. begin
  1071. Result := (Self.X * AVector.X) + (Self.Y * AVector.Y) + (Self.W * AVector.W);
  1072. end;
  1073. function TVector2DRec.Add(const AVector2D: TVector2DRec): TVector2DRec;
  1074. begin
  1075. Result.X := Self.X + AVector2D.X;
  1076. Result.Y := Self.Y + AVector2D.Y;
  1077. Result.W := 1.0;
  1078. end;
  1079. function TVector2DRec.Length: Extended;
  1080. begin
  1081. Result := Sqrt((Self.X * Self.X) + (Self.Y * Self.Y));
  1082. end;
  1083. function TVector2DRec.Norm: Extended;
  1084. begin
  1085. Result := Sqr(Self.X) + Sqr(Self.Y);
  1086. end;
  1087. function TVector2DRec.Normalize: TVector2DRec;
  1088. var
  1089. invLen: Single;
  1090. vn: Single;
  1091. const
  1092. Tolerance: Single = 1E-12;
  1093. begin
  1094. vn := Self.Norm;
  1095. if vn > Tolerance then
  1096. begin
  1097. invLen := 1 / Sqrt(vn);
  1098. Result.X := Self.X * invLen;
  1099. Result.Y := Self.Y * invLen;
  1100. end
  1101. else
  1102. Result := Self;
  1103. end;
  1104. // ---------------------------------
  1105. // TVector3DRec
  1106. // ---------------------------------
  1107. function TVector3DRec.Create(const AX, AY, AZ, AW: Single): TVector3DRec;
  1108. begin
  1109. Result.X := AX;
  1110. Result.Y := AY;
  1111. Result.Z := AZ;
  1112. Result.W := AW;
  1113. end;
  1114. function TVector3DRec.Add(const AVector3D: TVector3DRec): TVector3DRec;
  1115. begin
  1116. Result.X := Self.X + AVector3D.X;
  1117. Result.Y := Self.Y + AVector3D.Y;
  1118. Result.Z := Self.Z + AVector3D.Z;
  1119. Result.W := 1.0;
  1120. end;
  1121. function TVector3DRec.Norm: Single;
  1122. begin
  1123. Result := Self.X * Self.X + Self.Y * Self.Y + Self.Z * Self.Z;
  1124. end;
  1125. function TVector3DRec.Normalize: TVector3DRec;
  1126. var
  1127. invLen: Single;
  1128. vn: Single;
  1129. const
  1130. Tolerance: Single = 1E-12;
  1131. begin
  1132. vn := Self.Norm;
  1133. if vn > 0 then
  1134. begin
  1135. invLen := 1 / Sqrt(vn);
  1136. Result.X := Self.X * invLen;
  1137. Result.Y := Self.Y * invLen;
  1138. Result.Z := Self.Z * invLen;
  1139. Result.W := 0;
  1140. end
  1141. else
  1142. Result := Self;
  1143. end;
  1144. function TVector3DRec.DotProduct(const AVector3D: TVector3D): Single;
  1145. begin
  1146. Result := (Self.X * AVector3D.X) + (Self.Y * AVector3D.Y) +
  1147. (Self.Z * AVector3D.Z);
  1148. end;
  1149. function TVector3DRec.CrossProduct(const AVector3D: TVector3D): TVector3D;
  1150. begin
  1151. Result.X := (Self.Y * AVector3D.Z) - (Self.Z * AVector3D.Y);
  1152. Result.Y := (Self.Z * AVector3D.X) - (Self.X * AVector3D.Z);
  1153. Result.Z := (Self.X * AVector3D.Y) - (Self.Y * AVector3D.X);
  1154. end;
  1155. function TVector3DRec.Length: Single;
  1156. begin
  1157. Result := Sqrt((Self.X * Self.X) + (Self.Y * Self.Y) + (Self.Z * Self.Z));
  1158. end;
  1159. // ---------------------------------
  1160. // TQuaternionRec
  1161. // ---------------------------------
  1162. function TQuaternionRec.GetElement(Index: Byte): Extended;
  1163. begin
  1164. if (Index > 3) then
  1165. raise EMathError.Create(sWRONG_ELEMENT);
  1166. Result := FData[Index];
  1167. end;
  1168. class operator TQuaternionRec.Implicit(V: TVectorExt): TQuaternionRec;
  1169. begin
  1170. if (Length(V) <> 4) then
  1171. raise EMathError.Create(sWRONG_SIZE);
  1172. Move(V[0], Result.FData, SizeOf(Result.FData));
  1173. end;
  1174. function TQuaternionRec.Inv: TQuaternionRec;
  1175. begin
  1176. Result := [FData[0], -FData[1], -FData[2], -FData[3]];
  1177. end;
  1178. class operator TQuaternionRec.Multiply(Scalar: Extended; Q: TQuaternionRec)
  1179. : TQuaternionRec;
  1180. begin
  1181. Result := Q * Scalar;
  1182. end;
  1183. class operator TQuaternionRec.Multiply(Q: TQuaternionRec; Sc: Extended)
  1184. : TQuaternionRec;
  1185. begin
  1186. Result := [Q.FData[0] * Sc, Q.FData[1] * Sc, Q.FData[2] * Sc,
  1187. Q.FData[3] * Sc];
  1188. end;
  1189. class operator TQuaternionRec.Multiply(Q1, Q2: TQuaternionRec): TQuaternionRec;
  1190. var
  1191. Mat: TMatrixRec;
  1192. begin
  1193. Mat := [[Q1.FData[0], -Q1.FData[1], -Q1.FData[2], -Q1.FData[3]],
  1194. [Q1.FData[1], Q1.FData[0], -Q1.FData[3], Q1.FData[2]],
  1195. [Q1.FData[2], Q1.FData[3], Q1.FData[0], -Q1.FData[1]],
  1196. [Q1.FData[3], -Q1.FData[2], Q1.FData[1], Q1.FData[0]]];
  1197. Result := Mat * Q2;
  1198. end;
  1199. constructor TQuaternionRec.Create(Q: TVectorExt);
  1200. begin
  1201. if Length(Q) <> 4 then
  1202. raise EMathError.Create(sWRONG_SIZE);
  1203. Move(Q[0], FData[0], SizeOf(FData));
  1204. end;
  1205. procedure TQuaternionRec.SetElement(Index: Byte; Value: Extended);
  1206. begin
  1207. if (Index > 3) then
  1208. raise EMathError.Create(sWRONG_ELEMENT);
  1209. FData[Index] := Value;
  1210. end;
  1211. function TQuaternionRec.TruncateSTI: TQuaternionRec;
  1212. const
  1213. Int32Max: Double = Integer.MaxValue;
  1214. Int32Min: Double = Integer.MinValue;
  1215. function xTrunc(Value: Extended): Double;
  1216. begin
  1217. if (Value >= Int32Min) and (Value <= Int32Max) then
  1218. Result := Trunc(Value)
  1219. else if (Value < Int32Min) then
  1220. Result := Int32Min
  1221. else
  1222. Result := Int32Max;
  1223. end;
  1224. begin
  1225. Result[0] := xTrunc(FData[0]);
  1226. Result[1] := xTrunc(FData[1]);
  1227. Result[2] := xTrunc(FData[2]);
  1228. Result[3] := xTrunc(FData[3]);
  1229. end;
  1230. end.