intro.bbdoc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. Matrices are fundamental mathematical constructs used in various fields, such as computer graphics,
  2. physics simulations, and linear algebra. They are especially useful for representing linear transformations,
  3. including rotations, translations, and scaling operations. In the context of graphics and 3D geometry,
  4. matrices are commonly used to manipulate vertices and objects in a scene, transforming their coordinates
  5. and orientations.
  6. A matrix is a rectangular array of numbers, organized into rows and columns. In BlitzMax,
  7. `brl.matrix` provides several structs to work with matrices of different
  8. sizes and types, such as #SMat2D, #SMat3D, #SMat4D, #SMat2F, #SMat3F, #SMat4F, #SMat2I, #SMat3I, and #SMat4I.
  9. The name of each struct indicates its size and the primitive type it uses: #Double, #Float, or #Int.
  10. In our examples, we'll focus primarily on the #Double structs, but the same concepts apply to the other
  11. structs as well.
  12. The following is a brief introduction to the three main types of matrices used in graphics and 3D geometry, which
  13. BlitzMax provides structs for, along with a high-level overview of their applications:
  14. ## Types of Matrices
  15. ### 2x2 Matrices
  16. A 2x2 matrix, represented by the #SMat2D, #SMat2F and #SMat2I structs, is primarily used for 2D linear transformations,
  17. such as rotation and scaling. These matrices can be applied to 2D vectors, transforming their
  18. coordinates accordingly. For example, a 2x2 rotation matrix can be used to rotate a 2D vector
  19. around the origin by a specified angle.
  20. ### 3x3 Matrices
  21. 3x3 matrices, represented by the #SMat3D, #SMat3F and #SMat3I structs, are commonly used for 3D linear transformations that do
  22. not involve translation, such as rotation and scaling. These matrices can be applied to 3D vectors,
  23. transforming their coordinates without changing their position in the scene. For example, a 3x3 rotation
  24. matrix can be used to rotate a 3D vector around a specific axis by a given angle.
  25. The following example demonstrates the use of 3x3 matrices, by creating a simple solar system. The sun
  26. is represented by a yellow circle, and the planets are represented by blue circles. The planets are
  27. rotating around the sun, and their positions are calculated using 3x3 matrices.
  28. ```blitzmax
  29. SuperStrict
  30. Framework SDL.SDLRenderMax2D
  31. Import brl.matrix
  32. Graphics 800, 600, 0
  33. Local sunX:Float = GraphicsWidth() / 2
  34. Local sunY:Float = GraphicsHeight() / 2
  35. Local sunRadius:Float = 50
  36. Local planets:TPlanet[] = [New TPlanet(150, 20, 0.7), New TPlanet(200, 15, 0.5), New TPlanet(250, 10, 0.3)]
  37. While Not KeyHit(KEY_ESCAPE)
  38. Cls
  39. ' Draw the sun
  40. SetColor(255, 255, 0)
  41. DrawOval(sunX - sunRadius, sunY - sunRadius, sunRadius * 2, sunRadius * 2)
  42. ' Draw the planets
  43. For Local planet:TPlanet = EachIn planets
  44. planet.Draw(sunX, sunY)
  45. Next
  46. Flip
  47. Wend
  48. Type TPlanet
  49. Field distance:Float
  50. Field radius:Float
  51. Field angle:Float
  52. Field speed:Float
  53. Method New(distance:Float, radius:Float, speed:Float)
  54. Self.distance = distance
  55. Self.radius = radius
  56. Self.speed = speed
  57. End Method
  58. Method Draw(centerX:Float, centerY:Float)
  59. ' Calculate the planet's position
  60. Local planetMatrix:SMat3D = SMat3D.Identity()
  61. planetMatrix = planetMatrix.Rotate(angle)
  62. planetMatrix = planetMatrix.Translate(New SVec3D(distance, 0, 0))
  63. Local planetPos:SVec3D = planetMatrix.Apply(New SVec3D(0, 0, 1))
  64. ' Draw the planet
  65. SetColor(0, 0, 255)
  66. DrawOval(Float(centerX + planetPos.x - radius), Float(centerY + planetPos.y - radius), radius * 2, radius * 2)
  67. ' Update the angle for the next frame
  68. angle :+ speed
  69. End Method
  70. End Type
  71. ```
  72. ### 4x4 Matrices
  73. 4x4 matrices, represented by the #SMat4D, #SMat4F and #SMat4I structs, are the most versatile and widely used matrices in 3D
  74. graphics. They can represent any combination of linear transformations, such as rotation, scaling,
  75. and translation. A 4x4 matrix can be applied to a 3D vector, transforming its position, orientation,
  76. and scale in the scene. For example, a 4x4 transformation matrix can be used to move an object in 3D space,
  77. rotate it around a specific axis, and scale it uniformly or non-uniformly.
  78. Creating a 3D-like effect in 2D can be achieved using simple orthogonal projection. In this example,
  79. we will create a rotating cube using a 4x4 transformation matrix to apply rotation, scaling, and translation.
  80. ```blitzmax
  81. SuperStrict
  82. Framework SDL.SDLRenderMax2D
  83. Import brl.matrix
  84. Graphics 800, 600, 0
  85. Local cube:TCube = New TCube
  86. Local angle:Float = 0
  87. Local centerX:Int = GraphicsWidth() / 2
  88. Local centerY:Int = GraphicsHeight() / 2
  89. While Not KeyHit(KEY_ESCAPE)
  90. Cls
  91. ' Create the transformation matrix..
  92. ' Start with an identity matrix as the initial transformation.
  93. Local matrix:SMat4D = SMat4D.Identity()
  94. ' Move the object away from the camera along the Z-axis by a distance of 6 units.
  95. ' This translation ensures that the object is visible and centered in the view.
  96. matrix = matrix.Translate(New SVec3D(0, 0, -6))
  97. ' Rotate the object around the Z-axis (blue axis) by an angle scaled by 1.2.
  98. ' This rotation is applied first to achieve a "rolling" effect.
  99. matrix = matrix.Rotate(New SVec3D(0, 0, 1), angle * 1.2)
  100. ' Rotate the object around the Y-axis (green axis) by an angle scaled by 0.7.
  101. ' This rotation is applied after the first rotation, creating a "pitching" effect.
  102. matrix = matrix.Rotate(New SVec3D(0, 1, 0), angle * 0.7)
  103. ' Finally, rotate the object around the X-axis (red axis) by the base angle.
  104. ' This rotation is applied last, creating a "yawing" effect.
  105. matrix = matrix.Rotate(New SVec3D(1, 0, 0), angle)
  106. ' Draw cube
  107. cube.Draw(matrix, 100, centerX, centerY)
  108. Flip
  109. angle :+ 0.5
  110. Wend
  111. Type TCube
  112. Field vertices:Float[24] ' 8 vertices, each with 3 coordinates
  113. Field edges:Int[24] ' 12 edges, each with 2 vertex indices
  114. Method New()
  115. vertices = [ -1:Float, -1:Float, -1:Float, 1:Float, -1:Float, -1:Float, 1:Float, 1:Float, -1:Float, -1:Float, ..
  116. 1:Float, -1:Float, -1:Float, -1:Float, 1:Float, 1:Float, -1:Float, 1:Float, 1:Float, 1:Float, ..
  117. 1:Float, -1:Float, 1:Float, 1:Float ]
  118. edges = [ 0, 1, 1, 2, 2, 3, 3, 0, ..
  119. 4, 5, 5, 6, 6, 7, 7, 4, ..
  120. 0, 4, 1, 5, 2, 6, 3, 7 ]
  121. End Method
  122. Method Draw(matrix:SMat4D, scale:Float = 1, centerX:Int, centerY:Int)
  123. Local transformedVertices:Float[24]
  124. ' Apply transformation and orthographic projection
  125. For Local i:Int = 0 Until 24 Step 3
  126. Local vertex:SVec3D = New SVec3D(vertices[i], vertices[i + 1], vertices[i + 2])
  127. vertex = matrix.Apply(vertex)
  128. transformedVertices[i] = centerX + (scale * vertex.x)
  129. transformedVertices[i + 1] = centerY - (scale * vertex.y)
  130. Next
  131. ' Draw edges
  132. For Local i:Int = 0 Until 24 Step 2
  133. DrawLine(transformedVertices[edges[i] * 3], transformedVertices[edges[i] * 3 + 1],
  134. transformedVertices[edges[i + 1] * 3], transformedVertices[edges[i + 1] * 3 + 1])
  135. Next
  136. End Method
  137. End Type
  138. ```
  139. ## Column-Major vs. Row-Major Matrices
  140. In `brl.matrix`, we use column-major ordering for matrices. Column-major ordering is a convention
  141. in which elements are stored column by column in memory. It is the opposite of row-major ordering, where
  142. elements are stored row by row. This distinction is important when performing operations like matrix
  143. multiplication or when applying transformations to vectors or other matrices.
  144. Column-major ordering is commonly used in graphics programming and some mathematical libraries. In
  145. this convention, when applying transformations, the order in which they are applied is reversed
  146. compared to row-major ordering. This means that when you want to apply multiple transformations,
  147. you should apply them in the reverse order that you would with row-major ordering.
  148. For example, in column-major ordering, to rotate an object around the X, Y, and Z axes and then
  149. translate it, you would first apply the translation, then the rotation around the Z axis, followed
  150. by the rotation around the Y axis, and finally the rotation around the X axis.
  151. ## Determinant, Inverse, and Transpose in Matrices
  152. ### Determinant
  153. The determinant is a scalar value associated with square matrices that carries essential
  154. information about the matrix's properties. It has several important geometric interpretations
  155. and applications in linear algebra.
  156. In the context of 2D transformations, the determinant represents the area scaling factor when a
  157. matrix is applied to a vector. If the determinant is positive, the transformation preserves the
  158. orientation; if it's negative, the orientation is reversed. A determinant equal to zero indicates
  159. that the transformation collapses the vector onto a lower-dimensional subspace (e.g., a line or a point),
  160. making the matrix singular and non-invertible.
  161. Mathematically, the determinant of a 2x2 matrix is calculated as follows:
  162. ```
  163. |A| = |a b|
  164. |c d|
  165. |A| = ad - bc
  166. ```
  167. Here's an example illustrating how to calculate the determinant of a 2x2 matrix using the #SMat2D struct:
  168. ```blitzmax
  169. SuperStrict
  170. Framework BRL.StandardIO
  171. Import BRL.Matrix
  172. ' Define matrix elements
  173. Local a:Double = 3.0
  174. Local b:Double = 2.0
  175. Local c:Double = 5.0
  176. Local d:Double = 4.0
  177. ' Create a 2x2 matrix
  178. Local mat:SMat2D = New SMat2D(a, b, c, d)
  179. ' Calculate the determinant
  180. Local det:Double = mat.Determinant()
  181. ' Print the determinant
  182. Print "Determinant: " + det
  183. ```
  184. When you run this example, it will create a 2x2 matrix with the specified elements,
  185. calculate the determinant using the `Determinant()` method provided by #SMat2D, and print the resulting
  186. determinant value. In this case, the output will be:
  187. ```
  188. Determinant: -2.0
  189. ```
  190. For a 3x3 matrix, the determinant can be calculated using the following formula:
  191. ```
  192. |A| = |a b c|
  193. |d e f|
  194. |g h i|
  195. |A| = a(ei - fh) - b(di - fg) + c(dh - eg)
  196. ```
  197. Here's an example illustrating how to calculate the determinant of a 3x3 matrix using the #SMat3D struct:
  198. ```blitzmax
  199. SuperStrict
  200. Framework BRL.StandardIO
  201. Import BRL.Matrix
  202. ' Define matrix elements
  203. Local a:Double = 1.0
  204. Local b:Double = 2.0
  205. Local c:Double = 3.0
  206. Local d:Double = 4.0
  207. Local e:Double = 5.0
  208. Local f:Double = 6.0
  209. Local g:Double = 7.0
  210. Local h:Double = 8.0
  211. Local i:Double = 9.0
  212. ' Create a 3x3 matrix
  213. Local mat:SMat3D = New SMat3D(a, b, c, d, e, f, g, h, i)
  214. ' Calculate the determinant
  215. Local det:Double = mat.Determinant()
  216. ' Print the determinant
  217. Print "Determinant: " + det
  218. ```
  219. When you run this example, it will create a 3x3 matrix with the specified elements,
  220. calculate the determinant using the `Determinant()` method provided by #SMat3D, and print the
  221. resulting determinant value. In this case, the output will be:
  222. ```
  223. Determinant: 0.0
  224. ```
  225. ### Inverse
  226. The inverse of a matrix is another matrix that, when multiplied with the original matrix,
  227. results in the identity matrix. In other words, for a matrix A, its inverse A⁻¹ exists if
  228. and only if A * A⁻¹ = A⁻¹ * A = I, where I is the identity matrix. Not all matrices have
  229. inverses; only square matrices (i.e., matrices with the same number of rows and columns) may
  230. have inverses, and even then, not all square matrices are invertible.
  231. For a 2x2 matrix:
  232. ```
  233. | a b |
  234. | c d |
  235. ```
  236. The inverse can be calculated using the following formula:
  237. ```
  238. 1 / (ad - bc) * | d -b |
  239. | -c a |
  240. ```
  241. The term (ad - bc) is the determinant of the matrix. If the determinant is zero, the matrix
  242. is singular and does not have an inverse.
  243. For a 3x3 matrix, the process is more complicated and involves finding the matrix of minors,
  244. the matrix of cofactors, and finally, the adjugate matrix. The inverse can then be computed
  245. by dividing the adjugate matrix by the determinant of the original matrix.
  246. Here is an example for finding the inverse of a 2x2 matrix using the #SMat2D struct:
  247. ```blitzmax
  248. SuperStrict
  249. Framework brl.standardio
  250. Import brl.matrix
  251. ' Create a 2x2 matrix
  252. Local a:Double = 3
  253. Local b:Double = 2
  254. Local c:Double = 5
  255. Local d:Double = 3
  256. Local mat:SMat2D = New SMat2D(a, b, c, d)
  257. ' Calculate the inverse
  258. Local matInverse:SMat2D = mat.Invert()
  259. ' Print the original and inverse matrices
  260. Print "Original matrix:~n" + mat.ToString()
  261. Print "Inverse matrix:~n" + matInverse.ToString()
  262. ```
  263. When you run this example, it will output the original 2x2 matrix and its inverse:
  264. ```
  265. Original matrix:
  266. 3.000 2.000
  267. 5.000 3.000
  268. Inverse matrix:
  269. -1.000 0.667
  270. 1.667 -1.000
  271. ```
  272. And here is an example for finding the inverse of a 3x3 matrix using the #SMat3D struct:
  273. ```blitzmax
  274. SuperStrict
  275. Framework brl.standardio
  276. Import brl.matrix
  277. ' Create a 3x3 matrix
  278. Local a:Double = 1
  279. Local b:Double = 2
  280. Local c:Double = 3
  281. Local d:Double = 0
  282. Local e:Double = 1
  283. Local f:Double = 4
  284. Local g:Double = 5
  285. Local h:Double = 6
  286. Local i:Double = 0
  287. Local mat:SMat3D = New SMat3D(a, b, c, d, e, f, g, h, i)
  288. ' Calculate the inverse
  289. Local matInverse:SMat3D = mat.Invert()
  290. ' Print the original and inverse matrices
  291. Print "Original matrix: " + mat.ToString()
  292. Print "Inverse matrix: " + matInverse.ToString()
  293. ```
  294. When you run this example, it will output the original 3x3 matrix and its inverse:
  295. ```
  296. Original matrix:
  297. 1.000 2.000 3.000
  298. 0.000 1.000 4.000
  299. 5.000 6.000 0.000
  300. Inverse matrix:
  301. -24.000 18.000 5.000
  302. 20.000 -15.000 -4.000
  303. -5.000 4.000 1.000
  304. ```
  305. ### Transpose
  306. The transpose of a matrix is a new matrix obtained by interchanging its rows and columns.
  307. In other words, the transpose of a matrix A is a new matrix Aᵀ, where the element Aᵀ[i, j] = A[j, i].
  308. The transpose operation has several important properties and applications in linear algebra, including
  309. simplifying matrix equations and working with symmetric matrices.
  310. For a 2x2 matrix A:
  311. ```
  312. A = |a b| Aᵀ = |a c|
  313. |c d| |b d|
  314. ```
  315. For a 3x3 matrix A:
  316. ```
  317. A = |a b c| Aᵀ = |a d g|
  318. |d e f| |b e h|
  319. |g h i| |c f i|
  320. ```
  321. Here's an example illustrating how to calculate the transpose of a 2x2 matrix using the #SMat2D struct.
  322. ```blitzmax
  323. SuperStrict
  324. Framework brl.standardIO
  325. Import brl.matrix
  326. ' Define matrix elements
  327. Local a:Double = 1.0
  328. Local b:Double = 2.0
  329. Local c:Double = 3.0
  330. Local d:Double = 4.0
  331. ' Create a 2x2 matrix
  332. Local mat:SMat2D = New SMat2D(a, b, c, d)
  333. ' Calculate the transpose
  334. Local matTranspose:SMat2D = mat.Transpose()
  335. ' Print the original and transposed matrices
  336. Print "Original matrix:~n" + mat.ToString()
  337. Print "Transposed matrix:~n" + matTranspose.ToString()
  338. ```
  339. When you run this example, it will create a 2x2 matrix with the specified elements, calculate
  340. the transpose using the Transpose() method provided by the #SMat2D struct, and print the original
  341. and transposed matrices. In this case, the output will be:
  342. ```
  343. Original matrix:
  344. 1.0, 2.0
  345. 3.0, 4.0
  346. Transposed matrix:
  347. 1.0 3.0
  348. 2.0 4.0
  349. ```
  350. And an example for calculating the transpose of a 3x3 matrix using the #SMat3D struct.
  351. ```blitzmax
  352. SuperStrict
  353. Framework brl.standardIO
  354. Import brl.matrix
  355. ' Define matrix elements
  356. Local a:Double = 1.0
  357. Local b:Double = 2.0
  358. Local c:Double = 3.0
  359. Local d:Double = 4.0
  360. Local e:Double = 5.0
  361. Local f:Double = 6.0
  362. Local g:Double = 7.0
  363. Local h:Double = 8.0
  364. Local i:Double = 9.0
  365. ' Create a 3x3 matrix
  366. Local mat:SMat3D = New SMat3D(a, b, c, d, e, f, g, h, i)
  367. ' Calculate the transpose
  368. Local matTranspose:SMat3D = mat.Transpose()
  369. ' Print the original and transposed matrices
  370. Print "Original matrix: " + mat.ToString()
  371. Print "Transposed matrix: " + matTranspose.ToString()
  372. ```
  373. When you run this example, it will create a 3x3 matrix with the specified elements,
  374. calculate the transpose using the Transpose() method provided by the #SMat3D struct, and print the
  375. original and transposed matrices. In this case, the output will be:
  376. ```
  377. Original matrix:
  378. 1.0 2.0 3.0
  379. 4.0 5.0 6.0
  380. 7.0 8.0 9.0
  381. Transposed matrix:
  382. 1.0 4.0 7.0
  383. 2.0 5.0 8.0
  384. 3.0 6.0 9.0
  385. ```
  386. Understanding the transpose concept and its properties is important when working with matrices
  387. in your BlitzMax projects. The transpose operation can help simplify matrix equations and work with
  388. symmetric matrices, among other applications. By transposing a matrix, you can manipulate its elements
  389. and apply various transformations as required in your project.
  390. ## Scaling, rotation, and shearing matrices
  391. Scaling, rotation, and shearing matrices are fundamental linear transformations used in various fields, such as
  392. computer graphics, physics simulations, and geometric modeling. These transformations can be applied to vectors or points
  393. to change their position, orientation, or shape.
  394. ### Scaling matrices
  395. Scaling is the process of resizing an object uniformly or non-uniformly along its axes. Scaling matrices are diagonal matrices
  396. that have scaling factors along the diagonal elements, and zeros elsewhere.
  397. For 2D scaling:
  398. ```
  399. | sx 0 |
  400. | 0 sy |
  401. ```
  402. For 3D scaling:
  403. ```
  404. | sx 0 0 |
  405. | 0 sy 0 |
  406. | 0 0 sz |
  407. ```
  408. Here, sx, sy, and sz are the scaling factors along the x, y, and z axes, respectively. To apply the scaling transformation, you multiply
  409. the scaling matrix by the vector or point you want to scale.
  410. ### Rotation matrices
  411. Rotation is the process of rotating an object around a point or an axis. Rotation matrices are used to represent the rotation
  412. transformations in both 2D and 3D spaces.
  413. For 2D rotation around the origin by angle θ:
  414. ```
  415. | cos(θ) -sin(θ) |
  416. | sin(θ) cos(θ) |
  417. ```
  418. For 3D rotation around an arbitrary axis (x, y, z) by angle θ, the rotation matrix is more complex. One common method is using
  419. the axis-angle representation, which involves the Rodrigues' rotation formula. The formula for the 3D rotation matrix is as follows:
  420. ```
  421. R = I + sin(θ) * K + (1 - cos(θ)) * K^2
  422. ```
  423. Where `I` is the identity matrix, `θ` is the angle of rotation, and `K` is the skew-symmetric matrix representation of the axis vector.
  424. ### Shearing matrices
  425. Shearing is the process of transforming an object by displacing its points along one axis based on the displacement of points along a
  426. parallel axis. Shearing matrices are used to represent these transformations.
  427. For 2D shearing:
  428. ```
  429. | 1 shx |
  430. | shy 1 |
  431. ```
  432. For 3D shearing along the x-axis:
  433. ```
  434. | 1 shy shz |
  435. | 0 1 0 |
  436. | 0 0 1 |
  437. ```
  438. And similar matrices can be defined for shearing along the y-axis and z-axis. Here, `shx`, `shy`, and `shz` represent the shearing factors.
  439. When applying these transformations, it's important to consider the order of operations, as matrix multiplication is not commutative.
  440. Typically, scaling and shearing are applied first, followed by rotation, and finally translation. Also, remember that these matrices should
  441. be applied to homogeneous coordinates for translation to work correctly. In 3D graphics, this often involves using 4x4 matrices with an
  442. additional row and column for the homogeneous coordinate.
  443. ## Matrix multiplication
  444. Matrix multiplication is an essential operation in linear algebra and has numerous applications in computer graphics, physics, and other fields.
  445. Multiplying two matrices involves specific rules, and it's important to understand the dimensions of the matrices and how to perform the
  446. multiplication element-wise.
  447. ### Rules for Matrix Multiplication
  448. Given two matrices A and B, the product AB can only be computed if the number of columns in A is equal to the number of rows in B.
  449. If matrix A has dimensions m × n and matrix B has dimensions n × p, then the product AB will have dimensions m × p.
  450. `(AB)_ij = A_i1 * B_1j + A_i2 * B_2j + ... + A_in * B_nj`
  451. where (AB)_ij represents the element in the i-th row and j-th column of the resulting matrix AB.
  452. ### Element-wise matrix multiplication
  453. To multiply two matrices element-wise, follow these steps:
  454. 1. Verify that the dimensions of the matrices are compatible for multiplication. The number of columns in matrix A must be equal
  455. to the number of rows in matrix B.
  456. 2. Create a new matrix C with dimensions m × p, where m is the number of rows in matrix A and p is the number of columns in matrix B.
  457. 3. For each element (i, j) in the resulting matrix C, calculate the value as the sum of the products of the corresponding row elements in matrix A
  458. and the column elements in matrix B:
  459. `C_ij = A_i1 * B_1j + A_i2 * B_2j + ... + A_in * B_nj`
  460. Iterate through all elements in matrix C, computing their values using the above formula.
  461. 4. The resulting matrix C represents the product of matrices A and B.
  462. It's important to note that matrix multiplication is not commutative, meaning that AB ≠ BA in general. However, it is
  463. associative (A(BC) = (AB)C) and distributive over addition (A(B+C) = AB + AC).
  464. The `CompMul()` method can be used to perform element-wise matrix multiplication.
  465. ### Matrix multiplication using the dot product
  466. Matrix multiplication is a fundamental operation in linear algebra, and it is performed using the dot product.
  467. It is important to understand that matrix multiplication is not the same as element-wise multiplication. In matrix
  468. multiplication, the dot product of the rows of the first matrix and the columns of the second matrix is used to calculate the resulting matrix elements.
  469. Consider two matrices, A and B, where A has dimensions m x n (m rows and n columns), and B has dimensions p x q (p rows and q columns).
  470. For matrix multiplication to be possible, the number of columns in A (n) must be equal to the number of rows in B (p). The resulting
  471. matrix, C, will have dimensions m x q (m rows and q columns).
  472. Here is the formula for matrix multiplication using the dot product:
  473. C[i][j] = Σ (A[i][k] * B[k][j]) for k = 0 to n-1
  474. where i ranges from 0 to m-1 and j ranges from 0 to q-1.
  475. In other words, each element in the resulting matrix C is the dot product of the i-th row of matrix A and the j-th column of matrix B.
  476. Let's see an example with two 3x3 matrices:
  477. ```
  478. A = | a b c | B = | p q r |
  479. | d e f | | s t u |
  480. | g h i | | v w x |
  481. C = | (a*p + b*s + c*v) (a*q + b*t + c*w) (a*r + b*u + c*x) |
  482. | (d*p + e*s + f*v) (d*q + e*t + f*w) (d*r + e*u + f*x) |
  483. | (g*p + h*s + i*v) (g*q + h*t + i*w) (g*r + h*u + i*x) |
  484. ```
  485. The `Operator *()` method can be used to perform matrix multiplication using the dot product.
  486. ### Vector Multiplication
  487. Matrix-vector multiplication is a fundamental operation in linear algebra, computer graphics, and many other fields. This operation
  488. is used to apply transformations, such as scaling, rotation, and translation, to points and vectors in 2D and 3D space. In this section,
  489. we will discuss how to multiply a matrix by a vector and how this operation can be applied to 2D and 3D vectors in BlitzMax.
  490. #### 2D Vectors ( #SVec2D, #SVec2F, #SVec2I )
  491. To multiply a 2x2 matrix by a 2D vector, perform the following steps:
  492. 1. Multiply each element of the first row of the matrix by the corresponding element of the vector.
  493. 2. Sum the results from step 1 to obtain the first element of the resulting vector.
  494. 3. Multiply each element of the second row of the matrix by the corresponding element of the vector.
  495. 4. Sum the results from step 3 to obtain the second element of the resulting vector.
  496. Mathematically, this can be represented as:
  497. ```
  498. | a c | | x | | a * x + c * y |
  499. | b d | | y | = | b * x + d * y |
  500. ```
  501. #### 3D Vectors ( #SVec3D, #SVec3F, #SVec3I )
  502. To multiply a 3x3 matrix by a 3D vector, follow these steps:
  503. 1. Multiply each element of the first row of the matrix by the corresponding element of the vector.
  504. 2. Sum the results from step 1 to obtain the first element of the resulting vector.
  505. 3. Multiply each element of the second row of the matrix by the corresponding element of the vector.
  506. 4. Sum the results from step 3 to obtain the second element of the resulting vector.
  507. 5. Multiply each element of the third row of the matrix by the corresponding element of the vector.
  508. 6. Sum the results from step 5 to obtain the third element of the resulting vector.
  509. Mathematically, this can be represented as:
  510. ```
  511. | a d g | | x | | a * x + d * y + g * z |
  512. | b e h | | y | = | b * x + e * y + h * z |
  513. | c f i | | z | | c * x + f * y + i * z |
  514. ```
  515. You can use the `Apply()` method to multiply a matrix by a vector.
  516. Here's an example:
  517. ```blitzmax
  518. Local mat2D:SMat2D = SMat2D.Identity()
  519. Local vec2D:SVec2D = New SVec2D(2, 3)
  520. Local result2D:SVec2D = mat2D.Apply(vec2D)
  521. Local mat3D:SMat3D = SMat3D.Identity()
  522. Local vec3D:SVec3D = New SVec3D(2, 3, 4)
  523. Local result3D:SVec3D = mat3D.Apply(vec3D)
  524. ```
  525. ## The Identity Matrix
  526. The identity matrix is a special square matrix that has ones on the diagonal and zeros elsewhere. In mathematical notation,
  527. an identity matrix of size n x n is denoted as Iₙ. Here's an example of a 3x3 identity matrix:
  528. ```
  529. I₃ = | 1 0 0 |
  530. | 0 1 0 |
  531. | 0 0 1 |
  532. ```
  533. The identity matrix plays a crucial role in matrix algebra, as it serves as the "neutral element" for matrix multiplication. When you
  534. multiply any matrix by the identity matrix, the result is the original matrix unchanged. Mathematically, this property can be written as:
  535. A * Iₙ = A
  536. Iₙ * A = A
  537. where A is any n x n matrix.
  538. This property is analogous to the number 1 in scalar multiplication. Just as multiplying any number by 1 leaves the number unchanged
  539. (e.g., 7 * 1 = 7), multiplying any matrix by the identity matrix leaves the matrix unchanged.
  540. The identity matrix is also important for other matrix operations. For example, when calculating the inverse of a matrix, the goal is to
  541. find a matrix B such that A * B = Iₙ. When this condition is met, matrix B is the inverse of matrix A.
  542. The `Identity()` method allows you create an identity matrix.
  543. ## Linear Transformations
  544. Matrices are often used to represent linear transformations in various fields, including computer graphics and linear algebra.
  545. A linear transformation is a function that maps vectors from one vector space to another while preserving the operations of vector
  546. addition and scalar multiplication. In this section, we will discuss some of the key properties of linear transformations and how
  547. matrices can be used to represent them.
  548. ### Linearity
  549. A linear transformation, T, has the property of linearity, which means it satisfies the following conditions:
  550. 1. T(u + v) = T(u) + T(v) for all vectors u and v.
  551. 2. T(c * u) = c * T(u) for all vectors u and any scalar c.
  552. This property ensures that the transformation maintains the structure of the vector space, preserving
  553. parallelism and proportions between the vectors.
  554. ### Invertibility
  555. A linear transformation is invertible if there exists another transformation, called its inverse, that can undo the effect of the original
  556. transformation. In terms of matrices, a matrix A is invertible if there exists a matrix B such that AB = BA = I, where I is the identity matrix.
  557. Invertible transformations are essential in many applications, as they allow us to reverse the effects of a transformation and recover the original data.
  558. ### Effect on Geometry
  559. Linear transformations can have various effects on the geometry of shapes, including:
  560. 1. Scaling: A transformation that changes the size of a shape, either uniformly or non-uniformly along different axes.
  561. 2. Rotation: A transformation that rotates a shape around a specified point or axis.
  562. 3. Shearing: A transformation that distorts a shape by shifting its points along one axis relative to the other axis.
  563. ## Orthogonal and Orthonormal Matrices
  564. Orthogonal and orthonormal matrices are special types of square matrices that have unique properties, making them particularly useful in
  565. various applications such as computer graphics, physics, and linear algebra.
  566. ### Orthogonal Matrices
  567. A matrix A is called an orthogonal matrix if its transpose, A^T, is also its inverse, i.e., A^T * A = A * A^T = I, where I is the identity
  568. matrix. In other words, the columns (and rows) of an orthogonal matrix are orthogonal to each other, meaning they form a 90-degree angle
  569. and their dot product is zero.
  570. The geometric interpretation of orthogonal matrices is that they represent transformations that preserve lengths and angles, such as
  571. rotations and reflections.
  572. ### Orthonormal Matrices
  573. An orthonormal matrix is an orthogonal matrix where the columns (and rows) are not only orthogonal but also have unit length (i.e., they
  574. are normalized). Orthonormal matrices simplify calculations in various applications, as they do not change the length of the vectors they transform.
  575. ### Applications
  576. Orthogonal and orthonormal matrices play a significant role in computer graphics, as they are used to represent transformations that maintain
  577. the geometry of 3D objects. For instance, they can be employed to create rotation matrices, which are essential for rotating objects in 3D space.
  578. Here's a BlitzMax example demonstrating the use of an orthonormal matrix to represent a 3D rotation:
  579. ```blitzmax
  580. Local angleX:Float = 30 ' in degrees
  581. Local angleY:Float = 45 ' in degrees
  582. Local angleZ:Float = 60 ' in degrees
  583. ' Create orthonormal rotation matrices for each axis
  584. Local rotationMatrixX:SMat3D = SMat3D.RotationX(angleX)
  585. Local rotationMatrixY:SMat3D = SMat3D.RotationY(angleY)
  586. Local rotationMatrixZ:SMat3D = SMat3D.RotationZ(angleZ)
  587. ' Combine the rotations
  588. Local rotationMatrix:SMat3D = rotationMatrixX * rotationMatrixY * rotationMatrixZ
  589. ' Apply the rotation to a 3D vector
  590. Local vec:SVec3D = New SVec3D(1, 2, 3)
  591. Local rotatedVec:SVec3D = rotationMatrix.Apply(vec)
  592. ```
  593. When the rotation matrix is applied to a 3D vector, it will rotate the vector according to the specified angles.
  594. The order in which the rotations are combined (in this example, X, then Y, then Z) will determine the final rotation.