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.rhkb.cn/news/23843.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 230.二叉搜索树中第K小的元素

题目&#xff1a;给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 小的元素&#xff08;从 1 开始计数&#xff09;。 思路&#xff1a; 代码&#xff1a; /*** Definition for a binary tree node.* public class Tre…

Android 老项目 jcenter 库失效

最近重新维护了一些老项目发现大部分jcenter库失效了&#xff0c; Could not resolve com.xx:2.1.3. 如果你也遇到了&#xff0c;不妨试试 替换为 aliyun的jcenter服务&#xff0c;就不用一个个找代替库了。 project 下的 build.gradle 文件添加&#xff1a; maven { url htt…

Python数据结构:哈希表-高效存储与查找的秘密武器!

大家周一好&#xff01;今天我们来聊聊Python中一个非常重要的数据结构——哈希表。无论是算法面试还是实际开发&#xff0c;哈希表都扮演着至关重要的角色。掌握它&#xff0c;你就能轻松解决许多复杂的编程问题&#xff01; 在编程中&#xff0c;如何实现快速的存储与查找操…

【复习】Redis

数据结构 Redis常见的数据结构 String&#xff1a;缓存对象Hash&#xff1a;缓存对象、购物车List&#xff1a;消息队列Set&#xff1a;点赞、共同关注ZSet&#xff1a;排序 Zset底层&#xff1f; Zset底层的数据结构是由压缩链表或跳表实现的 如果有序集合的元素 < 12…

【电机控制器】ESP32-C3语言模型——DeepSeek

【电机控制器】ESP32-C3语言模型——DeepSeek 文章目录 [TOC](文章目录) 前言一、简介二、代码三、实验结果四、参考资料总结 前言 使用工具&#xff1a; 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、简介 二、代码 #include <Arduino.h&g…

STM32-智能小车项目

项目框图 ST-link接线 实物图&#xff1a; 正面&#xff1a; 反面&#xff1a; 相关内容 使用L9110S电机模块 电机驱动模块L9110S详解 | 良许嵌入式 一、让小车动起来 新建文件夹智能小车项目 在里面复制19-串口打印功能 重命名为01-让小车动起来 新建文件夹motor&…

Redis基础学习

目录 Redis命令 通用命令 String Key的顶层格式 Hash List ​编辑​编辑Set SortedSet 在IDEA使用Jedis操作Redis 常规使用 Jedis的连接池 SpringDataRedis 手动序列化和反序列化 操作Hash Redis命令 通用命令 想知道某个命令怎么用 1.可以在官网学习用法 h…

ASP.NET Core Clean Architecture

文章目录 项目地址一、项目主体1. CQRS1.1 Repository数据库接口1.2 GetEventDetail 完整的Query流程1.3 创建CreateEventCommand并使用validation 2. EFcore层2.1 BaseRepository2.2 CategoryRepository2.3 OrderRepository 3. Email/Excel导出3.1 Email1. IEmail接口层2. Ema…

MySQL数据库——表的约束

1.空属性&#xff08;null/not null&#xff09; 两个值&#xff1a;null&#xff08;默认的&#xff09;和not null&#xff08;不为空&#xff09; 数据库默认字段基本都是字段为空&#xff0c;但是实际开发时&#xff0c;尽可能保证字段不为空&#xff0c;因为数据为空没办法…

DeepSeek-R1:通过强化学习激发大语言模型的推理能力

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》&#xff08;人工智能科学与技术丛书&#xff09;【陈敬雷编著】【清华大学出版社】 文章目录 DeepSeek大模型技术系列三DeepSeek大模型技术系列三》DeepSeek-…

蓝桥杯备考:递归初阶之汉诺塔问题

我们只要想一个主问题&#xff0c;我们是先把a上面n-1个盘子放在c里&#xff0c;然后再把第n个盘子放在b上&#xff0c;再利用a把c上n-1个盘子都放在b上就行了 #include <iostream> using namespace std;void dfs(int n,char x,char y,char z) {if(n0) return;dfs(n-1,x…

聊一聊vue如何实现角色权限的控制的

大家好&#xff0c;我是G探险者。 关于角色与权限控制&#xff0c;通常是分为两大类&#xff1a;一种是菜单权限&#xff1b;一种是操作权限。 菜单权限是指&#xff0c;每个角色对应着可以看到哪些菜单&#xff0c;至于每个菜单里面的每个按钮&#xff0c;比如增删改查等等这类…

如何将公钥正确添加到服务器的 authorized_keys 文件中以实现免密码 SSH 登录

1. 下载密钥文件 2. RSA 解析 将 id_ed25519 类型的私钥转换为 RSA 类型&#xff0c;要将 ED25519 私钥转换为 RSA 私钥&#xff0c;需要重新生成一个新的 RSA 密钥对。 步骤&#xff1a; 生成新的 RSA 密钥对 使用 ssh-keygen 来生成一个新的 RSA 密钥对。比如&#xff0c;执…

RK Android11 WiFi模组 AIC8800 驱动移植流程

RK Android WiFi模组 AIC8800 驱动移植流程 作者&#xff1a;Witheart更新时间&#xff1a;20250220 概要&#xff1a;本文介绍了基于 AIC8800D40 芯片的 WiFi6 模组 BL-M8800DS2-40 在 RK3568 平台上的驱动移植流程。主要涉及环境搭建、驱动代码分析、设备树修改、驱动编译配…

力扣3102.最小化曼哈顿距离

力扣3102.最小化曼哈顿距离 题目 题目解析及思路 题目要求返回移除一个点后的最小的最大曼哈顿距离 最大最小值的题一般直接想到二分 本题有一个简单办法就是利用切比雪夫距离 当正方形转45&#xff0c;即边上点**( x , y ) -> (x y , y - x)时&#xff0c;两点间max(…

BUUCTF--[极客大挑战 2019]RCE ME

目录 URL编码取反绕过 异或绕过 异或的代码 flag 借助蚁剑中的插件进行绕过 利用动态链接库 编写恶意c语言代码 进行编译 然后再写一个php文件 将这两个文件上传到/var/tmp下 运行payload 直接看代码 <?php error_reporting(0); if(isset($_GET[code])){$code$_G…

Linux----线程

一、基础概念对比 特性进程 (Process)线程 (Thread)资源分配资源分配的基本单位&#xff08;独立地址空间&#xff09;共享进程资源调度单位操作系统调度单位CPU调度的最小单位创建开销高&#xff08;需复制父进程资源&#xff09;低&#xff08;共享进程资源&#xff09;通信…

Missing required prop: “maxlength“

背景&#xff1a; 封装一个使用功能相同使用频率较高的input公共组件作为子组件&#xff0c;大多数长度要求为200&#xff0c;且实时显示统计子数&#xff0c;部分input有输入提示。 代码实现如下&#xff1a; <template><el-input v-model"inputValue" t…

DeepSeek引领目标检测新趋势:如何通过知识蒸馏优化模型性能

目录 一、知识蒸馏是什么&#xff1f; 二、知识蒸馏在目标检测中的重要性 提升实时性 跨任务迁移学习 三、如何使用知识蒸馏优化目标检测&#xff1f; 训练教师模型 生成软标签 训练学生模型 调节温度参数 多教师蒸馏&#xff08;可选&#xff09; 四、案例分享 定…

给老系统做个安全检查——Burp SqlMap扫描注入漏洞

背景 在AI技术突飞猛进的今天&#xff0c;类似Cursor之类的工具已经能写出堪比大部分程序员水平的代码了。然而&#xff0c;在我们的代码世界里&#xff0c;仍然有不少"老骥伏枥"的系统在兢兢业业地发光发热。这些祖传系统的代码可能早已过时&#xff0c;架构可能岌…