Hi there,
the best thing you can do to understand stuff is to write down explicitly what is happening. So let's do that for a 3x3 matrix and corresponding vector.
If you multiply a matrix A and a vector x you get the result vector r:
A*x=r
If you write it down with values you would get:
|a0 b0 c0| |x0| |r0|
|a1 b1 c1| * |x1| = |r1|
|a2 b2 c2| |x2| |r2|
Or if you use the row notation it would be:
| a0 a1 a2 |
| b0 b1 b2 |
|x0 x1 x2| * | c0 c1 b3 | = | r0 r1 r2 |
Notice that the difference between both notations is, that you have row vectors instead of column vectors, the vector is now to the left of the matrix and the values of the matrix are flipped by exchanging rows and columns. If you see the vectors as 3x1 matrices, you have also just flipped rows and columns. This "flipping" is called transposing a matrix, but we won't bother with that anymore. It is just important for you to realize, that both notations I showed you give the exact same results if you compare the values of the equation. I favour the column notation and will use it, from now on.
Okay, what you know so far is, that you multiply a vector with a matrix to get a transformed vector. So let's have a look what is actually calculated. As @_WeirdCat_ already mentioned, the matrix-vector (or matrix-matrix) product calculates the dot product of the left-hand matrices/vector row and the right-hand matrix/vector columns. If you visualize it:
|x0|
|x1|
|x2|
|a0 b0 c0| |r0| |dot(row0ofA, x)| |a0*x0 + b0*x1 + c0*x2 |
|a1 b1 c1| |r1| = |dot(row1ofA, x)| = |a1*x0 + b1*x1 + c1*x2 |
|a2 b2 c2| |r2| |dot(row2ofA, x)| |a2*x0 + b2*x1 + c2*x2 |
If you remove some stuff you get
|r0| |a0*x0 + b0*x1 + c0*x2|
|r1| = |a1*x0 + b1*x1 + c1*x2|
|r2| |a2*x0 + b2*x1 + c2*x2|
These are basically just 3 equations for the 3 values of the new vector r:
r0 = a0*x0 + b0*x1 + c0*x2
r1 = a1*x0 + b1*x1 + c1*x2
r2 = a2*x0 + b2*x1 + c2*x2
Each value of the result vector is a weighted sum of all values from the original vector. All a matrix does is providing the weighting factors.
To get a better understanding, let us monitor the basic operations that we use in computer graphics:
Let's say we want to scale an object by 2 along the y-Axis, then you would just multiply the y-component by 2:
r0 = x0
r1 = 2*x1
r2 = x2
So writing it down as a weighted sum of all components gives:
r0 = 1*x0 + 0*x1 + 0*x2
r1 = 0*x0 + 2*x1 + 0*x2
r2 = 0*x0 + 0*x1 + 1*x2
Or as matrix notation:
|1 0 0| |x0| |r0|
|0 2 0| * |x1| = |r1|
|0 0 1| |x2| |r2|
Not so hard, right?
So, now you want to rotate around the z-axis. Means the z values remain constant, but the x and y values change. If you rotate around a certain angle P, then you will get the formulas for each component:
r0 = cos(P)*x0 - sin(P)*x1
r1 = sin(P)*x0 + cos(P)*x1
r2 = x2
Just look up, why you have to use these combinations of sinus and cosinus: https://en.wikipedia.org/wiki/Rotation_matrix
So as weighted sum we get:
r0 = cos(P)*x0 + -sin(P)*x1 + 0*x2
r1 = sin(P)*x0 + cos(P)*x1 + 0*x2
r2 = 0*x0 + 0*x1 + 1*x2
Or as a matrix:
|cos(P) -sin(P) 0| |x0| |r0|
|sin(P) cos(P) 0| * |x1| = |r1|
| 0 0 1| |x2| |r2|
I think you get the pattern now. But what about translations. Well usually you just add the translation to the old vector:
r0 = x0 + t0
r1 = x1 + t1
r2 = x2 + t2
The problem here is, that this does not fit into the pattern we used so far. The translations are not multiplied by any component of x. So how do we include them into matrix-vector multiplication? Well, the trick is to extend the matrix dimension.
|a0 b0 c0 d0| |x0| |r0|
|a1 b1 c1 d1| * |x1| = |r1|
|a2 b2 c2 d2| |x2| |r2|
|a3 b3 c3 d3| |x3| |r3|
So your sum becomes:
r0 = a0*x0 + b0*x1 + c0*x2 + d0*x3
r1 = a1*x0 + b1*x1 + c1*x2 + d1*x3
r2 = a2*x0 + b2*x1 + c2*x2 + d2*x3
r3 = a3*x0 + b3*x1 + c3*x2 + d3*x3
Remember that you always had to set the fourth component of your vector (x3) to 1? Well then you get:
r0 = a0*x0 + b0*x1 + c0*x2 + d0
r1 = a1*x0 + b1*x1 + c1*x2 + d1
r2 = a2*x0 + b2*x1 + c2*x2 + d2
r3 = a3*x0 + b3*x1 + c3*x2 + d3
To make sure the new vector has also a value of 1, the factors a3, b3 and c3 need to be zero:
r0 = a0*x0 + b0*x1 + c0*x2 + d0
r1 = a1*x0 + b1*x1 + c1*x2 + d1
r2 = a2*x0 + b2*x1 + c2*x2 + d2
r3 = 0 *x0 + 0 *x1 + 0 *x2 + d3
So to create a translation marix for
r0 = x0 + t0
r1 = x1 + t1
r2 = x2 + t2
r3 = x3 (= 1)
You set
d0 = t0
d1 = t1
d2 = t2
So you get:
r0 = 1*x0 + 0*x1 + 0*x2 + t0*x3 // REMEMBER x3 = 1 !!!
r1 = 0*x0 + 1*x1 + 0*x2 + t1*x3
r2 = 0*x0 + 0*x1 + 1*x2 + t2*x3
r3 = 0*x0 + 0*x1 + 0*x2 + 1 *x3
Or as a matrix:
|1 0 0 t0| |x0| |r0| // REMEMBER: x3 = 1!!!
|0 1 0 t1| * |x1| = |r1|
|0 0 1 t2| |x2| |r2|
|0 0 0 1 | |x3| |r3|
So that's basically all you need to know and I hope you understand it now. ?
Greetings