Ver Fonte

Updated brl.matrix documentation.

Added Translate() method.
Brucey há 2 anos atrás
pai
commit
95aa412d47
2 ficheiros alterados com 901 adições e 17 exclusões
  1. 795 0
      matrix.mod/doc/intro.bbdoc
  2. 106 17
      matrix.mod/matrix.bmx

+ 795 - 0
matrix.mod/doc/intro.bbdoc

@@ -0,0 +1,795 @@
+Matrices are fundamental mathematical constructs used in various fields, such as computer graphics,
+physics simulations, and linear algebra. They are especially useful for representing linear transformations,
+including rotations, translations, and scaling operations. In the context of graphics and 3D geometry,
+matrices are commonly used to manipulate vertices and objects in a scene, transforming their coordinates
+and orientations.
+
+A matrix is a rectangular array of numbers, organized into rows and columns. In BlitzMax,
+`brl.matrix` provides several structs to work with matrices of different
+sizes and types, such as #SMat2D, #SMat3D, #SMat4D, #SMat2F, #SMat3F, #SMat4F, #SMat2I, #SMat3I, and #SMat4I.
+The name of each struct indicates its size and the primitive type it uses: #Double, #Float, or #Int.
+In our examples, we'll focus primarily on the #Double structs, but the same concepts apply to the other
+structs as well.
+
+The following is a brief introduction to the three main types of matrices used in graphics and 3D geometry, which
+BlitzMax provides structs for, along with a high-level overview of their applications:
+
+## Types of Matrices
+
+### 2x2 Matrices
+A 2x2 matrix, represented by the #SMat2D, #SMat2F and #SMat2I structs, is primarily used for 2D linear transformations,
+such as rotation and scaling. These matrices can be applied to 2D vectors, transforming their
+coordinates accordingly. For example, a 2x2 rotation matrix can be used to rotate a 2D vector
+around the origin by a specified angle.
+
+### 3x3 Matrices
+3x3 matrices, represented by the #SMat3D, #SMat3F and #SMat3I structs, are commonly used for 3D linear transformations that do
+not involve translation, such as rotation and scaling. These matrices can be applied to 3D vectors,
+transforming their coordinates without changing their position in the scene. For example, a 3x3 rotation
+matrix can be used to rotate a 3D vector around a specific axis by a given angle.
+
+The following example demonstrates the use of 3x3 matrices, by creating a simple solar system. The sun
+is represented by a yellow circle, and the planets are represented by blue circles. The planets are
+rotating around the sun, and their positions are calculated using 3x3 matrices.
+
+```blitzmax
+SuperStrict
+
+Framework SDL.SDLRenderMax2D
+Import brl.matrix
+
+Graphics 800, 600, 0
+
+Local sunX:Float = GraphicsWidth() / 2
+Local sunY:Float = GraphicsHeight() / 2
+Local sunRadius:Float = 50
+
+Local planets:TPlanet[] = [New TPlanet(150, 20, 0.7), New TPlanet(200, 15, 0.5), New TPlanet(250, 10, 0.3)]
+
+While Not KeyHit(KEY_ESCAPE)
+    Cls
+
+    ' Draw the sun
+    SetColor(255, 255, 0)
+    DrawOval(sunX - sunRadius, sunY - sunRadius, sunRadius * 2, sunRadius * 2)
+
+    ' Draw the planets
+    For Local planet:TPlanet = EachIn planets
+        planet.Draw(sunX, sunY)
+    Next
+
+    Flip
+Wend
+
+Type TPlanet
+    Field distance:Float
+    Field radius:Float
+    Field angle:Float
+    Field speed:Float
+
+    Method New(distance:Float, radius:Float, speed:Float)
+        Self.distance = distance
+        Self.radius = radius
+        Self.speed = speed
+    End Method
+
+	Method Draw(centerX:Float, centerY:Float)
+		' Calculate the planet's position
+		Local planetMatrix:SMat3D = SMat3D.Identity()
+		planetMatrix = planetMatrix.Rotate(angle)
+		planetMatrix = planetMatrix.Translate(New SVec3D(distance, 0, 0))
+		Local planetPos:SVec3D = planetMatrix.Apply(New SVec3D(0, 0, 1))
+	
+		' Draw the planet
+		SetColor(0, 0, 255)
+		DrawOval(Float(centerX + planetPos.x - radius), Float(centerY + planetPos.y - radius), radius * 2, radius * 2)
+	
+		' Update the angle for the next frame
+		angle :+ speed
+	End Method
+End Type
+```
+
+### 4x4 Matrices
+4x4 matrices, represented by the #SMat4D, #SMat4F and #SMat4I structs, are the most versatile and widely used matrices in 3D
+graphics. They can represent any combination of linear transformations, such as rotation, scaling,
+and translation. A 4x4 matrix can be applied to a 3D vector, transforming its position, orientation,
+and scale in the scene. For example, a 4x4 transformation matrix can be used to move an object in 3D space,
+rotate it around a specific axis, and scale it uniformly or non-uniformly.
+
+Creating a 3D-like effect in 2D can be achieved using simple orthogonal projection. In this example,
+we will create a rotating cube using a 4x4 transformation matrix to apply rotation, scaling, and translation. 
+
+```blitzmax
+SuperStrict
+
+Framework SDL.SDLRenderMax2D
+Import brl.matrix
+
+Graphics 800, 600, 0
+
+Local cube:TCube = New TCube
+Local angle:Float = 0
+
+Local centerX:Int = GraphicsWidth() / 2
+Local centerY:Int = GraphicsHeight() / 2
+
+While Not KeyHit(KEY_ESCAPE)
+    Cls
+
+    ' Create the transformation matrix..
+    ' Start with an identity matrix as the initial transformation.
+    Local matrix:SMat4D = SMat4D.Identity()
+    ' Move the object away from the camera along the Z-axis by a distance of 6 units.
+    ' This translation ensures that the object is visible and centered in the view.
+    matrix = matrix.Translate(New SVec3D(0, 0, -6))
+    ' Rotate the object around the Z-axis (blue axis) by an angle scaled by 1.2.
+    ' This rotation is applied first to achieve a "rolling" effect.
+    matrix = matrix.Rotate(New SVec3D(0, 0, 1), angle * 1.2)
+    ' Rotate the object around the Y-axis (green axis) by an angle scaled by 0.7.
+    ' This rotation is applied after the first rotation, creating a "pitching" effect.
+    matrix = matrix.Rotate(New SVec3D(0, 1, 0), angle * 0.7)
+    ' Finally, rotate the object around the X-axis (red axis) by the base angle.
+    ' This rotation is applied last, creating a "yawing" effect.
+    matrix = matrix.Rotate(New SVec3D(1, 0, 0), angle)
+
+    ' Draw cube
+    cube.Draw(matrix, 100, centerX, centerY)
+
+    Flip
+    angle :+ 0.5
+Wend
+
+Type TCube
+    Field vertices:Float[24] ' 8 vertices, each with 3 coordinates
+    Field edges:Int[24] ' 12 edges, each with 2 vertex indices
+
+    Method New()
+        vertices = [ -1:Float, -1:Float, -1:Float, 1:Float, -1:Float, -1:Float, 1:Float, 1:Float, -1:Float, -1:Float, ..
+					1:Float, -1:Float, -1:Float, -1:Float, 1:Float, 1:Float, -1:Float, 1:Float, 1:Float, 1:Float, ..
+					1:Float, -1:Float, 1:Float, 1:Float ]
+        edges = [ 0, 1, 1, 2, 2, 3, 3, 0, ..
+                  4, 5, 5, 6, 6, 7, 7, 4, ..
+                  0, 4, 1, 5, 2, 6, 3, 7 ]
+    End Method
+
+    Method Draw(matrix:SMat4D, scale:Float = 1, centerX:Int, centerY:Int)
+        Local transformedVertices:Float[24]
+
+		' Apply transformation and orthographic projection
+		For Local i:Int = 0 Until 24 Step 3
+			Local vertex:SVec3D = New SVec3D(vertices[i], vertices[i + 1], vertices[i + 2])
+			vertex = matrix.Apply(vertex)
+			transformedVertices[i] = centerX + (scale * vertex.x)
+			transformedVertices[i + 1] = centerY - (scale * vertex.y)
+		Next
+
+		' Draw edges
+		For Local i:Int = 0 Until 24 Step 2
+			DrawLine(transformedVertices[edges[i] * 3], transformedVertices[edges[i] * 3 + 1],
+					transformedVertices[edges[i + 1] * 3], transformedVertices[edges[i + 1] * 3 + 1])
+		Next
+
+    End Method
+End Type
+```
+
+## Column-Major vs. Row-Major Matrices
+
+In `brl.matrix`, we use column-major ordering for matrices. Column-major ordering is a convention
+in which elements are stored column by column in memory. It is the opposite of row-major ordering, where
+elements are stored row by row. This distinction is important when performing operations like matrix
+multiplication or when applying transformations to vectors or other matrices.
+
+Column-major ordering is commonly used in graphics programming and some mathematical libraries. In
+this convention, when applying transformations, the order in which they are applied is reversed
+compared to row-major ordering. This means that when you want to apply multiple transformations,
+you should apply them in the reverse order that you would with row-major ordering.
+
+For example, in column-major ordering, to rotate an object around the X, Y, and Z axes and then
+translate it, you would first apply the translation, then the rotation around the Z axis, followed
+by the rotation around the Y axis, and finally the rotation around the X axis.
+
+## Determinant, Inverse, and Transpose in Matrices
+
+### Determinant
+
+The determinant is a scalar value associated with square matrices that carries essential
+information about the matrix's properties. It has several important geometric interpretations
+and applications in linear algebra.
+
+In the context of 2D transformations, the determinant represents the area scaling factor when a
+matrix is applied to a vector. If the determinant is positive, the transformation preserves the
+orientation; if it's negative, the orientation is reversed. A determinant equal to zero indicates
+that the transformation collapses the vector onto a lower-dimensional subspace (e.g., a line or a point),
+making the matrix singular and non-invertible.
+
+Mathematically, the determinant of a 2x2 matrix is calculated as follows:
+
+```
+|A| = |a  b|
+      |c  d|
+
+|A| = ad - bc
+```
+
+Here's an example illustrating how to calculate the determinant of a 2x2 matrix using the #SMat2D struct:
+
+```blitzmax
+SuperStrict
+
+Framework BRL.StandardIO
+Import BRL.Matrix
+
+' Define matrix elements
+Local a:Double = 3.0
+Local b:Double = 2.0
+Local c:Double = 5.0
+Local d:Double = 4.0
+
+' Create a 2x2 matrix
+Local mat:SMat2D = New SMat2D(a, b, c, d)
+
+' Calculate the determinant
+Local det:Double = mat.Determinant()
+
+' Print the determinant
+Print "Determinant: " + det
+```
+When you run this example, it will create a 2x2 matrix with the specified elements,
+calculate the determinant using the `Determinant()` method provided by #SMat2D, and print the resulting
+determinant value. In this case, the output will be:
+```
+Determinant: -2.0
+```
+
+For a 3x3 matrix, the determinant can be calculated using the following formula:
+```
+|A| = |a  b  c|
+      |d  e  f|
+      |g  h  i|
+
+|A| = a(ei - fh) - b(di - fg) + c(dh - eg)
+```
+
+Here's an example illustrating how to calculate the determinant of a 3x3 matrix using the #SMat3D struct:
+```blitzmax
+SuperStrict
+
+Framework BRL.StandardIO
+Import BRL.Matrix
+
+' Define matrix elements
+Local a:Double = 1.0
+Local b:Double = 2.0
+Local c:Double = 3.0
+Local d:Double = 4.0
+Local e:Double = 5.0
+Local f:Double = 6.0
+Local g:Double = 7.0
+Local h:Double = 8.0
+Local i:Double = 9.0
+
+' Create a 3x3 matrix
+Local mat:SMat3D = New SMat3D(a, b, c, d, e, f, g, h, i)
+
+' Calculate the determinant
+Local det:Double = mat.Determinant()
+
+' Print the determinant
+Print "Determinant: " + det
+```
+
+When you run this example, it will create a 3x3 matrix with the specified elements,
+calculate the determinant using the `Determinant()` method provided by #SMat3D, and print the
+resulting determinant value. In this case, the output will be:
+```
+Determinant: 0.0
+```
+
+### Inverse
+
+The inverse of a matrix is another matrix that, when multiplied with the original matrix,
+results in the identity matrix. In other words, for a matrix A, its inverse A⁻¹ exists if
+and only if A * A⁻¹ = A⁻¹ * A = I, where I is the identity matrix. Not all matrices have
+inverses; only square matrices (i.e., matrices with the same number of rows and columns) may
+have inverses, and even then, not all square matrices are invertible.
+
+For a 2x2 matrix:
+```
+| a  b |
+| c  d |
+```
+The inverse can be calculated using the following formula:
+```
+1 / (ad - bc) * |  d  -b |
+                | -c   a |
+```
+
+The term (ad - bc) is the determinant of the matrix. If the determinant is zero, the matrix
+is singular and does not have an inverse.
+
+For a 3x3 matrix, the process is more complicated and involves finding the matrix of minors,
+the matrix of cofactors, and finally, the adjugate matrix. The inverse can then be computed
+by dividing the adjugate matrix by the determinant of the original matrix.
+
+Here is an example for finding the inverse of a 2x2 matrix using the #SMat2D struct:
+```blitzmax
+SuperStrict
+
+Framework brl.standardio
+Import brl.matrix
+
+' Create a 2x2 matrix
+Local a:Double = 3
+Local b:Double = 2
+Local c:Double = 5
+Local d:Double = 3
+
+Local mat:SMat2D = New SMat2D(a, b, c, d)
+
+' Calculate the inverse
+Local matInverse:SMat2D = mat.Invert()
+
+' Print the original and inverse matrices
+Print "Original matrix:~n" + mat.ToString()
+Print "Inverse matrix:~n" + matInverse.ToString()
+```
+When you run this example, it will output the original 2x2 matrix and its inverse:
+```
+Original matrix:
+3.000 2.000
+5.000 3.000
+Inverse matrix:
+-1.000 0.667
+ 1.667 -1.000
+```
+
+
+And here is an example for finding the inverse of a 3x3 matrix using the #SMat3D struct:
+```blitzmax
+SuperStrict
+
+Framework brl.standardio
+Import brl.matrix
+
+' Create a 3x3 matrix
+Local a:Double = 1
+Local b:Double = 2
+Local c:Double = 3
+Local d:Double = 0
+Local e:Double = 1
+Local f:Double = 4
+Local g:Double = 5
+Local h:Double = 6
+Local i:Double = 0
+
+Local mat:SMat3D = New SMat3D(a, b, c, d, e, f, g, h, i)
+
+' Calculate the inverse
+Local matInverse:SMat3D = mat.Invert()
+
+' Print the original and inverse matrices
+Print "Original matrix: " + mat.ToString()
+Print "Inverse matrix: " + matInverse.ToString()
+```
+When you run this example, it will output the original 3x3 matrix and its inverse:
+```
+Original matrix:
+ 1.000 2.000 3.000
+ 0.000 1.000 4.000
+ 5.000 6.000 0.000
+Inverse matrix:
+ -24.000 18.000 5.000
+ 20.000 -15.000 -4.000
+ -5.000 4.000 1.000
+```
+
+### Transpose
+
+The transpose of a matrix is a new matrix obtained by interchanging its rows and columns.
+In other words, the transpose of a matrix A is a new matrix Aᵀ, where the element Aᵀ[i, j] = A[j, i].
+The transpose operation has several important properties and applications in linear algebra, including
+simplifying matrix equations and working with symmetric matrices.
+
+For a 2x2 matrix A:
+```
+A = |a  b|       Aᵀ = |a  c|
+    |c  d|            |b  d|
+```
+
+For a 3x3 matrix A:
+```
+A = |a  b  c|       Aᵀ = |a  d  g|
+    |d  e  f|            |b  e  h|
+    |g  h  i|            |c  f  i|
+```
+
+Here's an example illustrating how to calculate the transpose of a 2x2 matrix using the #SMat2D struct.
+```blitzmax
+SuperStrict
+
+Framework brl.standardIO
+Import brl.matrix
+
+' Define matrix elements
+Local a:Double = 1.0
+Local b:Double = 2.0
+Local c:Double = 3.0
+Local d:Double = 4.0
+
+' Create a 2x2 matrix
+Local mat:SMat2D = New SMat2D(a, b, c, d)
+
+' Calculate the transpose
+Local matTranspose:SMat2D = mat.Transpose()
+
+' Print the original and transposed matrices
+Print "Original matrix:~n" + mat.ToString()
+Print "Transposed matrix:~n" + matTranspose.ToString()
+```
+When you run this example, it will create a 2x2 matrix with the specified elements, calculate
+the transpose using the Transpose() method provided by the #SMat2D struct, and print the original
+and transposed matrices. In this case, the output will be:
+```
+Original matrix:
+1.0,  2.0
+3.0,  4.0
+Transposed matrix:
+1.0  3.0
+2.0  4.0
+```
+
+And an example for calculating the transpose of a 3x3 matrix using the #SMat3D struct.
+```blitzmax
+SuperStrict
+
+Framework brl.standardIO
+Import brl.matrix
+
+' Define matrix elements
+Local a:Double = 1.0
+Local b:Double = 2.0
+Local c:Double = 3.0
+Local d:Double = 4.0
+Local e:Double = 5.0
+Local f:Double = 6.0
+Local g:Double = 7.0
+Local h:Double = 8.0
+Local i:Double = 9.0
+
+' Create a 3x3 matrix
+Local mat:SMat3D = New SMat3D(a, b, c, d, e, f, g, h, i)
+
+' Calculate the transpose
+Local matTranspose:SMat3D = mat.Transpose()
+
+' Print the original and transposed matrices
+Print "Original matrix: " + mat.ToString()
+Print "Transposed matrix: " + matTranspose.ToString()
+```
+
+When you run this example, it will create a 3x3 matrix with the specified elements,
+calculate the transpose using the Transpose() method provided by the #SMat3D struct, and print the
+original and transposed matrices. In this case, the output will be:
+```
+Original matrix:
+1.0  2.0  3.0
+4.0  5.0  6.0
+7.0  8.0  9.0
+Transposed matrix:
+1.0  4.0  7.0
+2.0  5.0  8.0
+3.0  6.0  9.0
+```
+
+
+Understanding the transpose concept and its properties is important when working with matrices
+in your BlitzMax projects. The transpose operation can help simplify matrix equations and work with
+symmetric matrices, among other applications. By transposing a matrix, you can manipulate its elements
+and apply various transformations as required in your project.
+
+## Scaling, rotation, and shearing matrices
+
+Scaling, rotation, and shearing matrices are fundamental linear transformations used in various fields, such as
+computer graphics, physics simulations, and geometric modeling. These transformations can be applied to vectors or points
+to change their position, orientation, or shape. 
+
+### Scaling matrices
+
+Scaling is the process of resizing an object uniformly or non-uniformly along its axes. Scaling matrices are diagonal matrices
+that have scaling factors along the diagonal elements, and zeros elsewhere.
+
+For 2D scaling:
+
+```
+| sx  0  |
+| 0   sy |
+```
+
+For 3D scaling:
+```
+| sx  0   0  |
+| 0   sy  0  |
+| 0   0   sz |
+```
+
+Here, sx, sy, and sz are the scaling factors along the x, y, and z axes, respectively. To apply the scaling transformation, you multiply
+the scaling matrix by the vector or point you want to scale.
+
+### Rotation matrices
+
+Rotation is the process of rotating an object around a point or an axis. Rotation matrices are used to represent the rotation
+transformations in both 2D and 3D spaces.
+
+For 2D rotation around the origin by angle θ:
+
+```
+| cos(θ)  -sin(θ) |
+| sin(θ)   cos(θ) |
+```
+
+For 3D rotation around an arbitrary axis (x, y, z) by angle θ, the rotation matrix is more complex. One common method is using
+the axis-angle representation, which involves the Rodrigues' rotation formula. The formula for the 3D rotation matrix is as follows:
+
+```
+R = I + sin(θ) * K + (1 - cos(θ)) * K^2
+```
+
+Where `I` is the identity matrix, `θ` is the angle of rotation, and `K` is the skew-symmetric matrix representation of the axis vector.
+
+### Shearing matrices
+
+Shearing is the process of transforming an object by displacing its points along one axis based on the displacement of points along a
+parallel axis. Shearing matrices are used to represent these transformations.
+
+For 2D shearing:
+
+```
+| 1  shx |
+| shy  1 |
+```
+
+For 3D shearing along the x-axis:
+
+```
+| 1  shy  shz |
+| 0   1    0  |
+| 0   0    1  |
+```
+
+And similar matrices can be defined for shearing along the y-axis and z-axis. Here, `shx`, `shy`, and `shz` represent the shearing factors.
+
+When applying these transformations, it's important to consider the order of operations, as matrix multiplication is not commutative.
+Typically, scaling and shearing are applied first, followed by rotation, and finally translation. Also, remember that these matrices should
+be applied to homogeneous coordinates for translation to work correctly. In 3D graphics, this often involves using 4x4 matrices with an
+additional row and column for the homogeneous coordinate.
+
+## Matrix multiplication
+
+Matrix multiplication is an essential operation in linear algebra and has numerous applications in computer graphics, physics, and other fields.
+Multiplying two matrices involves specific rules, and it's important to understand the dimensions of the matrices and how to perform the
+multiplication element-wise.
+
+### Rules for Matrix Multiplication
+
+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.
+If matrix A has dimensions m × n and matrix B has dimensions n × p, then the product AB will have dimensions m × p.
+
+`(AB)_ij = A_i1 * B_1j + A_i2 * B_2j + ... + A_in * B_nj`
+
+where (AB)_ij represents the element in the i-th row and j-th column of the resulting matrix AB.
+
+### Element-wise matrix multiplication
+
+To multiply two matrices element-wise, follow these steps:
+
+1. Verify that the dimensions of the matrices are compatible for multiplication. The number of columns in matrix A must be equal
+to the number of rows in matrix B.
+
+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.
+
+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
+and the column elements in matrix B:
+`C_ij = A_i1 * B_1j + A_i2 * B_2j + ... + A_in * B_nj`
+Iterate through all elements in matrix C, computing their values using the above formula.
+
+4. The resulting matrix C represents the product of matrices A and B.
+
+It's important to note that matrix multiplication is not commutative, meaning that AB ≠ BA in general. However, it is
+associative (A(BC) = (AB)C) and distributive over addition (A(B+C) = AB + AC).
+
+The `CompMul()` method can be used to perform element-wise matrix multiplication.
+
+### Matrix multiplication using the dot product
+
+Matrix multiplication is a fundamental operation in linear algebra, and it is performed using the dot product.
+It is important to understand that matrix multiplication is not the same as element-wise multiplication. In matrix
+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.
+
+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).
+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
+matrix, C, will have dimensions m x q (m rows and q columns).
+
+Here is the formula for matrix multiplication using the dot product:
+
+C[i][j] = Σ (A[i][k] * B[k][j]) for k = 0 to n-1
+
+where i ranges from 0 to m-1 and j ranges from 0 to q-1.
+
+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.
+
+Let's see an example with two 3x3 matrices:
+
+```
+A = | a b c |     B = | p q r |
+    | d e f |         | s t u |
+    | g h i |         | v w x |
+
+C = | (a*p + b*s + c*v) (a*q + b*t + c*w) (a*r + b*u + c*x) |
+    | (d*p + e*s + f*v) (d*q + e*t + f*w) (d*r + e*u + f*x) |
+    | (g*p + h*s + i*v) (g*q + h*t + i*w) (g*r + h*u + i*x) |
+```
+
+The `Operator *()` method can be used to perform matrix multiplication using the dot product.
+
+### Vector Multiplication
+
+Matrix-vector multiplication is a fundamental operation in linear algebra, computer graphics, and many other fields. This operation
+is used to apply transformations, such as scaling, rotation, and translation, to points and vectors in 2D and 3D space. In this section,
+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.
+
+#### 2D Vectors ( #SVec2D, #SVec2F, #SVec2I )
+
+To multiply a 2x2 matrix by a 2D vector, perform the following steps:
+
+1. Multiply each element of the first row of the matrix by the corresponding element of the vector.
+2. Sum the results from step 1 to obtain the first element of the resulting vector.
+3. Multiply each element of the second row of the matrix by the corresponding element of the vector.
+4. Sum the results from step 3 to obtain the second element of the resulting vector.
+
+Mathematically, this can be represented as:
+
+```
+| a c | | x |   | a * x + c * y |
+| b d | | y | = | b * x + d * y |
+```
+
+#### 3D Vectors ( #SVec3D, #SVec3F, #SVec3I )
+
+To multiply a 3x3 matrix by a 3D vector, follow these steps:
+
+1. Multiply each element of the first row of the matrix by the corresponding element of the vector.
+2. Sum the results from step 1 to obtain the first element of the resulting vector.
+3. Multiply each element of the second row of the matrix by the corresponding element of the vector.
+4. Sum the results from step 3 to obtain the second element of the resulting vector.
+5. Multiply each element of the third row of the matrix by the corresponding element of the vector.
+6. Sum the results from step 5 to obtain the third element of the resulting vector.
+
+Mathematically, this can be represented as:
+
+```
+| a d g | | x |   | a * x + d * y + g * z |
+| b e h | | y | = | b * x + e * y + h * z |
+| c f i | | z |   | c * x + f * y + i * z |
+```
+
+You can use the `Apply()` method to multiply a matrix by a vector.
+
+Here's an example:
+
+```blitzmax
+Local mat2D:SMat2D = SMat2D.Identity()
+Local vec2D:SVec2D = New SVec2D(2, 3)
+Local result2D:SVec2D = mat2D.Apply(vec2D)
+
+Local mat3D:SMat3D = SMat3D.Identity()
+Local vec3D:SVec3D = New SVec3D(2, 3, 4)
+Local result3D:SVec3D = mat3D.Apply(vec3D)
+```
+
+## The Identity Matrix
+
+The identity matrix is a special square matrix that has ones on the diagonal and zeros elsewhere. In mathematical notation,
+an identity matrix of size n x n is denoted as Iₙ. Here's an example of a 3x3 identity matrix:
+
+```
+I₃ = | 1 0 0 |
+     | 0 1 0 |
+     | 0 0 1 |
+```
+
+The identity matrix plays a crucial role in matrix algebra, as it serves as the "neutral element" for matrix multiplication. When you
+multiply any matrix by the identity matrix, the result is the original matrix unchanged. Mathematically, this property can be written as:
+
+A * Iₙ = A
+
+Iₙ * A = A
+
+where A is any n x n matrix.
+
+This property is analogous to the number 1 in scalar multiplication. Just as multiplying any number by 1 leaves the number unchanged
+(e.g., 7 * 1 = 7), multiplying any matrix by the identity matrix leaves the matrix unchanged.
+
+The identity matrix is also important for other matrix operations. For example, when calculating the inverse of a matrix, the goal is to
+find a matrix B such that A * B = Iₙ. When this condition is met, matrix B is the inverse of matrix A.
+
+The `Identity()` method allows you create an identity matrix.
+
+## Linear Transformations
+
+Matrices are often used to represent linear transformations in various fields, including computer graphics and linear algebra.
+A linear transformation is a function that maps vectors from one vector space to another while preserving the operations of vector
+addition and scalar multiplication. In this section, we will discuss some of the key properties of linear transformations and how
+matrices can be used to represent them.
+
+### Linearity
+
+A linear transformation, T, has the property of linearity, which means it satisfies the following conditions:
+
+1. T(u + v) = T(u) + T(v) for all vectors u and v.
+2. T(c * u) = c * T(u) for all vectors u and any scalar c.
+
+This property ensures that the transformation maintains the structure of the vector space, preserving
+parallelism and proportions between the vectors.
+
+### Invertibility
+
+A linear transformation is invertible if there exists another transformation, called its inverse, that can undo the effect of the original
+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.
+Invertible transformations are essential in many applications, as they allow us to reverse the effects of a transformation and recover the original data.
+
+### Effect on Geometry
+
+Linear transformations can have various effects on the geometry of shapes, including:
+
+1. Scaling: A transformation that changes the size of a shape, either uniformly or non-uniformly along different axes.
+2. Rotation: A transformation that rotates a shape around a specified point or axis.
+3. Shearing: A transformation that distorts a shape by shifting its points along one axis relative to the other axis.
+
+## Orthogonal and Orthonormal Matrices
+
+Orthogonal and orthonormal matrices are special types of square matrices that have unique properties, making them particularly useful in
+various applications such as computer graphics, physics, and linear algebra.
+
+### Orthogonal Matrices
+
+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
+matrix. In other words, the columns (and rows) of an orthogonal matrix are orthogonal to each other, meaning they form a 90-degree angle
+and their dot product is zero.
+
+The geometric interpretation of orthogonal matrices is that they represent transformations that preserve lengths and angles, such as
+rotations and reflections.
+
+### Orthonormal Matrices
+
+An orthonormal matrix is an orthogonal matrix where the columns (and rows) are not only orthogonal but also have unit length (i.e., they
+are normalized). Orthonormal matrices simplify calculations in various applications, as they do not change the length of the vectors they transform.
+
+### Applications
+
+Orthogonal and orthonormal matrices play a significant role in computer graphics, as they are used to represent transformations that maintain
+the geometry of 3D objects. For instance, they can be employed to create rotation matrices, which are essential for rotating objects in 3D space.
+
+Here's a BlitzMax example demonstrating the use of an orthonormal matrix to represent a 3D rotation:
+
+```blitzmax
+Local angleX:Float = 30 ' in degrees
+Local angleY:Float = 45 ' in degrees
+Local angleZ:Float = 60 ' in degrees
+
+' Create orthonormal rotation matrices for each axis
+Local rotationMatrixX:SMat3D = SMat3D.RotationX(angleX)
+Local rotationMatrixY:SMat3D = SMat3D.RotationY(angleY)
+Local rotationMatrixZ:SMat3D = SMat3D.RotationZ(angleZ)
+
+' Combine the rotations
+Local rotationMatrix:SMat3D = rotationMatrixX * rotationMatrixY * rotationMatrixZ
+
+' Apply the rotation to a 3D vector
+Local vec:SVec3D = New SVec3D(1, 2, 3)
+Local rotatedVec:SVec3D = rotationMatrix.Apply(vec)
+```
+
+When the rotation matrix is applied to a 3D vector, it will rotate the vector according to the specified angles.
+The order in which the rotations are combined (in this example, X, then Y, then Z) will determine the final rotation.

+ 106 - 17
matrix.mod/matrix.bmx

@@ -86,7 +86,7 @@ Struct SMat2D
 	End Method
 	
 	Rem
-	bbdoc: Multiplies the matrix by @z, returning a new matrix.
+	bbdoc: Multiplies the matrix by @z, the dot product, returning a new matrix.
 	End Rem
 	Method Operator*:SMat2D(z:SMat2D)
 		Return New SMat2D(a * z.a + c * z.b, b * z.a + d * z.b, a * z.c + c * z.d, b * z.c + d * z.d)
@@ -100,7 +100,7 @@ Struct SMat2D
 	End Method
 	
 	Rem
-	bbdoc: Multiplies the matrix by @z by its components, return a new matrix.
+	bbdoc: Multiplies the matrix by @z by its components, or element-wise matrix multiplication, return a new matrix.
 	End Rem
 	Method CompMul:SMat2D(z:SMat2D)
 		Return New SMat2D(a * z.a, b * z.b, c * z.c, d * z.d)
@@ -250,7 +250,7 @@ Struct SMat3D
 	End Method
 	
 	Rem
-	bbdoc: Multiplies the matrix by @z, returning a new matrix.
+	bbdoc: Multiplies the matrix by @z, the dot product, returning a new matrix.
 	End Rem
 	Method Operator*:SMat3D(z:SMat3D Var)
 		Local a00:Double = a
@@ -298,7 +298,7 @@ Struct SMat3D
 	End Method
 	
 	Rem
-	bbdoc: Multiplies the matrix by @z by its components, return a new matrix.
+	bbdoc: Multiplies the matrix by @z by its components, or element-wise matrix multiplication, return a new matrix.
 	End Rem
 	Method CompMul:SMat3D(z:SMat3D Var)
 		Return New SMat3D(a * z.a, b * z.b, c * z.c, d * z.d, e * z.e, f * z.f, g * z.g, h * z.h, i * z.i)
@@ -353,7 +353,7 @@ Struct SMat3D
 	End Method
 	
 	Rem
-	bbdoc: Rotates the matrix by @angle degrees, returning a new matrix.
+	bbdoc: Rotates the matrix on a 2D rotation in the XY plane by @angle degrees, returning a new matrix.
 	End Rem
 	Method Rotate:SMat3D(angle:Double)
 		Local sa:Double = Sin(angle)
@@ -366,9 +366,26 @@ Struct SMat3D
 			ca * f - sa * c, ..
 			g, h, i)
 	End Method
+
+	Rem
+	bbdoc: Rotates the matrix around the Z axis by @angle degrees, returning a new matrix.
+	End Rem
+	Method RotateZ:SMat3D(angle:Double)
+		Local ca:Double = Cos(angle)
+		Local sa:Double = Sin(angle)
 	
+		Return New SMat3D( ..
+			a * ca - c * sa, ..
+			b * ca - d * sa, ..
+			0, ..
+			a * sa + c * ca, ..
+			b * sa + d * ca, ..
+			0, ..
+			g, h, i)
+	End Method
+
 	Rem
-	bbdoc: Retrns a rotation matrix of @angle degrees.
+	bbdoc: Returns a rotation matrix of @angle degrees.
 	End Rem
 	Function Rotation:SMat3D(angle:Double)
 		Local sa:Double = Sin(angle)
@@ -391,6 +408,30 @@ Struct SMat3D
 	Function Scaling:SMat3D(s:SVec2D)
 		Return New SMat3D(s.x, 0, 0, 0, s.y, 0, 0, 0, 1)
 	End Function
+
+	Rem
+	bbdoc: Returns a translation with the specified @x, @y, and @z displacements.
+	End Rem
+	Method Translate:SMat3D(x:Double, y:Double, z:Double)
+		Return New SMat3D( ..
+			a, b, c, ..
+			d, e, f, ..
+			g + a * x + b * y + c * z, ..
+			h + d * x + e * y + f * z, ..
+			i + g * x + h * y + i * z)
+	End Method
+
+	Rem
+	bbdoc: Returns a translation with displacement vector @s.
+	End Rem
+	Method Translate:SMat3D(t:SVec3D)
+		Return New SMat3D( ..
+			a, b, c, ..
+			d, e, f, ..
+			g + a * t.x + b * t.y + c * t.z, ..
+			h + d * t.x + e * t.y + f * t.z, ..
+			i + g * t.x + h * t.y + i * t.z)
+	End Method
 	
 	Rem
 	bbdoc: Returns a transposition of the matrix.
@@ -520,7 +561,7 @@ Struct SMat4D
 	End Method
 
 	Rem
-	bbdoc: Multiplies the matrix by @z, returning a new matrix. 
+	bbdoc: Multiplies the matrix by @z, the dot product, returning a new matrix. 
 	End Rem
 	Method Operator*:SMat4D(z:SMat4D Var)
 		Local a00:Double = a
@@ -612,7 +653,7 @@ Struct SMat4D
 	End Method
 	
 	Rem
-	bbdoc: Multiplies the matrix by @z by its components, returning a new matrix.
+	bbdoc: Multiplies the matrix by @z by its components, or element-wise matrix multiplication, returning a new matrix.
 	End Rem
 	Method CompMul:SMat4D(z:SMat4D Var)
 		Return New SMat4D(a * z.a, b * z.b, c * z.c, d * z.d, ..
@@ -942,7 +983,7 @@ Struct SMat2F
 	End Method
 	
 	Rem
-	bbdoc: Multiplies the matrix by @z, returning a new matrix.
+	bbdoc: Multiplies the matrix by @z, the dot product, returning a new matrix.
 	End Rem
 	Method Operator*:SMat2F(z:SMat2F)
 		Return New SMat2F(a * z.a + c * z.b, b * z.a + d * z.b, a * z.c + c * z.d, b * z.c + d * z.d)
@@ -1026,7 +1067,7 @@ Struct SMat2F
 	Function Scaling:SMat2F(s:SVec2D)
 		Return New SMat2F(Float(s.x), 0, 0, Float(s.y))
 	End Function
-	
+
 	Rem
 	bbdoc: Returns the transpose of this matrix.
 	End Rem
@@ -1120,7 +1161,7 @@ Struct SMat3F
 	End Method
 	
 	Rem
-	bbdoc: Multiplies the matrix by @z, returning a new matrix.
+	bbdoc: Multiplies the matrix by @z, the dot product, returning a new matrix.
 	End Rem
 	Method Operator*:SMat3F(z:SMat3F Var)
 		Local a00:Float = a
@@ -1277,7 +1318,31 @@ Struct SMat3F
 	Function Scaling:SMat3F(s:SVec2D)
 		Return New SMat3F(Float(s.x), 0, 0, 0, Float(s.y), 0, 0, 0, 1)
 	End Function
-	
+
+	Rem
+	bbdoc: Returns a translation with the specified @x, @y, and @z displacements.
+	End Rem
+	Method Translate:SMat3F(x:Float, y:Float, z:Float)
+		Return New SMat3F( ..
+			a, b, c, ..
+			d, e, f, ..
+			g + a * x + b * y + c * z, ..
+			h + d * x + e * y + f * z, ..
+			i + g * x + h * y + i * z)
+	End Method
+
+	Rem
+	bbdoc: Returns a translation with displacement vector @s.
+	End Rem
+	Method Translate:SMat3F(t:SVec3F)
+		Return New SMat3F( ..
+			a, b, c, ..
+			d, e, f, ..
+			g + a * t.x + b * t.y + c * t.z, ..
+			h + d * t.x + e * t.y + f * t.z, ..
+			i + g * t.x + h * t.y + i * t.z)
+	End Method
+
 	Rem
 	bbdoc: Returns a transposition of the matrix.
 	End Rem
@@ -1406,7 +1471,7 @@ Struct SMat4F
 	End Method
 
 	Rem
-	bbdoc: Multiplies the matrix by @z, returning a new matrix. 
+	bbdoc: Multiplies the matrix by @z, the dot product, returning a new matrix. 
 	End Rem
 	Method Operator*:SMat4F(z:SMat4F Var)
 		Local a00:Float = a
@@ -1872,7 +1937,7 @@ Struct SMat2I
 	End Method
 	
 	Rem
-	bbdoc: Multiplies the matrix by @z, returning a new matrix.
+	bbdoc: Multiplies the matrix by @z, the dot product, returning a new matrix.
 	End Rem
 	Method Operator*:SMat2I(z:SMat2I)
 		Return New SMat2I(a * z.a + c * z.b, b * z.a + d * z.b, a * z.c + c * z.d, b * z.c + d * z.d)
@@ -2050,7 +2115,7 @@ Struct SMat3I
 	End Method
 	
 	Rem
-	bbdoc: Multiplies the matrix by @z, returning a new matrix.
+	bbdoc: Multiplies the matrix by @z, the dot product, returning a new matrix.
 	End Rem
 	Method Operator*:SMat3I(z:SMat3I Var)
 		Local a00:Int = a
@@ -2223,7 +2288,31 @@ Struct SMat3I
 	Function Scaling:SMat3I(s:SVec2F)
 		Return New SMat3I(Int(s.x), 0, 0, 0, Int(s.y), 0, 0, 0, 1)
 	End Function
-	
+
+	Rem
+	bbdoc: Returns a translation with the specified @x, @y, and @z displacements.
+	End Rem
+	Method Translate:SMat3I(x:Int, y:Int, z:Int)
+		Return New SMat3I( ..
+			a, b, c, ..
+			d, e, f, ..
+			g + a * x + b * y + c * z, ..
+			h + d * x + e * y + f * z, ..
+			i + g * x + h * y + i * z)
+	End Method
+
+	Rem
+	bbdoc: Returns a translation with displacement vector @s.
+	End Rem
+	Method Translate:SMat3I(t:SVec3I)
+		Return New SMat3I( ..
+			a, b, c, ..
+			d, e, f, ..
+			g + a * t.x + b * t.y + c * t.z, ..
+			h + d * t.x + e * t.y + f * t.z, ..
+			i + g * t.x + h * t.y + i * t.z)
+	End Method
+
 	Rem
 	bbdoc: Returns a transposition of the matrix.
 	End Rem
@@ -2352,7 +2441,7 @@ Struct SMat4I
 	End Method
 
 	Rem
-	bbdoc: Multiplies the matrix by @z, returning a new matrix. 
+	bbdoc: Multiplies the matrix by @z, the dot product, returning a new matrix. 
 	End Rem
 	Method Operator*:SMat4I(z:SMat4I Var)
 		Local a00:Int = a