Original address: http://blog.csdn.net/vagrxie/article/details/4960473
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:vector, dimensional, coordinate system, normalization, dot product, cross productDescription
Because the university in the Advanced Mathematics course to learn the linear algebra related content, so learning 3D programming when this paragraph is actually jumping past, learning some content when it is very depressed, (4, 5 years is not used, inevitably forget) finally often rely on the advanced API to complete, But in fact, these high-level API algorithm concrete implementation of what the basic can not understand, so still decided to come back good to understand the basic part, of course, the first is the mathematical part. In order to achieve a better visual effect, but also in the complex matrix operation to verify the results of the operation, will introduce the use of Freemat or Scilab (5.1.1) or GNU Octave (3.2.3), the three software as a substitute for MATLAB to use. Can not use large MATLAB is also a kind of liberation, the default use of Freemat, no time to consider other alternatives. When it comes to computing, try to implement DirectX and Irrlicht two versions, also refer to some source code. (mainly used to see the implementation of the formula in C + +) Basically, I would like to explain the concept of the main, preferably a visual explanation.
Vector
The quantity that can be expressed only by size, such as temperature, quality, etc. Both the size and the direction of the vector, such as displacement, velocity, and so on, must be indicated. In geometry, we use a directed line to represent a vector. There are two variables that can determine a vector, that is, the length of the vector and the direction of the vector. The quantity is independent of position, and two vectors with the same length and direction are equal. In Irrlicht, there are special class Vector2d,vector3d to represent 2-dimensional, 3-dimensional vectors respectively. The structure D3dxvector2,d3dxvector3,d3dxvector4 is used to represent vectors in DirectX.
Left-handedness coordinate
A picture of the preface, do not know how to use the hand twisted to take a look at the figure, understand what is the left hand, what is the right hand coordinate system. In OpenGL, a right-handed coordinate system is used, and a left-handed coordinate system is used in Directx,irrlicht. (Images from the web)
The modulus of a vector
The size (or length) of the vector is called the modulus of the vector, and the modulo of vector A is | | a| |. The following is an example of a 3-dimensional vector (up to 3D):
The function that gets the vector modulus in Irrlicht is the member function of Vector3D
//! Get length of the vector. T GetLength () const {return core::squareroot (x*x + y*y + z*z);} //! Get squared length of the vector./** this was useful because it is much faster than GetLength ()./return squared Length of t He vector. */T getlengthsq () const {return x*x + y*y + z*z;}
It is possible to see the implementation of the formula, where GETLENGTHSQ is used to optimize the code by using the square value directly at some point.
The implementation in DirectX is almost the same, except that the C-style interface does not use C + + classes.
D3dxinline FLOAT d3dxvec3length (CONST D3dxvector3 *pv) {#ifdef d3dx_debug if (!PV) return 0.0f; #endif # Ifdef __cplusplus return sqrtf (pv->x * pv->x + pv->y * pv->y + pv->z * pv->z); #else return (Floa T) sqrt (pv->x * pv->x + pv->y * pv->y + pv->z * pv->z); #endif}d3dxinline FLOAT d3dxvec3lengthsq (CO NST D3dxvector3 *PV) {#ifdef d3dx_debug if (!PV) return 0.0f; #endif return pv->x * pv->x + pv->y * pv- >y + pv->z * PV->Z;}
Freemat:
--A = [1, 1, 1]a = 1 1 1--> b = Norm (a) b = |
Two-point distance in three-dimensional space
Formula:
Implementation of Irrlicht:
//! Get distance from another point./** here, the vector was interpreted as point in 3 dimensional space. */t Getdistancefrom (const vector3d<t>& Other) const{ return vector3d<t> (x-other. X, Y-other. Y, Z-other. Z). GetLength ();} //! Returns squared distance from another point./** here, the vector was interpreted as point in 3 dimensional space. */t getdistancefromsq (const vector3d<t>& Other) const{ return vector3d<t> (x-other. X, Y-other. Y, Z-other. Z). GETLENGTHSQ ();}
There is also the square of the sq function version.
Normalization of vectors
The normalization of vectors is also called (normalized) to make the modulus of the vector change to 1, which becomes the unit vector. Vector normalization can be achieved by dividing the vectors by the modulus of the vector. The normalized vector is equivalent to a vector of units in the same direction as the vectors, which can be used to represent the direction of the vector. Since the concept of direction is very important in 3D programming, this concept is also important, and the unit vectors have many important properties that are used more frequently when representing the normal vectors of an object's surface.
The basic formula:
The calling function in Irrlicht and its implementation:
//! Normalizes the vector./** in case of the 0 vectors the result is still 0, otherwisethe length of the vector would be 1./retu RN Reference to this vector after normalization. */vector3d<t>& normalize () { f64 length = (F32) (x*x + y*y + z*z); if (core::equals (length, 0.0))//This check isn ' t a optimization but prevents getting NAN in the sqrt. return *this; Length = Core::reciprocal_squareroot ((f64) (x*x + y*y + z*z)); x = (T) (x * length); y = (T) (y * length); z = (T) (z * length); return *this;}
The above code first calculates length in case it is 0 and then calculates 1/| directly | u| |, (this is done from the code implementation because the Sse,nviadia has the ability to compute this value directly) and then it is multiplied with each coordinate value separately.
Calling Functions in DirectX: (No implementation available)
d3dxvector3* WINAPI d3dxvec3normalize (D3dxvector3 *pout, CONST D3dxvector3 *PV);
Addition and subtraction of vectors, multiplication of numbers
Too simple, not much description, is nothing more than the corresponding addition, subtraction, multiplication, the geometrical meaning, the addition can be seen as the direction of the combination of two vectors, subtraction can be seen as two vectors of the direction of the difference (even for the tracking algorithm), the multiplication of the vector to scale.
In order to complete, here from the Baidu Encyclopedia copy a piece of information: (The following are 2-dimensional, put to 3-dimensional also almost)
Set a= (x, y),b= (× ', Y ').
1. Addition of vectors
The addition of vectors satisfies the law of parallelogram principle and triangles.
AB+BC=AC.
a+b= (x+x ', Y+y ').
a+0=0+a=A.
Algorithm for vector addition:
Exchange law:a+b=b+A;
Binding law: (a+b) +c=a+ (b+c).
2, subtraction of vectors
If
a、
bare vectors that are opposite to each other, then
a=-
b,
b=-
a,
a+
b=
0.0The reverse amount is
0
AB-AC=CB. That is, "common starting point, pointing to be reduced"
a= (x, y) b= (× ', Y ') then a-b= (x-x ', y-y ').
3, number multiplication vector
Real number λ and vector
aThe product is a vector, which is recorded as λ
a, and ∣λa∣=∣λ∣
·∣a∣.
When λ>0, λa and a are in the same direction;
When λ<0, λa and a reverse direction;
When λ=0, λa=0, the direction is arbitrary.
When a=0 , for any real number λ, there is λa=0.
Note: By definition, if λa=0, then λ=0 or a=0.
The real number λ is called the coefficient of vector a , and the geometric meaning of the multiplier vector, λa , is to extend or compress the directed segment representing Vector a .
When ∣λ∣>1, the directed segment representing Vector A is stretched to the original ∣λ∣ times in the original direction (λ>0) or in the opposite direction (λ<0);
When ∣λ∣<1, the directed segment representing Vector A is shortened to the original ∣λ∣ times in the original direction (λ>0) or the opposite direction (λ<0).
Multiplication of numbers and vectors satisfies the following arithmetic law
Binding law: (λa)・the=λ (a· b)= (a• λb).
Vector-to-number distribution law (first assignment Law): (λ+μ)a=λa+μa.
Number for the distribution law of vectors (second distributive law): λ (a+b) =λa+λB.
Elimination law of the multiplication vector: ① If the real number λ≠0 and λa=λb, then a=b. ② if a≠0 and λa=μa, then λ=μ.
Point product (dot product) also known as quantity product or inner product
V0. V1 = v0.x*v1.x+v0.y*v1.y+v0.z*v1.z;
So the dot product result of a vector is a number, not a vector.
The dot product equals the length of the vector v0 multiplied by the length of the V1, multiplied by the cosine of the angle between them, the |v0|*|v1|*cos (θ).
By dot product, you can calculate the angle between two vectors.
cos (θ) =v0.v1/|v0| | v1|;
Θ=math.acos (v0.v1/|v0| | v1|);
If all two vectors are unit vectors, the above formula can be simplified to
Θ=math.acos (V0.V1);
v0.v1=0 = "Two vectors perpendicular to one another
v0.v1>0 = "Two vectors with an angle of less than 90 degrees
v0.v1<0 = "Two vectors with an angle greater than 90 degrees
Implementation in Irrlicht: (very simple formula, very straightforward implementation)
//! Get the dot product with another vector. T dotProduct (const vector3d<t>& Other) const{ return x*other. X + y*other. Y + z*other. Z;}
Implementation in DirectX: (Very simple formula, also very straightforward implementation)
D3dxinline FLOAT D3dxvec3dot (const D3DXVECTOR3 *PV1, const D3DXVECTOR3 *pv2) {#ifdef d3dx_debug if (!pv1 | |!pv2) return 0.0f; #endif return pv1->x * pv2->x + pv1->y * pv2->y + pv1->z * PV2->Z;}
Cross product: Also called vector product
The result of the cross product is a vector, which is perpendicular to the two vectors that are multiplied.
Formula:
Note: The cross product does not satisfy the commutative law, which in turn multiplies the resulting vector in the opposite direction of the original vector.
The left-handed coordinate system can determine the direction of the vector returned by the cross product by the law of the left hand, bending the left hand from the first vector to the second vector, which is the direction of the vector that the thumb refers to. The right-hand coordinate system can be used to determine the direction of the vector returned by the cross product by the right-hand rule, bending the right hand from the first vector to the second vector, which is the direction in which the thumb refers to the vector being obtained. Thus, in fact, the vector obtained by the cross product is always perpendicular to the plane where the original two vectors reside.
If the two vectors are in the same or opposite direction, the cross product result will be a 0 vector. (ie a//b)
An important application of fork multiplication is to find the normal vector of triangles.
Implementation of Irrlicht:
//! Calculates the cross product with another vector./**/param p vector to multiply with./return crossproduct of this vector With P. */vector3d<t> crossproduct (const vector3d<t>& p) const{ return vector3d<t> (Y * p.z-z * P.Y, Z * p.x-x * p.z, X * p.y-y * p.x);}
Implementation of DirectX:
D3dxinline d3dxvector3* d3dxvec3cross (D3dxvector3 *pout, const D3DXVECTOR3 *PV1, const D3DXVECTOR3 *pV2) { D3DX VECTOR3 v; #ifdef d3dx_debug if (!pout | |!pv1 | |!pv2) return NULL; #endif v.x = pv1->y * Pv2->z-pv1-> ; Z * pv2->y; V.Y = pv1->z * pv2->x-pv1->x * pv2->z; v.z = pv1->x * Pv2->y-pv1->y * pv2->x; *pout = V; return pOut;}
Basically, that's the formula.
As a last-minute concept, practice this code here.
The cross product of A= (2,2,1) and b= (4,5,3) are obtained.
Freemat:
--A = [2,2,1]a = 2 2 1--> b = [4,5,3]b = 4 5 3--> c = Cross (b) c = 1-2 |
Irrlicht:
#include <stdio.h> #include <irrlicht.h>using namespace irr::core;int _tmain (int argc, _tchar* argv[]) { VECTOR3DF A (2.0f, 2.0f, 1.0f); VECTOR3DF B (4.0f, 5.0f, 3.0f); VECTOR3DF C = a.crossproduct (b); printf ("C = (%f,%f,%f)", c.x, C.y, c.z); return 0;}
Output:
c = (1.000000,-2.000000, 2.000000)
DirectX:
#include <stdio.h> #include <d3dx9.h>int _tmain (int argc, _tchar* argv[]) { D3dxvector3 A (2.0f, 2.0f, 1.0f); D3dxvector3 B (4.0f, 5.0f, 3.0f); D3dxvector3 C; D3dxvec3cross (&c, &a, &b); printf ("C = (%f,%f,%f)", c.x, C.y, c.z); return 0;}
Output:
c = (1.000000,-2.000000, 2.000000)
Here is a more complete example is to hope that you understand Irrlicht this C + + style interface and DirectX C-style interface using the difference, here is not two styles of interface to put forward more comments, in case of a war of words.
Calculation of the next predicted matrix
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
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 (1) vectors and their operations