您的位置:首页 > 其它

Concatenating Transformations(变换的累加)

2019-08-07 06:27 1316 查看

周一到周五,每天一篇,北京时间早上7点准时更新~

As you have learned, coordinate transforms can be represented by matrices, and transformation of a vector from one space to another involves a simple matrix–vector multiplication operation(坐标的转换可以用矩阵来表示,把一个向量从一个坐标系转换到另外一个坐标系涉及到一个矩阵乘以向量的操作). Multiplying by a sequence of matrices can apply a sequence of transformations. It is not necessary to store the intermediate vectors after each matrix– vector multiplication(如果你使用一堆矩阵对向量进行转换的话,就牵涉到一堆的转换,你不必邀存储向量与这一堆矩阵相乘时每个阶段的向量状态). Rather, it is possible and generally preferable to first multiply together all of the matrices making up a single set of related transformations to produce a single matrix representing the entire transformation sequence(你可以先把所有的矩阵相乘,得到最终矩阵,然后再拿这个最后的结果去与向量相乘). This matrix can then be used to transform vectors directly from the source to the destination coordinate spaces. Remember, order is important(你要记住的是,矩阵相乘的顺序不能随意改变). When writing code with vmath or in GLSL, you should always multiply a matrix by a vector and read the sequence of transformations in reverse order. For example, consider the following code sequence:(在GLSL中,你通常会使用矩阵乘以向量的操作,并且矩阵的相乘顺序与正确的数学逻辑意义上的顺序是反着来的,比如下面的)

vmath::mat4 translation_matrix = vmath::translate(4.0f, 10.0f, -20.0f);vmath::mat4 rotation_matrix = vmath::rotate(45.0f,
vmath::vec3(0.0f, 1.0f,
0.0f));
vmath::vec4 input_vertex = vmath::vec4(...);
vmath::vec4 transformed_vertex = translation_matrix
rotation_matrix
input_vertex;
This code first rotates a model 45° around the y axis (due to rotation_matrix) and then translates it by 4 units in the x axis, 10 units in the y axis, and negative 20 units in the z axis (due to translation_matrix)(上面的代码先绕y轴旋转45度,然后再沿x、y、z方向分别平移了4,10,-20). This places the model in a particular orientation and then moves it into position. Reading the sequence of transformations backward gives the order of operations (rotation, then translation). We could rewrite this code as follows:(请注意矩阵书写时候的顺序,与我们逻辑上的顺序是反的,我们也可以把代码写成下面这样)

vmath::mat4 translation_matrix = vmath::translate(4.0f, 10.0f, -20.0f);
vmath::mat4 rotation_matrix = vmath::rotate(45.0f,
vmath::vec3(0.0f, 1.0f,
0.0f));
vmath::mat4 composite_matrix = translation_matrix rotation_matrix;
vmath::vec4 input_vertex = vmath::vec4(...);
vmath::vec4 transformed_vertex = composite_matrix
input_vertex;
Here, composite_matrix is formed by multiplying the translation matrix by the rotation matrix, forming a composite that represents the rotation followed by the translation(这里,我们先得到了合成后的矩阵,然后我们拿这个合成后的矩阵去乘以向量). This matrix can then be used to transform any number of vertices or other vectors. If you have a lot of vertices to transform, this can greatly speed up your calculation. Each vertex now takes only one matrix–vector multiplication operation rather than two.(如果你的点比较多的时候,这种方式会提高效率,每个向量只需要乘以最后的合成矩阵,而不用依次去乘以两个矩阵) Care must be taken here. It’s too easy to read (or write) the sequence of transformations left-to-right as you would code. If we were to multiply our translation and rotation matrices together in that order, then in the first transform we would move the origin of the model; the rotation operation would then take place around that new origin, potentially sending our model flying off into space!(这一大坨英文的意思就是,这里你需要注意矩阵的相乘顺序,如果你顺序写错了,那就得不到你想要的结果,比如你总想着先旋转再移动, 于是乎代码很容易写成rotation_matrix*translate_matrix)

Quaternions(四元数)

A quaternion is a four-dimensional quantity that is similar in some ways to a complex number(四元数跟复数有点类似,它有一个实部和三个虚部,这个跟肾虚无关,有人就说肾虚也会引发失眠和头疼,所以小伙子们应该保持良好的生活习惯). It has a real part and three imaginary parts (as compared to a complex number’s one imaginary part). Just as a complex number has an imaginary part i, a quaternion has three imaginary parts, i, j, and k. Mathematically, a quaternion q is represented as(如同复数有一个虚部i一样,四元数有三个虚部i、j、k,数学上,四元数q可以写成下面的样子)

The imaginary parts of the quaternion have properties similar to the imaginary part of a complex number. In particular:(四元数的虚部跟复数的虚部有着相似的性质,特别是:)


Also, the product of any two of i, j, and k gives whichever one was not part of that product. Thus:(并且,i、j、k的两两乘积等于除开这俩个参与乘法的第三者,如下:)

Given this, we can see that it is possible to multiply two quaternions together as follows:(有了这些理论之后,四元数的乘法公式如下:)

As with complex numbers, multiplication of quaternions is non-commutative(如同复数一样,四元数的乘法也是不可交换的). Addition and subtraction for quaternions is defined as simple vector addition and subtraction, with the terms being added or subtracted on a component-by-component basis(四元数的加减法就直接用对应元素进行加减操作就可以了). Other functions such as unary negation and magnitude also behave as expected for a four component vector(四元数求反和求长度就跟四维向量一样操作就可以). Although a quaternion is a four-component entity, it is common practice to represent a quaternion as a real scalar part and a three-component imaginary vector part. Such representation is often written(虽然四元数是个四维的数据,但是通常我们使用一个标量和三维虚部的向量表示它,这样的表述通常可以这么来写:)

Okay, great—but this isn’t the dreaded math chapter, right?(OK,屌爆了,可以看到这并不是一个很狗带的数学章节) This is about computer graphics, OpenGL, and all that fun stuff(这是关于图形学、OpenGL和所有那些有趣的玩意,有趣个卵啊,头都快秃了,搞不好写书的就是个秃友亮). Well, here’s where quaternions get really useful. Recall that our rotation functions take an angle and an axis to rotate around(Well,我们来瞅瞅四元数为何有用吧,让我们回想起旋转的那些操作). Well, we can represent those two quantities as a quaternion by stuffing the angle in the real part and the axis in the vector part, yielding a quaternion that represents a rotation around any axis(我们可以使用实部去记录旋转,虚部去记录旋转轴,这样一来一个四元数就可以表达绕任意轴旋转这个概念了). A sequence of rotations can be represented by a series of quaternions multiplied together, producing a single resulting quaternion that encodes the whole lot in one go(四元数的乘法也是可以累加的,你可以把多次旋转让多个四元数相乘之后存到一个结果四元数里). While it’s possible to make a bunch of matrices that represent rotation around the various Cartesian axes and then multiply them all together, that method is susceptible to gimbal lock(使用四元数就很好的解决了在使用旋转矩阵去表达旋转时,会产生万向锁的问题). If you do the same thing with a sequence of quaternions, gimbal lock cannot occur. For your coding pleasure, vmath includes the vmath::quaternion class that implements most of the functionality described here(如果你使用四元数的话,就不会有万向锁的问题,我们的vmath是个好青年,我们这里讲的这些玩意它都实现了)

本日的翻译就到这里,明天见,拜拜~~

第一时间获取最新桥段,请关注东汉书院以及图形之心公众号

东汉书院,等你来玩哦

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: