週一到週五,天天一篇,北京時間早上7點準時更新~app
As noted, coordinates may be moved from space to space by multiplying their vector representations by transformation matrices(如同提到過的那樣,座標能夠經過乘以變換矩陣從一個空間轉換到另外一個空間). Transformations are used to manipulate your model and the particular objects within it(變換主要是用來去計算特定空間中你的模型以及某些特定的物體). These transformations move objects into place, rotate them, and scale them(這些變換把物體移動到某個位置,旋轉他們,縮放他們). Figure 4.8 illustrates three of the most common modeling transformations that you will apply to your objects(圖4.8顯示了三個最多見的你會應用到你物體上的模型變換). Figure 4.8(a) shows translation, in which an object is moved along a given axis(圖4.8a顯示了平移,這裏是把一個物體沿着一個給定的座標軸平移). Figure 4.8(b) shows a rotation, in which an object is rotated about one of the axes(圖4.8b顯示了旋轉,物體繞着某個軸旋轉). Finally, Figure 4.8(c) shows the effects of scaling, where the dimensions of the object are increased or decreased by a specified amount(最後圖4.8c中顯示了縮放物體). Scaling can occur non-uniformly (the various dimensions can be scaled by different amounts), so you can use scaling to stretch and shrink objects(各方向上的縮放能夠不同,這樣一來你就能夠來擠壓物體)
Each of these standard transforms can be represented as a matrix by which you can multiply your vertex coordinates to calculate their positions after the transformation(每個標準變換能夠表示成爲使用一個矩陣乘以你的座標). The following subsections discuss the construction of those matrices, both mathematically and using the functions provided in the vmath library(接下來的章節從數學意義上以及vmath庫的角度討論矩陣的構造)less
The Identity Matrix(單位矩陣)dom
There are a number of important types of transformation matrices you need to be familiar with before we start trying to use them(在你開始使用矩陣以前,你須要先了解一些很是重要的矩陣類型). The first is the identity matrix(第一個就是單位矩陣). As shown below, the identity matrix contains all zeros except a series of ones that traverse the matrix diagonally. The 4 × 4 identity matrix looks like this:(如同下面展現的這樣,單位矩陣是一個對角陣,除了對角線上的元素之外,其餘地方都是0,,4x4的單位矩陣長相如此:)
Multiplying a vertex by the identity matrix is equivalent to multiplying it by 1; it does nothing to it(與單位矩陣相乘,向量不變)ide
Objects drawn using the identity matrix are untransformed; they are at the origin (last column), and the x, y, and z axes are defined to be the same as those in eye coordinates(使用單位矩陣去對物體進行變換,物體不會有什麼變化). Obviously, identity matrices for 2 × 2 matrices, 3 × 3 matrices, and matrices of other dimensions exist and simply have ones in their diagonal(很顯然,二、3和其餘維度的單位矩陣也是存在的,全部的單位矩陣都是方陣,全部單位矩陣都是它本身的轉置矩陣). All identity matrices are square. There are no non-square identity matrices. Any identity matrix is its own transpose. You can make an identity matrix for OpenGL in C++ code like this(你能夠在C++中來這麼定義一個OpenGL中的單位矩陣):函數
// Using a raw array:
GLfloat m1[] = { 1.0f, 0.0f, 0.0f, 0.0f, // X Column
0.0f, 1.0f, 0.0f, 0.0f, // Y Column
0.0f, 0.0f, 1.0f, 0.0f, // Z Column
0.0f, 0.0f, 0.0f, 1.0f }; // W Column
// Or using the vmath::mat4 constructor:
vmath::mat4 m2{ vmath::vec4(1.0f, 0.0f, 0.0f, 0.0f), // X Column
vmath::vec4(0.0f, 1.0f, 0.0f, 0.0f), // Y Column
vmath::vec4(0.0f, 0.0f, 1.0f, 0.0f), // Z Column
vmath::vec4(0.0f, 0.0f, 0.0f, 1.0f) }; // W Column
There are also shortcut functions in the vmath library that construct identity matrices for you. Each matrix class has a static member function that produces an identity matrix of the appropriate dimensions:(下面展現了vmath庫中,vmath提供的生成單位矩陣的接口)動畫
vmath::mat2 m2 = vmath::mat2::identity(); vmath::mat3 m3 = vmath::mat3::identity(); vmath::mat4 m4 = vmath::mat4::identity();
If you recall, the very first vertex shader we used in Chapter 2, 「Our First OpenGL Program,」 was a pass-through shader. It did not transform the vertices at all, but simply passed the hard-coded data on untouched in the default coordinate system with no matrix applied to the vertices at all(回想起咱第2章中的shader,它裏面沒有對頂點進行任何變化,簡單的將數據傳遞給了渲染管線的下一個階段). We could have multiplied all of the vertices by the identity matrix, but that would have been a wasteful and pointless operation(咱們可讓全部點都乘以單位矩陣,但這沒什麼卵用).ui
The Translation Matrix(平移矩陣)this
A translation matrix simply moves the vertices along one or more of the three axes. Figure 4.9 shows, for example, translating a cube up the y axis by ten units(一個平移矩陣會將頂點沿着一個或者多個座標軸移動,圖4.9展現了沿着y軸正方向移動一個立方體10個單位)
The formulation of a 4 × 4 translation matrix is as follows:(平移矩陣的長相以下)
Here, tx, ty, and tz represent the translation in the x, y, and z axes, respectively(這裏,tx、ty、tz表明的是平移的相對距離). Examining the structure of the translation matrix reveals one of the reasons why we need to use four-dimensional homogeneous coordinates to represent positions in 3D graphics(觀察平移矩陣的結構不難發現,爲什麼俺們要使用w份量爲1的齊次座標去表示一個三維座標了). Consider the position vector v, whose w component is 1.0. Multiplying by a translation matrix of the form above yields(乘以一個上面的平移矩陣後,會產生下面這樣的一個玩意)
As you can see, tx, ty, and tz have been added to the components of v, producing translation. Had the w component of v not been 1.0, then using this matrix for translation would have resulted in t x, ty, and tz being scaled by that value, affecting the output of the transformation(如同你看到的,tx、ty、tz已經被加到向量v上去了,產生了平移。若是w不是1的話,那麼這個結果就會不同,tx、ty、tz就被縮放了). In practice, position vectors are almost always encoded using four components with w (the last) being 1.0, whereas direction vectors are encoded either simply using three components, or as four components with w being zero(在實踐中,表達位置的向量一般將w份量設置成1,表達方向的向量要麼是三位向量,要麼w份量是0). Thus, multiplying a four-component direction vector by a translation matrix doesn’t change it at all(也就是說,乘以一個四維的方向向量,不會改變它). The vmath library contains two functions that will construct a 4 × 4 translation matrix for you using either three separate components or a 3D vector(vmath庫包含了使用三個份量或者一個三維向量去構建4x4平移矩陣的API):spa
template
static inline Tmat4 translate(T x, T y, T z) { ... }
template
static inline Tmat4 translate(const vecN& v) { ... }
The Rotation Matrix(旋轉矩陣)翻譯
To rotate an object about one of the three coordinate axes, or indeed any arbitrary vector, you have to devise a rotation matrix(爲了繞着某個軸去旋轉物體,你此時就須要旋轉矩陣). The form of a rotation matrix depends on the axis about which we wish to rotate. To rotate about the x axis, we use(旋轉矩陣的結構因旋轉軸的不一樣而不一樣,下面啊咱們展現了一個繞x軸旋轉的旋轉矩陣的結構)
Here, Rx(θ) represents a rotation around the x axis by an angle of θ. Likewise, to rotate around the y or z axes, we can use(這裏Rx(θ)表示繞x軸旋轉 θ角度,繞y、z軸旋轉以下圖所示)
It is possible to multiply these three matrices together to produce a composite transform matrix and then rotate by a given amount around each of the three axes in a single matrix–vector multiplication operation. The matrix to do this is(你也能夠把這仨個軸向的旋轉矩陣合體成一個,計算方法以下)
Here, sψ, sθ, and sφ indicate the sine of ψ, θ, and φ, respectively, and cψ, cθ, and cφ indicate the cosine of ψ, θ, and φ, respectively. If this seems like a huge chunk of math, don’t worry—again, a couple of vmath functions come to the rescue:(這裏sψ, sθ, sφ表示的是ψ,θ,φ的正弦值,cψ, cθ, cφ表示的是ψ,θ,φ的餘弦值,看起來好多數學公式,頭好大啊,不怕,有vmath)
template
static inline Tmat4 rotate(T angle_x, T angle_y, T_angle_z);
You can also perform a rotation around an arbitrary axis by specifying x, y, and z values for that vector. To see the axis of rotation, you can just draw a line from the origin to the point represented by (x,y,z). The vmath library also includes code to produce this matrix from an angle-axis representation:(你也能夠繞着任意座標軸旋轉,這個座標軸是從原點指向x、y、z的向量,vmath也有這方面的操做API)
template
static inline Tmat4 rotate(T angle, T x, T y, T z);
template
static inline Tmat4 rotate(T angle, const vecN& axis);
These two overloads of the vmath::rotate function produce a rotation matrix representing a rotation of angle degrees round the axis specified by x, y, and z for the first variant, or by the vector v for the second(這倆重載的函數能夠產生一個繞x、y、z軸旋轉angle讀的旋轉矩陣). Here, we perform a rotation around the vector specified by the x, y, and z arguments. The angle of rotation is in the counterclockwise direction measured in degrees and specified by the argument angle(這裏要注意的是angle是按照逆時針方向定義的). In the simplest of cases, the rotation is around only one of the coordinate system’s cardinal axes (x, y, or z)(最簡單的狀況就是,繞着x、y、z中的某一個軸進行旋轉). The following code, for example, creates a rotation matrix that rotates vertices 45° around an arbitrary axis specified by (1,1,1), as illustrated in Figure 4.10(下面的代碼展現了建立一個繞(1,1,1)軸旋轉45度的例子)
vmath::mat4 rotation_matrix = vmath::rotate(45.0, 1.0, 1.0, 1.0);
Notice in this example the use of degrees. This function internally converts degrees to radians because, unlike computers, many programmers prefer to think in terms of degrees(再次強調這裏的單位是角度,底層會把他們轉化成弧度。這裏用角度是由於大部分碼農都習慣用角度去思考人生)
Euler Angles(歐拉角)
Euler angles are a set of three angles that represent orientation in space. Each angle represents a rotation around one of three orthogonal vectors that define our frame (for example, the x, y, and z axes)(歐拉角在空間中使用三個角度來表達旋轉,每個角度表示的是繞某一個定義了某個座標系的座標軸旋轉的角度). As you have read, the order in which matrix transformations are performed is important, as performing some transformations (such as rotations) in different orders will produce different results(使用歐拉角來表達旋轉的時候,旋轉的順序會影響最終結果). This is due to the noncommutative nature of matrix multiplication(這都是由於矩陣的乘法是不可交換的). Thus, given a set of Euler angles, should you rotate first around the x axis, then around y, and then z, or should you perform the rotations in the opposite order, or even do y first? Well, so long as you’re consistent, it doesn’t really matter(所以,給你一組歐拉角,你是x、y、z軸這樣的順序進行旋轉仍是反着來,甚至先y再其餘呢?實際上這並沒什麼影響)
Representation of orientations as a set of three angles has some advantages. For example, this type of representation is fairly intuitive, which is important if you plan to hook the angles up to a user interface(使用歐拉角去表達旋轉仍是有一些優點的,好比它比較直觀). Another benefit is that it’s pretty straightforward to interpolate angles, construct a rotation matrix at each point, and see smooth,consistent motion in your final animation. However, Euler angles also come with a serious pitfall—gimbal lock(另外一個優點就是,是用歐拉角進行插值比較直觀,插出來以後,再構建矩陣,而後作成動畫是那麼的平滑。然而歐拉角也存在不少問題,好比萬向鎖). Gimbal lock occurs when a rotation by one angle reorients one of the axes to be aligned with another of the axes(當歐拉角旋轉座標軸使得它與另外一個座標軸重合的時候,萬向鎖就出現了). Any further rotation around either of the two now-colinear axes will result in the same transformation of the model, removing a degree of freedom from the system. Thus, Euler angles are not suitable for concatenating transforms or accumulating rotations(今後以後,你再也別想繞着這個方向轉動物體了。也就是說,歐拉角不適合作矩陣的累加). To avoid this, our vmath::rotate functions are able to take an angle by which to rotate and an axis about which to rotate(爲了不這一點,因此vmath提供的接口是繞某個軸轉某個角度的這種API,而不是矩陣的方式). Of course, stacking three rotations together— one in each of the x, y, and z axes—allows you to use Euler angles if you must, but it is much preferable to use angle-axis representation for rotations, or to use quaternions to represent transformations and convert them to matrices as needed(使用繞什麼軸旋轉多少度的這種方式其實是更推薦的,或者你也可使用四元數去表達旋轉, 若是你須要矩陣的時候再把他們轉成矩陣就行)
The Scaling Matrix(縮放矩陣)
Our final 「standard」 transformation matrix is a scaling matrix(咱們最後一個標準的變換矩陣就是縮放矩陣了). A scaling transform changes the size of an object by expanding or contracting all the vertices along the three axes by the factors specified. A scaling matrix has the following form(一個縮放變換矩陣會沿着各個座標軸按照各個軸向的縮放因子去改變頂點的位置達到改變物體大小的效果,縮放矩陣的結構以下所示)
Here, sx, sy, and sz represent the scaling factor in the x, y, and z dimensions, respectively. Creating a scaling matrix with the vmath library is similar to the method for creating a translation or rotation matrix. Three functions exist to construct this matrix for you:(這裏sx、sy、sz分別表示x、y、z軸向上的縮放因子,咱們vmath庫也提供了方法去建立縮放矩陣,以下圖所示:)
template
static inline Tmat4 scale(T x, T y, T z) { ... }
template
static inline Tmat4 scale(const Tvec3& v) { ... }
template
static inline Tmat4 scale(T x) { ... }
The first of these scales independently in the x, y, and z axes by the values given in the x, y, and z parameters. The second performs the same function but uses a threecomponent vector rather than three separate parameters to represent the scale factors. The final function scales by the same amount, x, in all three dimensions(第一個傳入的是x、y、z方向上的縮放因子,第二個傳入的是一個向量,向量的x、y、z分別表示縮放因子,第三個建立的縮放矩陣 全部軸向上的縮放因子同樣). Scaling does not have to be uniform, and you can use it to both stretch and squeeze objects alongdifferent directions. (縮放不必定在各個方向上須要保持一致,因此你可使用縮放去擠壓物體,好比一個10x10x10的立方體能夠被以下的方式進行縮放,x、z方向上的縮放因子是2)For example, a 10 × 10 × 10 cube could be scaled by two in the x and z directions as shown in Figure 4.11.
本日的翻譯就到這裏,明天見,拜拜~~
第一時間獲取最新橋段,請關注東漢書院以及圖形之心公衆號
東漢書院,等你來玩哦