The last couple of days have been fairly interesting. I decided to learn about Vectors and the Math behind working with them. Things like what the dot product, unit vectors are and I did a bit of cursory trigonometry. Math has become a lot more fun for me since learning about games and 3d programming. Also I learnt how to embed math equasitions in by blog:
\[ det A = \sum_{j=1}^{n} A_{ij}(-1)^{i+j} det \bar{A}_{ij} \\ \tag{Determinant of A} \\ \]
The interesting thing about learning this stuff is not that I need it to work Direct X, which I do, but more so because it's nice to know what they mean and why it works. I think that's always been by a problem: sometimes I'm more interested in the concept sometimes than actually using it. But I think it does affect a lot of people too - only they don't spend as much time on it as I do I think.
I remember when one of our Australian developers went to town converting all his C++ code to use templates... I think he loved the idea of templates more than perhaps the readability or productivity that the code might afford. All because templating in C++ was interesting. I sympathise.
Anyway, I've also started reading more up on the Software Engineering coursework I have, it actually a lot more interesting than the CPD course, probably because I'm more familiar with it. I'm hoping the CPD becomes more interesting and fun... The thing about the CPD course is that it's all just a bit fluffy, you have to reflect on your past activities and apply theory to it and its all a bit 'mushy'. My last degree was more in-your-face: here is a database, run this python query on it and send the bytes to that file etc. much more measured and hands-on, I guess that's why I like programming and maybe why I apprciate the math I'm learning at the moment.(a bit more than Continous Professional Development!)
I hit the gym yesterday and did quite a long and extended session focusing on my legs and having run in, I decided to run back and boy was that a test of endurance. My plans to be a little more varied in my workout haven't yet come into fruition yet.
I watched the new Aquaman Film which I actually really enjoyed. I thought that perhaps this would be a watered down superhero film because it's not a well-known character but it was good. I quite like the co-star Amber Hurd, she's beautiful. Always helps.
I watched my favourite film, Gladiator last night and I never get used to it - its a great film.
Anyway back to my Direct X studies, whilst reading this new book about direct X 12... I've learned about the fundamental behind Vector arithmetic, basically observing the geometric results of adding, subtracting and multiplying vectors or forces.
I also noticed that the initialization and basic start-up code I learned about in DirectX11 has been replaced with a concept of queues and lists and commands that you send and prioritise graphics instructions to the GPU. This is new.
Some interesting facts are that negating a vector flips its direction, multiplying one, extends or rather scales its magnitude in the same direction and if you add two vectors (or forces) you can see the resulting displacement of an object or just the resultant vector by parallel extending the opposite vectors(I'll look for a good picture soon).
Translation in 3d Graphics terminology merely refers to taking a vector and putting it somewhere else - the direction and magnitude of the vector remain the same. Oh, and of course, a vector is represented geometrically as [x, y, z] and if you use the coordinate system, then you can see which direction this represents.
Some of the interesting things you can do on vectors is determining the vector magnitude using a special formula(which I can't show you right now because I can't get latex to work right on my blog). No wait I can:
\[ ||u|| = \sqrt{x^2 + y^2 + z^2} \\ \tag{eq.1.1 Magnitude of vector} \\ \]
The other is normalising the vector(which creates what is called a unit vector) which can be worked-out by applying a formula which basically just reduces the magnitude of the vector to 1 but the direction is still the same but obviously if you reduce the vector's magnitude, it's x, y, z coordinates will change, and that formula works out the newly adjusted values for them .
The other interesting thing you can do with two vectors is to determine if the angle between two vectors is acute, obtuse or perpendicular. This can be done by getting the scalar product (or the dot product) which is a sort of combination of two Vectors.
The other combination is the cross-product which allows you to determine a new vector which is orthogonal to the two vectors concerned - this is also called the left-hand rule, as the left hand rule also shows you(on your hand) where the orthogonal vector will be when given the direction of the first vector(which you aim your fingers at) and then curl your fingers towards to 2nd vector and then your thumb shows you where the perpendicular vector is. Kinda cool.
The other thing you can do with unit vectors(magnitude is 1) is that you can easily determine the angle between the vectors (but not by using the dot product as that only tells you if the angle will be perpendicular, acute or obtuse) but by using cosine if both vectors are unit vectors. The equation for doing that is
\[ uv = ||u||||v|| \cos \theta \] and ||u|| and ||v|| just mean the magnitude of the vector and as these will both be 1, you can solve for the angle which will be the angle between the two vectors.
My mind started to have a collapse when we started going over orthogonalising vectors which is something I'll have to look into at a later stage but basically its a formula to determine perpendiculars to vectors (like the left-hand rule) but with math. And the other brain-freezer was orthogonal projection, which I'm sure is all easy but I need an alternative perspective before my brain lets these ideas in!
These are the general equasions I learnt about when using vectors:
\[ ||u|| = \sqrt{x^2 + y^2 + z^2} \\ \tag{eq.1.1 Magnitude of vector} \\ \]
\[ \hat{u} = \frac{u}{||u||} = \frac{x}{||u||} + \frac{y}{||u||} + \frac{z}{||u||} \\ \tag{eq 1.2 Unit vector} \\ \]
\[ u \cdot v = u_{x}v_{x} + u_{y}v_{y} + u_{z} + v_{z} \\ \tag{eq 1.3 dot product} \\\]
\[ u \cdot v = cos \theta \rightarrow ||u||||v|| = 1 (unit vectors) \\ \tag{eq 1.4 angle between vectors u and v} \\ \]
\[ w = u \times v = u_yv_z - u_zv_y, u_zv_x -u_xv_z, u_xv_y - y_yv_x \\ \tag{eg 1.5 cross product of two vectors} \\ \]
I also learned about how to store Vectors in C++/DirectX using the SIMD registers that are part of SSE2 using the XMVECTOR Structure to store 4 32-bit floating point numbers which can represent a vector's parts ie [x, y, z] and the 4th float is not used. The other key idea was that use should only use this structure if you're storing these structures globally as this ensures some alignment requirements to be enforced. When this is not the case, Ie you want to store a vector in a class, you should use the XMFLOAT2,3,4 structure to store a Vector as it holds 2,3,4 floating point numbers which can represent your vector.
The cool thing about these structures is that they are 128-bit structures and one SIMD register is 128-bit and you can do one complete SIMD operation using 128bits stored in a SIMD register which is what DirectX does with these structures that you pass in. This is for efficiency purposes. Quite interesting.
A lot of the stuff I learnt was quite interesting because the proofs were solved, not just merely stating the equations but explaining the reasons behind the equations which is the right way to do it in my opinion.
Today I read up on Matrices, which are compact forms in which you can store Vectors or any 3 or 4 valued number(such as triangle vertices!). There are also some interesting things you can do on matrices. Basically, you can add/subtract and combine matrices too. There are generic equations which allow you to do this in a compact way but I was shown how these equations were derived from their geometric interpretations which were fun.
These were the ideas behind :
- Multiplying matrices,
- Vector-matrix multiplication - basically combining a vector with a matrix
\[ uA = xA_{1,*} + yA_{2,*} + zA_{3,*} \\ \tag{vector matrix multimplication} \\ \]
- Transposing of a matrix - swapping a matrices columns with its rows
- The identity matrix - a matrix that when multiplied by a matrix does not change the matrix
- The determinant of a matrix - which is a number which helps determine the inverse of a matrix
\[ det A = \sum_{j=1}^{n} A_{ij}(-1)^{i+j} det \bar{A}_{ij} \\ \tag{Determinant of A} \\ \]
- Matrix Minors - a subset of a matrix which helps find the determinant of the matrix
- Adjoint of a matrix - also helps to find the inverse of a matrix
- The inverse of a matrix - which is used to help find another matrix when all others are provided in an equasion (so thats why its so useful.)
Equations: (TODO)
\[ \left[
\begin{array}{ c c }
1 & 2 \\
3 & 4
\end{array} \right]
\]
Just like with Vectors most of the concepts mentioned above can be automatically calculated using DirectX helper functions (but where is the fun in doing that!) but I'm thankful I know what that math behind it all is. The must say the Author Frank D Luna did a great job of explaining it.
With Matrices, you can use a XMMATRIX instead of a XMVECTOR and again you use this only for global variables of this type. To represent matrices in classes you would represent them as XMFLOAT4x4 which allows the storage of 4x4 Floats, which is the Matrix format most used in Direct X 12
No I'm not sure I'll remember it all, but its probably going to start making sense when we start trying to translate, rotate, scale models that themselves are represented as vertices which are 3-valued structures and thus can be stored singularly as a Vector or an array of them, or indeed an array of Matrices.
Tomorrow I'm going to read up about transformations(translate, rotate, scale) of these structures but first I'll need to figure out how orthogonal projection works - so let me get that out of the way first.