【数学】向量的四则运算、点积、叉积、正交基

除了正常的加减乘除以外,向量的最常见的三个运算是点积、叉积、正交基。

对于向量的乘法和除法要做一下说明,因为除发的效率要远低于乘法,因此会将除法尽可能的化为乘法来实现。比如我们要对向量缩放一半,则可以除以2,也可以乘以0.5,则尽量要以乘以0.5来实行。

【向量定义】

对于n维向量来说,有n个相互垂直的正交基 {{v_1,v_2,v_3...v_n}},那么一个独立的n维标量集{s_1,s_2,s_3,s_4...s_n}和此正交基存在一个线性组合v=s_1v_1+s_2v_2+s_3v_3+...s_nv_n,则v(s_1,s_2,s_3...s_n)就是一个n维向量。

这里面有一点要注意,只要有正交基,则可以在基上定义向量。比如经常的局部坐标系就是要求其正交基在其上定义局部坐标,比如这篇文章就求了相机坐标的局部坐标系的正交基:【OptiX】第1个示例 光线生成模块(RayGenerationProgram), 相机操作、添加三角网以及相交丢失模块(Miss Program)

【向量的加减法】

在求解颜色时,我们经常使用到加法,比如漫反射的结果再加上镜面反射的结果是最终的结果等等。这里要理解的一点是当代表颜色时,加法代表两个颜色叠加。比如R(1.0, 0.0, 0.0)+G(1.0, 0.0, 0.0)+B(1.0, 0.0, 0.0)=W(1.0, 1.0, 1.0),结果就是颜色混合的白色。

向量的加法从几何上代表两个向量所围成的平行四边形的对角线:

【数学】向量的四则运算、点积、叉积、正交基_第1张图片

向量的减法代表另一条对角线(v_1-v_2)时,v_1叫做被减向量,v_2叫做减向量,记v_1-v_2方向的一个口决是:指向被减向量

【数学】向量的四则运算、点积、叉积、正交基_第2张图片

【向量的点积】

向量点积的定义,拿三维向量来说:

v\cdot w=v_x\cdot w_x+v_y\cdot w_y+v_z\cdot w_z

这里要注意向量的点积结果是一个数值,而非一个向量。

下面来推导点积的最重要的几何意义公式v\cdot w=\left | v \right |\left | w \right |cos\theta其中\theta是两个向量之间的夹角。当vw都是单位向量时,v\cdot w=cos\theta 这是图形学界使用频率最高的公式之一。仅对二三维有效。

下面来进行推导:

\vec{a_1}=(x_1,y_1,z_1), \vec{b_1}=(x_2,y_2,z_2),它们的终点分别为A=(x_1,y_1,z_1), B=(x_2,y_2,z_2),\overrightarrow{AB}=(x_2-x_1,y_2-y_1,z_2-z_1)

那么,在三角形OAB中,使用余弦定理:

\left | AB \right |^2=\left | a_1 \right |^2+\left | b_1 \right |^2-\left | a_1 \right |\left | b_1 \right |cos\theta 其中\thetaa_1b_1的夹角。

将A,B,\overrightarrow{AB}的值代入后,整理即得\vec{a}\cdot \vec{b}=x_1\cdot x_2+y_1\cdot y_2 +z_1\cdot z_2=\left | \vec{a} \right |\left | \vec{b} \right |cos\theta

【向量的叉积】

先看叉积的性质。两个向量的叉积的结果是垂直于这两个向量\vec{a}\vec{b}的第三个向量\vec{a}\times \vec{b},它的方向使用右手螺旋定则,长度则为\vec{a}\vec{b}所围的平行四边形的面积。

【数学】向量的四则运算、点积、叉积、正交基_第3张图片

\left |\vec{a}\times \vec{b} \right |=\left | \vec{a} \right |\left | \vec{b} \right |sin\theta,其中\theta\vec{a}\vec{b}的夹角。

叉乘满足的基本性质如下:

  1. \left |\vec{a}\times \vec{a} \right |=\left | \vec{a} \right |\left | \vec{a} \right |sin\theta=0,自己与自己的夹角\theta=0,则sin\theta=0,所夹的平行四边形的面积也是0。
  2. \left |\vec{a}\times \vec{b} \right |=-\left |\vec{b}\times \vec{a} \right |
  3. (\vec{a}+\vec{b})\times \vec{c}=\vec{a}\times \vec{c}+\vec{b}\times \vec{c}

再看叉乘在数值计算上的定义:

u\times w=(u_1\vec{i}+u_2\vec{j}+u_3\vec{k})\times (v_1\vec{i}+v_2\vec{j}+v_3\vec{k})=u_1v_1\vec{i}\times\vec{i}+u_1v_2\vec{i}\times\vec{j}+u_1v_3\vec{i}\times\vec{k}

+u_2v_1\vec{j}\times\vec{i}+u_2v_2\vec{j}\times\vec{j}+u_2v_3\vec{j}\times\vec{k}

+u_3v_1\vec{k}\times\vec{i}+u_3v_2\vec{k}\times\vec{j}+u_3v_3\vec{k}\times\vec{k} (展开式一)

先讨论正交基\vec{i}\vec{j}\vec{k}的运算法则:

\vec{i}\times\vec{i}=\vec{j}\times\vec{j}=\vec{k}\times\vec{k}=0

\left\{\begin{matrix} \vec{i}\times\vec{j}=\vec{k}& \vec{j}\times\vec{i}=-\vec{k}\\ \vec{j}\times\vec{k}=\vec{i}& \vec{k}\times\vec{j}=-\vec{i}\\ \vec{k}\times\vec{i}=\vec{j}& \vec{i}\times\vec{k}=-\vec{j}\\ \end{matrix}\right.

再代入到(展开式一)

u\times w=(u_1v_2-u_2v_1)\vec{k}+(u_2v_3-u_3v_2)\vec{i}+(u_3v_1-u_1v_3)\vec{j}

=\begin{bmatrix} u_2 & u_3\\ v_2 & v_3 \end{bmatrix}\vec{i}- \begin{bmatrix} u_1 & u_3\\ v_1 & v_3 \end{bmatrix}\vec{j}+ \begin{bmatrix} u_1 & u_2\\ v_1 & v_2 \end{bmatrix}\vec{k}

=\begin{bmatrix} \vec{i} & \vec{j} &\vec{k} \\ u_1 & u_2 & u_3 \\ v_1 & v_2 & v_3 \end{bmatrix}

【计算正交基】

向量的经常的一个操作是构造正交基,根据一个向量,构建正交基,往往需要用到叉乘。在给定的单位向量\vec{a}=(x,y,z),构建一个与之垂直的向量\vec{b},则保证其相互垂直,则\vec{a}\cdot \vec{b}=0,随手可构造\vec{b}=(-z,0,x),再构造\vec{c}=\vec{a}\times \vec{b}

在pbrt-v2的geometry.h的针对向量的定义中有个内联函数用来根据一个输入的向量,计算正交基,输入一个v1,输出v2, 和v3,都是单位向量:

inline void CoordinateSystem(const Vector &v1, Vector *v2, Vector *v3) {
    if (fabsf(v1.x) > fabsf(v1.y)) {
        float invLen = 1.f / sqrtf(v1.x*v1.x + v1.z*v1.z);
        *v2 = Vector(-v1.z * invLen, 0.f, v1.x * invLen);
    }
    else {
        float invLen = 1.f / sqrtf(v1.y*v1.y + v1.z*v1.z);
        *v2 = Vector(0.f, v1.z * invLen, -v1.y * invLen);
    }
    *v3 = Cross(v1, *v2);
}

 

 

你可能感兴趣的:(理论基础)