Original address: http://blog.csdn.net/vagrxie/article/details/4974985
Copyright NOTICE: This work is created by nine days Goose Ling, using the Creative Commons Attribution-NonCommercial Use 4.0 International License Agreement license. Http://www.jtianling.com
Directory (?) [+]
Write by nine days Goose Feather (jtianling)--Blog.csdn.net/vagrxie
Discussion of newsgroups and documents
Technorati Tags:3d,matrix,irrlich,d3d,directx,mathThe concept of matrices (matrix)
The number of rows of M-N columns ordered by M * is called a matrix of n columns of m rows, usually in uppercase notation. All zeros are called 0 matrices.
The following is a 4x3 matrix:
The first row, column J , or i,j bit of a matrix A, usually written as a[ I,j] or Ai,j. In the example above, A[2,3]=7. (from Wikipedia)
When a matrix contains only single rows or columns, such matrices are called row vectors or column vectors. (Refer to the previous article, "Mathematical basis for 3D programming (1) vectors and their operations")
GNU Octave (MATLAB):
A = 2 3 5 8 9 7 6- 4 14 1 |
The above is a 4*4 matrix generated with the GNU Octave (MATLAB).
In fact, in Irrlicht and DirectX, there are only 4*4 matrices, the reason for later, in the Irrlicht matrix is represented by the template class CMatrix4, and there are
typedef CMatrix4 matrix4;
The matrix in DirectX is represented by D3dxmatrix and is much more functionally designed than the matrix in D3D.
In DirectX, this structure inherits from the following structure.
typedef struct _D3DMATRIX {
Union {
struct {
Float _11, _12, _13, _14;
Float _21, _22, _23, _24;
Float _31, _32, _33, _34;
Float _41, _42, _43, _44;
};
float m[4][4];
};
} D3dmatrix;
That is, a two-dimensional array of m[4][4] in DirectX to represent the 4*4 matrix. Unlike Irrlicht, it is expressed in Irrlicht with T-m[16]; But the use is roughly the same, because all overloaded with the () operator, you can take a (I, j) way to get the first row of matrix A, the value of column J.
For example, we have a matrix like the one below.
The code for construction and traversal in D3D is as follows:
#include #include int _tmain (int argc, _tchar* argv[]) { d3dxmatrix A (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { printf ("%.2f/t", A (i, J)); } printf ("/n"); } return 0;}
Results:
1.00 2.00 3.00 4.005.00 6.00 7.00 8.009.00 10.00 11.00 12.0013.00 14.00 15.00 16.00 |
In Irrlicht
#include #include using namespace irr::core;int _tmain (int argc, _tchar* argv[]) { matrix4 A; Float M[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; A.setm (m); for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { printf ("%.2f/t", A (i, J)); } printf ("/n"); } return 0;}
The output is the same.
Row-First and column-first (readings, not mathematical, only related to the physical mode of the computer storage matrix)
In D3D and Irrlicht, the sequential output matrix iterates through the rows and then iterates through the columns, which is called the row first or the row main order (Row-major order), which is specifically presented here because in fact there is a way of storing the columns first and then traversing the rows, called column precedence or column main order ( Column-major order). Give us a reference (Wikipedia's Row-major_order)
Traversal in D3D: (needs to be strongly turned into a float array and then traversed)
for (int i = 0; i < ++i) { printf ("%.2f/t", ((float*) A) [i]);}
Traversal in the Irrlicht:
for (int i = 0; i < ++i) { printf ("%.2f/t", A[i]);}
If we all use the priority of storage, then I do not have to spend a lot of words on the list of priorities, in fact, OpenGL is the use of column-First storage, hehe, it seems that OpenGL is born contrary to the world, coordinate system d3d,irrlicht with the right-hand coordinate system, OpenGL has to use the left-handed coordinate system, D3d,irrlicht with the row-First storage matrix, OpenGL will be the column-First storage matrix .... In Changsha dialect, this is called Tease PA ... (Of course, historically, this world should be the opposite of OpenGL)
In OpenGL, there is no design structure for the matrix, only the array representation (and also the underlying and original OpenGL), and if you use glloadmatrix* to load a matrix, this matrix should be arranged like this:
It's depressing ....
Matrix plus minus, multiply
Similar to vectors, there is not much to describe here. That is, the simple plus and minus multiplication of the corresponding element. The concept is very simple, not much to describe. Look at the actual operation.
GNU Octave (MATLAB):
> B = A + AB = 4 6- Ten - 8 2octave-3.2.3.exe:7:d:> C = B-ac = 2 3 5 8 9 7 6 4 1octave-3.2.3.exe:8:d:> d = A * 2D = 4 6 - 8- 2-Ten |
You can see that C = A and D = B = a + a = C * 2, the calculation of the corresponding element is very simple. In fact, the matrix classes in D3d,irrlicht have already overloaded the relevant operators, which can be used directly.
Transpose of the matrix (transpose)
The transpose of the matrix can be achieved by exchanging the rows and columns of the matrix. So, the transpose of a m*n matrix is a n*m matrix. We use to represent the transpose of the matrix M.
Set A to the MXN order matrix (i.e. m row n column), the element of row J of line I is a_ij, i.e.: a= (A_IJ)
Visually, all elements of a are rotated around a 45-degree ray of the lower right, starting from the 1th column of line 1th, as a mirror inversion, which results in a transpose. A matrix M, turns its first row into the first column, the second row becomes the second column, ..., the last row becomes the bottom column, and a new matrix n is obtained. This process is called a transpose of the matrix.
Basic properties
(The following t are superscript)
(A±B) T=at±bt
(AXB) t= Btxat
(at) T=a
In GNU Octave (MATLAB), there are ready-made transpose functions:
> AA = 1 2 3 4octave-3.2.3.exe> transpose (A) ans = 1 2 3 4 |
It also shows the most common use of transpose, converting the line vector to the column vector. Let's look at a matrix example.
> EE = 1 2 3 4 5 6 7 8 9 ten 14 16octave-3.2.3.exe:67:> Transpose (E) ans = 1 5 9 2 6 10 3 7 4 8 16 |
The counting growth line of E is exchanged, assuming that the index of the acquiring element is consistent with the above count, in fact it is equivalent to converting the row priority into a column priority, which is also a use of the actual relay.
For example, using column precedence in OpenGL, but what if we have a row-first data? It can be loaded by loading the transpose matrix, which means
The glloadtransposematrix* function.
Transpose is implemented in D3D by the function D3dxmatrixtranspose.
The code to implement the transpose in Irrlicht is as follows:
Returns transposed matrix template <class t> inline cmatrix4<t> cmatrix4<t>:: gettransposed () const { cmatrix4<t> T (em4const_nothing); gettransposed (t); return t; } Returns transposed matrix template <class t> inline void cmatrix4<t>::gettransposed (CMatrix4 <T>& o) const { o[0] = m[0]; o[1] = m[4]; o[2] = m[8]; o[3] = m[12]; o[4] = m[1]; o[5] = m[5]; o[6] = m[9]; o[7] = m[13]; o[8] = m[2]; o[9] = m[6]; O[10] = m[10]; O[11] = m[14]; O[12] = m[3]; O[13] = m[7]; O[14] = m[11]; O[15] = m[15]; #if defined (use_matrix_test) O.definitelyidentitymatrix=definitelyidentitymatrix; #endif }
It should be easy to understand because the transpose itself is simple.
Matrix multiplication
Matrix multiplication is referred to 1 as the most important operation in 3D graphics, not one of them.
It is defined only if the number of columns (column) of the first matrix is the same as the number of rows (row) of the second matrix. If a is the mxn matrix andB is the nxp Matrix, then their product AB will be an MXP matrix. The elements of the product matrix are derived as follows:
Matrix multiplication does not conform to the interchange rate, so the AB is referred to as matrix A right multiply B, or B to the left by a.
In fact, the above-mentioned algebraic equations, have been some explanations are very difficult to understand, such as "Wikipedia matrix multiplication" on the explanation, said a half-day, but I quickly around dizzy. I've seen the most understandable explanation from the reference 1,ab. The value of the IJ element is equal to the dot product of the I-line vector of A and the J-column vector of B. The concept of dot product refers to the knowledge of a vector, because it uses a higher-level noun (more abstract), so better understanding, than teaching you how to spell, how to remember the formula is better.
To put it simply:
Set the function DOTP first to calculate the dot product between the row vector A and the column vector b.
function ret = DOTP (A, B)
ret = SUM (A. * Transpose (B))
End
Endfunction
Verify the functions we wrote ourselves:
> AA = 1 2 3 4octave-3.2.3.exe> BB = 1 5 9 13octave-3.2.3.exe> DOTP (A, B) ret = 90ans = 90 |
In this case, the matrix multiplication function of two vectors is implemented with the definition of dot product, as follows:
function ret = Mul (A, B)
For i = 1:length (A)
for j = 1:length (B)
RET (I,J) = DOTP (A (I,1:length (a)), B (1:length (B), J))
End
End
Endfunction
Also verify that:
E = 1 2 3 4 5 6 7 8 9 16octave-3.2.3.exe:72:d:/oc> FF = 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4octave-3.2.3.exe:73:d:/oc> mul (e,f) octave-3.2.3.exe:74:d:/oc> M = Mul (E, F) octave-3.2.3.exe:75:d:/oc> MM = 110. 150octave-3.2.3.exe:76:d:/oc> E * Fans = 30 the 150 in the same. 150 |
Here, we use our high-level abstraction to implement the Mul function, and through validation, personal feeling, such a definition is more easy to remember, a matter of opinion, and when opinion it.
Otherwise, you would like to remember the formula is OK ..... See Irrlicht matrix multiplication implementation: (in addition to the number of multiplication, not involved in other concepts, one to go to the next, see dizziness not faint.) )
//! Multiply by another matrix//set this matrix to the product of each of the other matrices//goal are to reduce stack use an D copy template <class t> inline cmatrix4<t>& cmatrix4<t>::setbyproduct_nocheck (const CMATRIX4 <T>& other_a,const cmatrix4<t>& other_b) {const T *M1 = OTHER_A.M; Const T *M2 = OTHER_B.M; M[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3]; M[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3]; M[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3]; M[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3]; M[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7]; M[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7]; M[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7]; M[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7]; M[8] = M1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11]; M[9] = M1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11]; M[10] = M1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11]; M[11] = M1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11]; M[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15]; M[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15]; M[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15]; M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15]; #if defined (use_matrix_test) definitelyident Itymatrix=false; #endif return *this; }
Square
A matrix with the same number of rows and columns is called a phalanx. For example, the above 4*4 matrix is actually a square (just as the rectangle is long, the width can be different, the square side length is the same), and, the square of the number of rows (number of columns) is called its order, the above 4*4 matrix can be called 4-order Phalanx, is also the most used in 3D graphics programming matrix.
Unit matrix
The element on the main diagonal is 1, and the other element is the square of 0, called the unit matrix. (Identity matrix) is generally expressed in I, the unit matrix in the matrix algorithm equivalent to 1 of ordinary mathematical operations.
A unit matrix is multiplied by a matrix and does not change the matrix.
In GNU Octave (MATLAB), there are also ready-made functions to get the unit matrix:
> Eye (4) ans =diagonal Matrix 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 |
In Irrlicht, it is simpler to get the unit matrix, and the default MATRIX4 class is the unit matrix.
In D3D, pass the function:
D3dxinline d3dxmatrix* d3dxmatrixidentity
(D3dxmatrix *pout)
Get
Inverse matrix
SetAis one of several fields.N If there is another one in the same number field NOrder MatrixB, making:Ab=ba=i,then we callBis aAthe inverse of the matrix, andAis called the invertible matrix, the invertible matrix is also called the non-singular matrix, the non-singular matrix, the full rank matrix.
1. The invertible matrix must be a phalanx
2. An inverse matrix of a reversible matrix is unique
3. The product of two invertible matrices is still reversible
4. The transpose matrix of the reversible matrix is also reversible
Orthogonal matrix (no concept-_-! in my math book)
The N-order matrix M is called an orthogonal matrix if: Mx=i (defines the transpose matrix for matrix M). )
The following conditions are equivalent:
1) M is an orthogonal matrix
2) mx= I is the unit matrix
3)
is an orthogonal matrix
4) Each line of M is a unit vector and 22 orthogonal
5) The columns of M are unit vectors and 22 orthogonal
6) (Mx,my) = (x, y) x,y∈r
Resources:
1. "DirectX 9.0 3D Game Development Programming Fundamentals", (United States) Frank D.luna, Deffi, Tsinghua University Press
2. University of Mathematics, College of Mathematics and Econometrics, Hunan University, uncorrupted set, higher education press
3. Baidu Encyclopedia and Wikipedia
In fact, these concepts are not difficult, the basic concept of the linear algebra course in the university, I just want to combine the GNU Octave (MATLAB) and D3d,irrlicht together to review it, the next is expected to explain the matrix transformation, should also be the last article.
Original article author retention copyright reprint please indicate the original author and give the link
Write by nine days Goose Feather (jtianling)--Blog.csdn.net/vagrxie
(reprint) Mathematical basis for 3D graphics programming (2) matrix and its operation