您的位置:首页 > 运维架构

Common Vector Operators(常见的向量操作)

2019-07-31 06:09 1731 查看

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

Vectors behave as you would expect for operations such as addition, subtraction, unary negation, and so on(向量们经常需要进行加减乘除这样的操作). These operators perform a per-component calculation and result in a vector of the same size as their inputs(这些操作得到的结果依然是一个同样维度的向量). The vmath vector classes override the addition, subtraction, and unary negation operators, along with several others, to provide such functionality. This allows you to use code such as(我写的这个vmath是个好青年啊,它里面封装了这些操作,你可以像下面这些代码一样进行向量的数学运算,别忘了关注我的推特儿哦)

vmath::vec3 a(1.0f, 2.0f, 3.0f);
vmath::vec3 b(4.0f, 5.0f, 6.0f);
vmath::vec3 c;
c = a + b;
c = a - b;
c += b;
c = -c;

However, there are many more operations on vectors that are explained from a mathematical perspective in the following subsections(然而,数学意义上,接下来的这部分内容将会讲述更多的向量操作). They also have implementations in the vmath library, which will be outlined here(同样我写的vmath库已经把下面写的这些全部都实现了)

Dot Product(点积)

Vectors can be added, subtracted, and scaled by simply adding, subtracting, or scaling their individual xyz components(向量可以分别对xyz分量进行加减乘数或者缩放). An interesting and useful operation that can be applied only to two vectors, however, is called the dot product, which is also sometimes known as the inner product(这其中一个非常有用的只能发生在向量之间的操作叫点积,人们也管它叫内积). The dot product between two (three-component) vectors returns a scalar (just one value) that is the cosine of the angle between the two vectors scaled by the product of their lengths(俩向量的点积得到的是一个标量,这个标量又等于这俩向量的长度相乘后再乘以俩向量的夹角的余弦值). If the two vectors are of unit length, the value returned falls between −1.0 and 1.0 and is equal to the cosine of the angle between them(如果这俩向量是单位向量,那么点积就等于这俩向量夹角的余弦值了). Of course, to get the actual angle between the vectors, you’d need to take the inverse cosine (or arccosine) of this value(当然,为了获得那个角度的大小,你需要通过余弦值求arc余弦值). The dot product is used extensively during lighting calculations and is taken between a surface normal vector and a vector pointing toward a light source in diffuse lighting calculations(点积在光照计算的时候经常会用到,在漫反射中参与运算的向量是法线和一个指向光源的向量). We will delve deeper into this type of shader code in the “Lighting Models” section in Chapter 13(我们将会在Ligting Models这个章节里来深入了解一下这个shader的玩法). Figure 4.2 shows two vectors, V1 and V2, and how the angle between them is represented by θ(图4.2展示了两个向量v1和v2,以及他们之间的夹角θ)

Mathematically, the dot product of two vectors V1 and V2 is calculated as(数学上,点积的计算公式如下)

V1 × V2 = V1.x × V2.x + V1.y × V2.y + V1.z × V2.z

The vmath library has some useful functions that use the dot product operation(vmath库有很多使用了点积的函数). For starters, you can actually get the dot product itself between two vectors with the function vmath::dot, or with the dot member function of the vector classes(对于新司机来说,你可以使用vmath::dot或者是向量的成员函数来计算点积)

vmath::vec3 a(...);
vmath::vec3 b(...);
float c = a.dot(b);
float d = dot(a, b);

As we mentioned, the dot product between a pair of unit vectors is a value (between−1.0 and +1.0) that represents the cosine of the angle between them. (就如同我们提到的,两个单位向量的点积是这俩向量夹角的余弦值) A slightly higher level function, vmath::angle, actually returns this angle in radians(另一个更高端的接口vmath::angle计算的则是两个向量之间夹角的大小,单位是弧度)

float angle(const vmath::vec3& u, const vmath::vec3& v);
Cross Product(叉积)

Another useful mathematical operation between two vectors is the cross product, which is also sometimes known as the vector product(另一个比较有用的操作是叉积). The cross product between two vectors is a third vector that is perpendicular to the plane in which the first two vectors lie(俩向量叉积会产生一个垂直于这俩向量所在平面的向量). The cross product of two vectors V1 and V2 is defined as(两个向量叉积的定义如下:)

V1 × V2 = ||V1|| ||V2|| sin(θ)n

where n is the unit vector that is perpendicular to both V1 and V2(其中n是垂直于v1和v2的单位向量). This means that if you normalize the result of a cross product, you get the normal to the plane(意思就是说如果你单位化这个叉积的结果向量,你就会得到垂直于一个平面的法线). If V1 and V2 are both unit length, and are known to be perpendicular to each other, then you don’t even need to normalize the result, as it will also be unit length(如果v1和v2都是单位向量且互相垂直,那么你不需要进行单位化了,因为你得到的结果就是一个单位向量). Figure 4.3 shows two vectors, V1 and V2, and their cross product V3(图4.3展示了v1和v2以及他们的叉积v3)

The cross product of two three-dimensional vectors V1 and V2 can be calculated as(三维向量v1、v2的叉积可以使用如下公式)

Again, the vmath library has functions that take the cross product of two vectors and return the resulting vector: one member function of the three-component vector classes and one global function.(同样滴,vmath库有这样的一个计算向量叉积的全局函数和向量的成员函数,使用方式如下)

vec3 a(...);
vec3 b(...);
vec3 c = a.cross(b);
vec3 d = cross(a, b);

Unlike in the dot product, the order of the vectors in the cross product is important(与点积相比,谁叉了谁这个顺序是不能随意变动的). In Figure 4.3, V3 is the result of V2 cross V1(图4.3显示的都是v2叉了v1的结果v3). If you were to reverse the order of V1 and V2, the resulting vector V3 would point in the opposite direction(如果你用v1去叉v2,那么v3的方向则会反过来). Applications of the cross product are numerous, from finding surface normals of triangles to constructing transformation matrices(使用叉积的情况还是很多的,从计算法线到构建坐标系)

Length of a Vector(向量的长度)

As we have already discussed, vectors have a direction and a magnitude(我们已经提到过,向量有方向和长度). The magnitude of a vector is also known as its length. The magnitude of a three-dimensional vector can be found by using the following equation(计算向量长度的公式如下):

This can be generalized as the square root of the sum of the squares of the components of the vector(这个就是对向量各个部分求平方,然后加起来之后,开平方). In only two dimensions, this is simply Pythagoras’s theorem: The square of the hypotenuse is equal to the sum of the squares of the other two sides(当向量是二维向量的时候,就是说,四边形的斜边的平方等于其他两条边的平方的和). This extends to any number of dimensions, and the vmath library includes functions to calculate this for you.(这个可以扩展到任意维度,我们vmath库就已经包含了这部分内容了)

template
static inline T length(const vecN& v) { ... }

Reflection and Refraction(反射和折射)

Common operations in computer graphics are calculating reflection and refraction vectors(另外还有一部分的常用的操作就是反射和折射向量了). Given an incoming vector Rin and a normal to a surface N, we wish to know the direction in which Rin will be reflected (Rreflect), and given a particular index of refraction η, the direction in which Rin will be refracted(给出一个入射光线和物体表面的法线,我们就可以求出反射光线,在进一步,给出表面折射率的时候,俺们还能求出折射光线). We show this in Figure 4.4,with the refracted vectors for various values of η shown as Rrefract,η1 through(图4.4展示了两个不同折射率的时候,折射光线的情况)

Although Figure 4.4 shows the system in only two dimensions, we are interested in computing this in three dimensions (this is a 3D graphics book, after all). The math for calculating Rreflect is(图4.4展示的是一个二维的,我们实际上对三维的更感兴趣,三维的反射计算方式如下:)

The math for calculating Rrefract for a given value of η is(三维向量的折射计算公式如下:)

To get the desired result, both R and N must be unit-length vectors (i.e., they should be normalized before use)(为鸟得到期望的结果,R和N必须是单位向量). The two vmath functions, reflect() and refract(), implement these equations(vmath库中的reflect和refract函数实现了刚才的这些公式)

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

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

东汉书院,等你来玩哦

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