Coordinate Transformations(坐标系的变换)
作者:互联网
周一到周五,每天一篇,北京时间早上7点准时更新~
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库的角度讨论矩阵的构造)
The Identity Matrix(单位矩阵)
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(与单位矩阵相乘,向量不变)
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(很显然,2、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(我们可以让所有点都乘以单位矩阵,但这没什么卵用).
The Translation Matrix(平移矩阵)
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):
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.
本日的翻译就到这里,明天见,拜拜~~
第一时间获取最新桥段,请关注东汉书院以及图形之心公众号
东汉书院,等你来玩哦
标签:matrix,缩放,0.0,矩阵,坐标系,Coordinate,rotation,vmath,Transformations 来源: https://blog.51cto.com/battlefire/2426910