1.线性变换:

  函数的输入和输出都是3D向量,我们称为线性变换

矩阵表示法:

所以已知一个线性变换,只要将i,j,z也就是标准基向量代入线性变换,就能构造一个变换矩阵

A:线性变换的矩阵表示法 -- 线性变换才能满足这种提取式

⭐若为线性变换,当且仅当此函数具有下列性质:

2.缩放:scaling

缩放变换是相对于当前坐标系中的原点,令向量在x、y、z轴上分别以系数进行缩放

 -- Sx Sy Sz就是xyz轴的缩放系数

左手坐标系的变换矩阵与坐标表示与右手有很大不同,变换矩阵乘在坐标右侧, 坐标以行向量形式存在

3.旋转:rotating

旋转矩阵证明(罗德里格旋转公式):假设这种情况,令向量v绕轴n以角θ进行旋转,在沿n轴从上至下俯瞰时,我们按顺时针方向来测量角θ,并假设,v和n之间的夹角为α

旋转时我们考虑将向量v分解成平行于n轴的分量和垂直于n轴的分量,平行于n轴的分量在旋转时是保持不变的

最终,旋转向量:

   :v·n是大小,n是平行方向

    :在垂直于z轴的平面内旋转θ角度

确定大小:

确定方向:

  的方向就是旋转的"切方向"

因此推导出了旋转公式:

 :因为v垂直=v-v平行

要证明是线性变换,只要证明其满足上述两个性质⭐即可

①分配律:叉乘和点乘都满足分配律,所以第一条性质满足

②标量乘法提取:叉乘和点乘都满足能提取标量乘积,所以第二条性质满足

所以是线性变换 -- > 能写成矩阵表达式的方式

将各个标准基向量代入线性变换函数,再把得到的向量分别作为矩阵的行向量,最终结果:

其中:

旋转矩阵有一个特殊的性质,每个行向量都为单位长度且两两正交,也就是说这些行向量都是规范正交的,因此旋转矩阵是正交矩阵  --- 正交矩阵的特性:逆矩阵等于转置矩阵

特别的:如果选择绕x轴、y轴或z轴旋转(n取(1,0,0)...)

  

注意:①这是在不考虑齐次坐标的情况下的旋转矩阵

②记忆方法:如若旋转x轴,则第一行第一列扣除,剩下的”余子阵“左上角为cosθ,右上角为sinθ以此类推

注意:旋转部分,是以原点为中心进行旋转! -- 如果想对一个对称图案进行旋转,请先确定其旋转中心 。

4.齐次坐标:homogeneous coordinate

将坐标扩充为四元组,第四个坐标的取值w根据坐标描述对象的不同而不同:

 表示向量

 表示点

好处:①向量不考虑平移操作,设置w=0可以防止收到平移操作的影响

②点-点=向量 点+向量=点 向量+向量=向量

5.仿射变换:

仿射变换=线性变换+平移

扩充为齐次坐标后:

①如果输入的w=0,那么0*b_x=0,所以没有执行平移操作

②输入w不管是多少,仿射变换矩阵最后一列都是[0,0,0,1]^T,得到的新坐标w仍然为原值,所以进行仿射变换后不会改变w的值

注意,不管是缩放还是平移等变换矩阵,如果再乘以变换矩阵的逆,那么物体就没有移动,所以从理论上我们就能联想到平移矩阵和缩放矩阵的逆是如何书写的

6.变换的组合:

变换矩阵的组合:SRT  --  S:缩放矩阵  R:旋转矩阵  T:平移矩阵

我们往往会先把各种变换矩阵相乘,在对每一个顶点操作,免得每个顶点都挨着乘上不同的变换矩阵,影响性能 -- 但是注意,矩阵乘法不满足交换律,所以矩阵乘法的顺序很重要

7.坐标变换:

①向量的坐标变换:

对于框架A:,对于框架B:

其中x,y是P点在框架A中的坐标,是框架B的xy坐标轴相对于框架A的坐标

已知P点在A框架中的坐标,以及A框架中坐标轴相对于B框架的坐标,即可求得

现将向量推广到3D空间,如果,那么

②点的坐标变换:

点的坐标变换,相比于向量的坐标变换,要额外考虑坐标系的平移,坐标系的原点不在同一处

所以加上平移向量:

:框架A中原点在框架B中的位置坐标

③(总结)坐标变换的矩阵表示:

根据线性变换和齐次坐标(对应w坐标)的概念,我们可以把拆成矩阵相乘形式:

 坐标变换矩阵:   坐标转换矩阵的逆: 

-- 本质上是一个旋转加平移矩阵[旋转矩阵的逆就是其转置矩阵、平移矩阵的逆就是取负数] -- 能把坐标变换,理解成与几何变换相同的数学形式,可谓是殊途同归

在后续DX12管线处理中,我们需要得到观察矩阵(view matrix),观察矩阵可以从世界空间到观察空间的转换,我们可以通过求W的逆,将坐标从世界空间变换到观察空间,DirectXMath提供专门的函数XMMatrixLookAtLH()得到观察矩阵,也可以自行构造(龙书第15章书写摄像机类时自行构造了观察矩阵)

具体代码:

// 代码在龙书P499~500页
float x = -XMVectorGetX(XMVector3Dot(P, R));
float y = -XMVectorGetX(XMVector3Dot(P, U));
float z = -XMVectorGetX(XMVector3Dot(P, L));// mRight:摄像机右侧 -- 观察坐标系+x轴
mView(0, 0) = mRight.x;
mView(1, 0) = mRight.y;
mView(2, 0) = mRight.z;
mView(3, 0) = x;// mUp:摄像机正上方 -- 观察坐标系+y轴
mView(0, 1) = mUp.x;
mView(1, 1) = mUp.y;
mView(2, 1) = mUp.z;
mView(3, 1) = y;// mLook:摄像机正前方 -- 观察坐标系+z轴
mView(0, 2) = mLook.x;
mView(1, 2) = mLook.y;
mView(2, 2) = mLook.z;
mView(3, 2) = z;mView(0, 3) = 0.0f;
mView(1, 3) = 0.0f;
mView(2, 3) = 0.0f;
mView(3, 3) = 1.0f;

mRight是观察坐标系+x轴的向量在世界坐标系中的坐标表现 -> 观察坐标系是框架A,世界坐标系是框架B,所以得到的是从观察坐标系转换到世界坐标系的坐标转换矩阵 -- 所以需要求逆

8.DirectXMath库提供的变换函数:

// 1.这些函数的作用是构造(返回)一个变换矩阵
// 构造缩放矩阵
XMMATRIX XM_CALLCONV XMMatrixScaling(float ScaleX,float ScaleY,float ScaleZ);
// 用3D向量的分量来构造缩放矩阵
XMMATRIX XM_CALLCONV XMMatrixScalingFromVector(FXMVECTOR Scale); // 弧度 以顺时针方向旋转
XMMATRIX XM_CALLCONV XMMatrixRotationX(float Angle); // float Angle是以弧度为单位// 绕旋转轴Axis顺时针旋转
XMMATRIX XM_CALLCONV XMMatrixRotationAxis(FXMVECTOR Axis,float Angle); // 平移
XMMATRIX XM_CALLCONV XMMatrixTranslation(float OffsetX,float OffsetY,float OffsetZ);
// 平移 用向量构造
XMMATRIX XM_CALLCONV XMMatrixTranslationFromVector(FXMVECTOR Offset); // 2.计算:
// 计算向量与矩阵的乘积vM 针对点的变换 Vw默认为1
XMVECTOR XM_CALLCONV XMVector3TransformCoord(FXMVECTOR V,CXMMATRIX M); // 针对向量的变换 Vw默认为0
XMVECTOR XM_CALLCONV XMVector3TransformNormal(FXMVECTOR V,CXMMATRIX M); 

注意:参数float Angle是以弧度为单位(虽然参数名字是angle而不是radian)

其实弧度值根本没必要转换为角度值,弧度制为我们常见的表示形式(等等),且三角函数的参数都是以弧度制作为单位

弧度与角度的转换公式:

代码示例:

#include <windows.h>
#include <iostream>
#include <DirectXMath.h>
#include <DirectXPackedVector.h>using namespace std;
using namespace DirectX;
using namespace DirectX::PackedVector;ostream& XM_CALLCONV operator<<(ostream& os, FXMMATRIX m)
{XMFLOAT4X4 dest;XMStoreFloat4x4(&dest, m);for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {os << dest.m[i][j] << " ";}os << "\n";}return os;
}int main()
{XMMATRIX m1 = XMMatrixSet(1.f, 2.f, 3.f, 0.f,0.f, 1.f, 0.f, 0.f,0.f, 0.f, 1.f, 0.f,2.f, 2.f, 2.f, 1.f);cout << m1 << endl;XMMATRIX m2 = XMMatrixScaling(1.f, 2.f, 3.f);cout << m2 << endl;XMVECTOR v1 = XMVectorSet(1.f, 2.f, 3.f, 0.f);XMMATRIX m3 = XMMatrixScalingFromVector(v1);cout << m3 << endl;XMMATRIX m4 = XMMatrixRotationX(30 * XM_PI / 180); cout << m4 << endl;XMVECTOR v2 = XMVectorSet(1.f, 2.f, 3.f, 0);v2 = XMVector4Normalize(v2);XMMATRIX m5 = XMMatrixRotationAxis(v2, 60 * XM_PI / 180);cout << m5 << endl;
}

dx12 龙书第三章学习笔记 -- 变换相关推荐

  1. dx12 龙书第四章学习笔记 -- Direct3D的初始化

    1.预备知识: ①Direct3D 12概述: 通过Direct3D这种底层图形应用程序编程接口(Application Programming Interface, API),即可在应用程序中对图形 ...

  2. dx12 龙书第七章学习笔记 -- 利用Direct3D绘制几何体(续)

    1.帧资源 之前,我们在处理CPU和GPU的同步问题时,采取以下方法:在每帧绘制的结尾调用D3DApp::FlushCommandQueue函数,以确保GPU在每一帧都能正确完成所有命令的执行 这样做 ...

  3. dx12 龙书第十一章学习笔记 -- 模板

    模板缓冲区是一种"离屏"(off-screen)缓冲区,我们可以用它来实现一些特殊的效果.模板缓冲区.后台缓冲区以及深度缓冲区都有着相同的分辨率,所以三者相同位置上的像素就能一一对 ...

  4. dx12 龙书第二十一章学习笔记 -- 环境光遮蔽

    hd之前我们在光照模型中模拟间接光的公式为:.我们利用一个相同的光量将场景中的所有元素稍微照亮一点.这里有改良的余地,这章将就流行于改善环境光项的环境光遮蔽技术展开讨论. 1.通过投射光线实现环境光遮 ...

  5. 周志华西瓜书第三章学习笔记

    第三章学习笔记 文章目录 第三章学习笔记 1.知识脉络 2.我的笔记 参考 1.知识脉络 2.我的笔记 这一章公式推导实在太多了,需要补充的推导过程也有很多,就不写电子档了.扩展公式推导和LDA部分补 ...

  6. dx12 龙书第十八章学习笔记 -- 立方体贴图

    本章讨论:立方体贴图 cube map,即以特殊的方式来运用这种由6个纹理所构成的基本数组.我们可以利用这项技术方便地映射天空纹理或模拟反射. 1.什么是立方体贴图 -- Cube Map 立方体贴图 ...

  7. 西瓜书第三章阅读笔记

    西瓜书第三章阅读笔记 第三章 线性模型 1.机器学习三要素 2.基本形式 3.线性回归 3.1 模型 3.2 策略 3.3 求解算法 4.对数几率回归 4.1 模型 4.2 策略 4.3 求解算法 5 ...

  8. 正则表达式引擎的构建——基于编译原理DFA(龙书第三章)——1 概述

    说明:本系列文章介绍的算法均来自编译原理(龙书)一书,如果读者对代码没有兴趣,只想了解算法思路,完全可以阅读龙书相关章节内容,比我讲得清晰透彻. 序: 啃编译原理半年以来,任然徘徊在前4章,其间反反复 ...

  9. 工程伦理第三章学习笔记2020最新

    工程伦理第三章学习笔记2020最新 因为之前自己在网上找答案总是觉得费劲,一道一道的找,很慢,突然找到了前两章的答案,感觉有一种前人种树后人乘凉的感觉,于是自己在艰难找完第三章习题并全对的情况下,将题 ...

最新文章

  1. 区块链概况:什么是区块链
  2. 数据库 DB database SQL DBMS
  3. lex 词法分析 linux,lex语言词法分析
  4. 用git从github网站上下载代码的方法
  5. win7设置自动开机时间_电脑可以设置自动开机时间,您知道吗?
  6. Opencv判断是否加载图片的两种方法
  7. 主播靠颜值还是???!!!!!
  8. 高可用性、负载均衡的mysql集群解决方案
  9. async-http java_使用Java和async-http-client通过基本身份验证获取URL内容 - java
  10. 逻辑思维训练500题(修订版)
  11. could not open `C:\Program Files\Java\jre7\lib\amd64\jvm.cfg' 的解决办法:
  12. matlab实现模拟退火算法
  13. CSS图片文字排版01
  14. 跨站脚本攻击(XSS)及防范措施
  15. VUE | “面包屑”的原理
  16. vue 截取video第一帧作为封面
  17. 如何(不)让你的Python代码不再晦涩难懂
  18. 微信图片怎么添加竖排文字_轻松设置微信竖排昵称
  19. 实现从淘宝(天猫)定时抓取订单数据、打印电子面单并保存到ERP表中
  20. 第二十九章 管理许可(二)

热门文章

  1. java后台接收json数据
  2. 北理计算机研究生在良乡校区吗,食在良乡——说说我在北理工的这几年
  3. 利用谷歌语法进行漏洞搜索
  4. 远程桌面出现身份验证错误,要求的函数不受支持 (win10 远程连接)
  5. Quake4动画部分
  6. js 格式化prettier配置_Prettier格式化配置
  7. SpringBoot:微信授权扫一扫登陆整体流程超详细
  8. 去掉iphone手机数字默认下划线
  9. 【VScode远程连接虚拟机(ubuntu)】
  10. 计算机考研经验分享:一战暨南大学(死亡计专),调剂七天上岸华侨大学