123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795 |
- 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.
|