The theory of matrices was first developed (or so I read) in relation to geometric transformations.
The best single reference that explained Transformation Matrices to me esp with regards to graphics programming was Rod Stephens book Visual Basic Graphics Programming, which is 20+ years old. It’s a comprehensive but clear introduction. There are also many linear algebra math videos on Khan, Youtube etc that i am just starting to explore. Stephens multiplies his vector from the left of the matrix. Everyone else does it from the right, so i cannot use his examples as-is, but looking at his methods has been very helpful.
A vector is also a matrix, and its a point. Multiplying a square matrix by a column vector yields another column vector. Thats how the point gets transformed. The transformation matrix can contain numbers for scaling, translating (moving) and rotation.
The basic idea can be shown with a 2D autocad implementation and then extend to full 3D. Matrix math, and multiplication of matrices is somewhat hard to grasp, but programming it from scratch is good reinforcement. The basic 3D matrix is a 4×4 grid of doubles. The 2D matrix is 3×3.
The first sub initializes an identity matrix, which is the base. The subs that create Translation, Scaling and Rotation numbers will modify the identity matrix. To combine these operations into one, multiplication of two 3×3 matrices is done. Finally to apply the matrix to a point, the matrix is multiplied by the 1×3 point vector.
In reality, we are going to use arrays as matrices, and the array of a 1×3 is actually just a 3, but we are going to treat it as a column. VB.net arrays start with index zero. Most matrix references or maybe all use 1 as the base number.
Here is the 3×3 initial matrix with value 1 on the main diagonal and zero elsewhere. Its a function that returns the result and does not take any arguments.
show_mat(M) is a sub to show the matrix in the immediate window screen for checking.
Public Function m3x3_ID() As Double(,) Dim M(0 To 2, 0 To 2) As Double Dim i, j As Integer For i = 0 To 2 For j = 0 To 2 If i = j Then M(i, j) = 1 Else M(i, j) = 0 End If Next Next show_mat(M) Return M End Function Public Sub show_mat(M(,) As Double) Dim i, j As Integer Dim str As String = "" For i = 0 To UBound(M, 1) For j = 0 To UBound(M, 2) If j = 0 Then str = str & vbCrLf End If str = str & M(i, j) & vbTab Next Next Debug.Print(str) End Sub
We need a sub to multiply a 3×3 matrix by a 1×3 vector. MxV. This is a simple program that takes the Matrix and Vector as arguments and returns a Vector.
For 2D the Z value is not required but is required by autocad, leading to a bit of complication we wont have with 3D.
Function MxV(M(,) As Double, V() As Double) As Double() Dim V2(2) As Double V2(0) = M(0, 0) * V(0) + M(0, 1) * V(1) + M(0, 2) * 1 V2(1) = M(1, 0) * V(0) + M(1, 1) * V(1) + M(1, 2) * 1 V2(2) = M(2, 0) * V(0) + M(2, 1) * V(1) + M(2, 2) * 1 'need to zero this out for 2D demo purpose V2(2) = 0 show_pt(V2) Return V2 End Function
Matrices are combined by multiplication. I still have to show myself why that works, when rotation and scaling use the same cells. The multiplication of two 3×3 matrices is row by column. You could do it with brute force, but studying the concise math definition –
c(ij) = a(i1)b(1j) + a(i2)b(2j) + a(i3)b(3j)
– shows the basic i and j loop variables and the third variable just goes from 1 to 3. Modifying slightly for our 0 to 2 array gives a 3 variable loop. Matrices A and B are 3×3. The order matters. Multiplication is not commutative. A movement then a rotation is different than a rotation then a movement. The function returns the new matrix.
Function MxM(A(,) As Double, B(,) As Double) As Double(,) Dim C(2, 2) As Double Dim i, j, n As Integer Dim value As Double For i = 0 To 2 For j = 0 To 2 value = 0 For n = 0 To 2 value = value + A(i, n) * B(n, j) Next C(i, j) = value Next Next show_mat(C) Return C End Function