当前位置: 首页 > article >正文

DirectX12(D3D12)基础教程三 线性代数与3D世界空间

线性代数是数学的一个分支,它的研究对象是向量,向量空间(或称线性空间),线性变换和有限维的线性方程组。 向量和矩阵是学习3D入门最基本的理论基础。本章重点讲向量和矩阵. 

向量概念

向量最基本的定义就是一个方向长度,如图坐标点(3,4)

根据 勾股定理  \sqrt{x^{2}+y^{2}} 可以计算出它长度是5=\sqrt{3^{2}+4^{2}}也叫做向量的模 方向是与X轴的夹角θ,向量的长度和方向根据坐标可以计算出,通常书写标记为:\binom{3}{4} 通常大家喜欢在字母上面加一横表示向量,如: \bar{V}=\binom{3}{4}

单位向量

有一个特殊类型向量的模(长度)等于1叫做单位向量,把一个向量变成单位向量这叫标准化。任意向量的每个分量除以向量的模就得到它的单位向量。特别是在我们只关心方向不关心模(长度)的时候。比如 \bar{V}=\binom{3}{4}要标准化,先计算模\left | \right |\bar{v}\left | \right | = \sqrt{3^{2}+4^{2}} = 5,然后除以向量的模 ,\binom{3}{4}的单位向量\hat{n} = \frac{\bar{v=}\binom{3}{4}}{5} = \binom{3/5}{4/5}=\binom{0.6}{0.8}。现在我们再计算向量\binom{0.6}{0.8}的模 \left \| \bar{v} \right \| =\sqrt{0.6^{2}+0.8^{2}}=\sqrt{0.36+0.64}=\sqrt{1}=1,再次证实了。

向量运算

向量与标量加减乘除

\binom{X}{Y} [+-*/] Z = \binom{X[+-*/]Z}{Y[+-*/]Z} ,比如加法运算 :\binom{3}{4} + 10 = \binom{3+10}{4+10} = \binom{13}{14}

向量与向量的加减

\binom{X}{Y}[+-]\binom{X2}{Y2} = \binom{X[+-]X2}{Y[+-]Y2}   比如加法运算 :\binom{1}{2}+\binom{3}{4}=\binom{1+3}{2+4} = \binom{4}{6}

以上都比较好理解,不做过多的说明了

向量相乘

普通的乘法在向量上是没有定义的,在3D世界里 ,两种特定情况:1.点乘(Dot Product)记作\bar{v} \cdot \bar{k}2.叉乘(Cross Product)记作\bar{v}\times \bar{k}

1.点乘(Dot Product) ,两个向量的点乘结果等两个向量之间夹角的余弦值,可以算出向量之间夹角的角度,提前是先要标准化。点乘会在计算光照的时候非常有用。比如计算\binom{3}{4}向量与X轴\binom{0}{1}的夹角\Theta,点乘会像是这样\cos\Theta =\binom{0.6}{0.8}\cdot \binom{0}{1} = 0.6*0+0.8*1=0.8

2.叉乘(Cross Product) 叉乘只在3D空间中有定义,它需要两个不平行向量作为输入,生成一个正交于两个输入向量的第三个向量。公式如下:

如看不懂,先放下。

矩阵

现在我们已经讨论了向量的全部内容,是时候看看矩阵了!简单来说矩阵就是一个矩形的数字、符号或表达式数组。矩阵中每一项叫做矩阵的元素(Element)。下面是一个2×3矩阵的例子:\begin{bmatrix} 1 &2 &3 \\ 4& 5& 6 \end{bmatrix} 可以把它看做一个两维数据。

矩阵运算

矩阵与与标量加减乘除比较好理解,比较如加法 \begin{bmatrix} 1 & 2 & 3\\ 4 &5 & 6 \end{bmatrix} + 10 =\begin{bmatrix} 10+1 & 10+2 & 10+3\\ 10+4 &10+5 &10+ 6 \end{bmatrix} = \begin{bmatrix} 11 & 12 & 13\\ 14 &15 & 16 \end{bmatrix}

矩阵相乘

注意事项

1. 只有当左侧矩阵的列数与右侧矩阵的行数相等,两个矩阵才能相乘。
2. 矩阵相乘不遵守交换律也就是说A⋅B≠B⋅A

我们先看一个两个2×2矩阵相乘的例子

\begin{bmatrix} 1 &2 \\ 3& 4 \end{bmatrix} \times \begin{bmatrix} 5 &6 \\ 7& 8 \end{bmatrix} = \begin{bmatrix} 1*5+2*7 &1*6+2*8 \\ 3*5+4*7& 3*6 +4*8\end{bmatrix} =\begin{bmatrix} 19 &22 \\ 43& 50 \end{bmatrix}

上面的例子我们来找找规律:

 结果矩阵19是由第一个矩阵的第一行和第二个矩阵的第一列运算出来的

19 = 1*5+2*7

 结果矩阵22是由第一个矩阵的第一行和第二个矩阵的第二列运算出来的

22 = 1*6+2*8

结果矩阵43是由第一个矩阵的第二行和第二个矩阵的第一列运算出来的

43 = 3*5+4*7

结果矩阵50是由第一个矩阵的第二行和第二个矩阵的第二列运算出来的

43 = 3*6+4*8

它的规律就是 矩阵n×n 记作A_{n.n} ,矩阵B_{n.n}, 矩阵相乘结果 A_{n.n} \timesB_{n.n} = C_{n.n} C_{i.j} =A_{i.0} *B_{0.j} + A_{i.1} *B_{1.j} + A_{i.2} *B_{2.j} .. A_{i.n} *B_{n.j} 简单记作 结果矩阵的行就是第一矩阵的行,结果矩阵的列是第二矩阵的列,结果矩阵的值 第一矩阵的行与第二矩阵的列相乘相加的结果。

再练来习一个

\begin{bmatrix} 3 & 2 & 0\\ 0 & 3&1 \\ 0& 1 & 0 \end{bmatrix} \times \begin{bmatrix} 3 & 2 & 1\\ 2 & 0&3 \\ 0& 3 & 2 \end{bmatrix} = \begin{bmatrix} 3*3 +2*2+0*0& 3*2+2*0+0*3 & 3*1+2*3+0*2\\ 0*3+3*2+1*0 & 0*2+3*0+1*3&0*1+3*3+1*2 \\ 0*3+1*2+0*0& 0*2+1*0+0*3 & 0*1+1*3+0*2 \end{bmatrix}=\begin{bmatrix} 13 & 6 & 9\\ 6 & 3&11 \\ 2& 0 & 3 \end{bmatrix}

要是实在记不住 也没关系,运算时我们调用库函数去实现计算细节。

单位矩阵

由于某些原因我们通常使用4×4的变换矩阵,单位矩阵是一个除了对角线以外都是0的N×N矩阵。如下 \begin{bmatrix} 1 &0 &0 &0 \\ 0&1 & 0& 0\\ 0 &0 & 1 &0 \\ 0& 0 &0 & 1 \end{bmatrix}

向量/2D/3D变换都可以放在一个单位矩阵进行比如 矩阵乘以 单位矩阵 还是原来的矩阵\begin{bmatrix} 1 &0 &0 &0 \\ 0&1 & 0& 0\\ 0 &0 & 1 &0 \\ 0& 0 &0 & 1 \end{bmatrix}\times \begin{bmatrix} 1\\ 2\\ 3\\ 4 \end{bmatrix} = \begin{bmatrix} 1\\ 2\\ 3\\ 4 \end{bmatrix}

缩放

通常使用4×4的变换矩阵, 3D空间对向量进行缩放,先构造单位矩阵,然后设置缩放因子(S1,S2,S3)

\begin{bmatrix} s1 & 0 & 0 &0 \\ 0 & s2 & 0&0 \\ 0& 0 & s3&0 \\ 0& 0& 0 & 1 \end{bmatrix}\times \begin{pmatrix} x\\ y\\ z\\ 1 \end{pmatrix} =\begin{pmatrix} s1*x\\s2*y\\ s3*z\\ 1 \end{pmatrix}

位移

原始向量的基础上加上另一个向量,两个向量相加,我们也可用矩阵与向量相乘同样达到目的

\begin{bmatrix} 1 & 0 & 0 & x1\\ 0 &1 & 0 &y1 \\ 0 & 0 & 1 & z1\\ 0 & 0 & 0 & 1 \end{bmatrix}\times \begin{pmatrix} x\\y \\ z\\1 \end{pmatrix} = \begin{pmatrix} x+x1\\y +y1\\ z+z1\\1 \end{pmatrix}

旋转

对向量旋转需要定义一个角和一个旋转轴。沿x、y、z轴旋转作算法不相同。这部份理论稍复杂些我们直接抄公式了,旋转角度用θ表示

在实际代码中使用是比较简单的 比如沿Y轴旋转  XMMATRIX model = XMMatrixRotationY(static_cast<float>(m_dYAngle));    

组合练习

我们有一个顶点(x, y, z),我们希望将其缩放2倍,然后位移(1, 2, 3)个单位.
注意,矩阵乘法是不遵守交换律的,这意味着它们的顺序很重要,建议您在组合矩阵时,先进行缩放操作,然后是旋转,最后才是位移,否则它们会(消极地)互相影响。
定义缩放矩阵 2\cdot \begin{bmatrix} 1 & 0& 0&0 \\ 0 & 1& 0& 0\\ 0& 0 & 1&0 \\ 0& 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} 2 & 0& 0&0 \\ 0 & 2& 0& 0\\ 0& 0 & 2&0 \\ 0& 0 & 0 & 1 \end{bmatrix} 缩放w分量是无意义,所以还是1

定义位移矩阵 \begin{bmatrix} 1 & 0 & 0& 1\\ 0& 1& 0 &2 \\ 0& 0& 1 & 3\\ 0&0 &0 &1 \end{bmatrix}

缩放位移矩阵运算 \begin{bmatrix} 1 & 0 & 0& 1\\ 0& 1& 0 &2 \\ 0& 0& 1 & 3\\ 0&0 &0 &1 \end{bmatrix}\times \begin{bmatrix} 2 & 0 & 0& 0\\ 0& 2& 0 &0 \\ 0& 0& 2 & 0\\ 0&0 &0 &1 \end{bmatrix} = \begin{bmatrix} 2 & 0 & 0& 1\\ 0& 2& 0 &2 \\ 0& 0& 2 & 3\\ 0&0 &0 &1 \end{bmatrix}

顶点(x, y, z)最终的变换矩阵\begin{bmatrix} 2 & 0 & 0& 1\\ 0& 2& 0 &2 \\ 0& 0& 2 & 3\\ 0&0 &0 &1 \end{bmatrix} \times \begin{bmatrix} x \\ y\\ z\\ 1 \end{bmatrix} = \begin{bmatrix} 2*x+1 \\ 2*y+2\\ 2*z+3\\ 1 \end{bmatrix}

展开书写是这样的:\begin{bmatrix} 1 & 0 & 0& 1\\ 0& 1& 0 &2 \\ 0& 0& 1 & 3\\ 0&0 &0 &1 \end{bmatrix} \times \begin{bmatrix} 2 & 0 & 0& 0\\ 0& 2& 0 &0 \\ 0& 0& 2 & 0\\ 0&0 &0 &1 \end{bmatrix} \times \begin{bmatrix} x \\ y\\ z\\ 1 \end{bmatrix} = \begin{bmatrix} 2*x+1 \\ 2*y+2\\ 2*z+3\\ 1 \end{bmatrix}

当矩阵相乘时,在最右边的矩阵是第一个与向量相乘的,所以你应该从右向左读这个乘法

3D世界空间

举个例子出来说明,比如人站在房间里面看到一个物体,我们把这个物体作为研究对象,如图

局部空间

物体本身作参照点原点就在它在左角(0,0),它长宽高参照于物体起始的坐标。这叫局部坐标或叫局部空间。


世界空间

如果把房间的左下角作为原点,物体在房间的位置坐标叫世界空间


观察空间

以人坐标位置为原点观察物体,人为的设定Look At矩阵,这样就能计算出观察点在世界空间的坐标

投影

定义了 可观察空间大小,比如可观察空间远近,宽度 ,长度。如图红线处

裁剪空间

以观察点为原点,把不可视范围去掉,保留可视范围最后变换回标准化设备坐标系最终显示在屏幕上叫裁剪空间。

裁剪空间: V_{clip} 

投影空间 :M_{projection}

观察空间 :M_{view}

世界空间 :M_{model}

世界空间 :V_{local}

V_{clip} = M_{projection} \times M_{view} \times M_{model}\times V_{local}

从右向左读这个乘法.

感谢大家的支持,如要问题欢迎提问指正。


http://www.kler.cn/a/560767.html

相关文章:

  • istio介绍补充以及使用篇
  • Python常见面试题的详解21
  • 【前端开发】能不能用Vue+Bootstrap进行项目开发?有什么需求场景需要用到的地方
  • 一周学会Flask3 Python Web开发-Jinja2模板访问对象
  • 云原生时代的分布式文件系统设计与实现
  • 如何查看PostgreSQL的版本
  • Macos ./ollama目录说明
  • overflow-x: auto 使用鼠标实现横向滚动,区分触摸板和鼠标滚动事件的方法
  • angular简易计算器
  • MybatisPlus-扩展功能-枚举处理器
  • Linux-SaltStack基础
  • 【复习】Redis
  • 1.2 redis7.0.4安装与配置开机自启动
  • cpp的stl二分查找库函数
  • 蓝桥杯备赛-精卫填海-DP
  • Android KMP初探
  • AI驱动的自动化留给人类的时间不多了
  • Unity中点乘和叉乘对于我们来说的作用是什么?
  • VoIP之音频3A技术
  • 五、AIGC大模型_04LLaMA-Factory基础知识与SFT实战