[3D 图形学基础] 读书笔记(3) Part_I(Getting Started) - Affine 仿射

2023-12-26 03:40

本文主要是介绍[3D 图形学基础] 读书笔记(3) Part_I(Getting Started) - Affine 仿射,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本章内容主要是一些概念的理解~

1. 将坐标系从原先的三维拓展到了四维,从线性变换拓展到了仿射变换,简单理解就是从旋转/缩放变换增加了位移变换的功能。

2. 注意一下 刚体变换 这个概念,指的是只有 [旋转+位移] 的变换, 因为在这两种变换中,对象点与点之间的点乘关系不变,也就是说保持了刚体状态。

3. 最后讨论了仿射变换中,如何计算法线向量的问题

文章结束有本章内容的PDF链接~


Chapter_3 Affine 仿射


3.1 Points and Frames 点与坐标系

[点与向量]
将点与向量作为两种不同的类型来思考很有帮助。点是在几何体世界中的某个固定的位置,而向量则描述两点间的运动。我们会使用两种不同符号来区分点和向量。向量 v⃗  顶部有一个箭头,而点 p~ 顶部则有波浪线。

如果我们将向量看作两点间的运动,那么向量运算(加以及与标量的乘法)就有了明显的意义。如果我们将两向量相加,我们表示的是两个运动的连接。如果我们将向量与标量相乘,我们是将该运动以一定系数增大或减小。零向量是一个特殊的表示没有运动的向量。

这些运算对点来说并没有太多意义。将两个点相加应该得到什么结果(例如,将哈佛广场与肯德尔广场相加)?将点与标量乘应该意味着什么?用法7乘以南极点应该意味着什么?存在着一个与其他点不同的零点吗?

有一种两点间的运算确实具有某些层面的意义:减法。当我们将一个点与另一个点相减时,我们应该得到从第二个点到第一个点的向量。

p~q~=v⃗ 

相反,如果我们从一个点开始,沿着某一向量运动,我们应该得到另一个点

p~+v⃗ =p~

[仿射变换]
对点进行线性变换是有意义的。例如我们可以将一点绕着某一固定原点旋转。对于点,位移也是有意义的操作(位移的概念对向量没有意义)。为了表示位移,我们需要使用仿射变换(affine transform)这一概念。为了实现它,我们需要4x4的矩阵。4x4矩阵不仅仅有助于在这里处理仿射变换,随后我们描述摄影机投影运算时也很有用(见第10章)。

3.1.1 Frames 坐标系

[在仿射空间中用 [原点+向量] 来描述点]
在仿射空间中,我们这样描述一个点,从某一原点 o~ 开始,再将它与向量的线性组合相加。该向量由一组向量基和坐标系向量 ci 表示

p~=o~+icib⃗ i=[b⃗ 1b⃗ 2b⃗ 3o~]c1c2c31=f⃗ tc.

其中 1o~ 定义为 o~

横向的行

[b⃗ 1b⃗ 2b⃗ 3o~]=f⃗ t

称为一个仿射坐标系(affine frame),它与向量基相似,但由三个向量和一个点组成。

[仿射坐标系的第四个分量: 1表示点, 0表示向量]
用坐标系来指定一个点,我们使用一组4项的坐标系向量,其中最后一项总是为1。用坐标系来表示一个向量时,我们使用最后一项为0的坐标系向量(也就是说,它是向量基的组合)。使用4项的坐标系向量来表示几何体(以及4x4矩阵)也会在第10章我们研究针孔相机模型的时候派上用场。

3.2 Affine Transformations and 4 by 4 Matrices 仿射变换与4乘4矩阵

与线性变换的情况相同,我们会在坐标系向量与坐标系之间放置一个合适的矩阵,以此来定义作用于点的仿射变换的概念。

我们来定义一个4乘4矩阵形式的仿射矩阵(affine matrix)

aei0bfj0cgk0dhl1

[对点进行仿射变换量]
用以下方式对点 p~=f⃗ tc 进行仿射变换:

[b⃗ 1b⃗ 2b⃗ 3o~]c1c2c31[b⃗ 1b⃗ 2b⃗ 3o~]aei0bfj0cgk0dhl1c1c2c31

或者简写为

f⃗ tcf⃗ tAc.

我们可以验证上面公式的第二行描述了一个合法的点,根据乘法

xyz1=aei0bfj0cgk0dhl1xyz1

我们得到了一个4项的向量,其中第4项为1。此外,我们可以看到

[b⃗ 1b⃗ 2b⃗ 3o~]=[b⃗ 1b⃗ 2b⃗ 3o~]aei0bfj0cgk0dhl1

其中 0o~ 定义为 0⃗  ,我们得到了一个由3个向量和一个点组成的坐标系。

需要注意如果矩阵的最后一行不是 [0,0,0,1] ,那它通常会给我们一个非法的结果。

[对坐标系进行仿射变换]
与线性变换相似,我们可以对坐标系进行仿射变换

[b⃗ 1b⃗ 2b⃗ 3o~][b⃗ 1b⃗ 2b⃗ 3o~]aei0bfj0cgk0dhl1c1c2c31

或者简写为

f⃗ tf⃗ tA.

3.3 Applying Linear Transformations to Points 对点进行线性变换

[将3x3线性矩阵嵌入到4x4仿射矩阵]
假设我们有一个表示一个线性变换的3乘3矩阵。我们可以将它嵌入到4乘4矩阵的左上角,并使用这个更大的矩阵来对点(或坐标系)进行变换:

[b⃗ 1b⃗ 2b⃗ 3o~]c1c2c31[b⃗ 1b⃗ 2b⃗ 3o~]aei0bfj0cgk00001c1c2c31

这一变换与线性变换对 ci 有同样的效果。如果我们将点 p~ 看作从原点 o~ 偏移了向量 v⃗  ,我们可以看出这一变换与对该向量进行线性变换具有同样的效果。所以,例如,如果该3乘3矩阵是一个旋转矩阵,则这一线性变换会将该点绕着原点旋转(图3.1)。我们将会在第4章中看到,当对点进行线性变换时坐标系原点的位置会起到很重要的作用。

这里写图片描述
对一个点进行线性变换。由对从原点出发到该点的向量进行线性变换来完成。

[4x4矩阵的简写形式]
我们使用以下简写方式来描述只进行线性变换的4乘4矩阵:

L=[l001]c1c2c31

其中 L 是一个4乘4矩阵,l是一个3乘3矩阵,右上角的0是一个由0组成的3乘1矩阵,左下角的0是一个由0组成的1乘3矩阵,而右下角的1是一个标量。

3.4 Translations 位移

[对点进行位移操作]
对点的位移操作非常有用。这一变换不是线性的(见练习2.4)。仿射变换主要的新功能就在于,它能够表示位移。特别是,如果我们进行以下变换

[b⃗ 1b⃗ 2b⃗ 3o~]c1c2c31[b⃗ 1b⃗ 2b⃗ 3o~]100001000010txtytz1c1c2c31

我们可以看出它对坐标系向量造成的影响为

c1c1+txc2c2+tyc3c3+tz

对于位移,我们使用以下方式简写

T=[i0t1]c1c2c31

其中 T 是一个4乘4矩阵,i是一个3乘3单位矩阵,右上角的 t 是一个表示位移的3乘1矩阵,左下角的0是一个由0组成的1乘3矩阵,而右下角的1是一个标量。

注意,如果c的第4项为0,那么它表示向量而不是一个点,那么它就不会受到位移的影响。

3.5 Putting Them Together 综合这些要素

[综合线性与位移]
任意仿射矩阵都可以被分解为一个线性部分和一个位移部分:

aei0bfj0cgk0dhl1=100001000010dhl1aei0bfj0cgk00001

或者简写为

[l0t1]A=[i0t1][l001]=TL(3.1)(3.2)

注意矩阵相乘是不满足互易性的, TL 相乘的顺序有意义,一个仿射矩阵也可以用一个不同的位移矩阵 T 被分解为 A=LT ,但我们不会使用这个形式。

[刚体变换]
A=TR(3.3)

在这个情况中,我们将矩阵 A 称作一个刚体矩阵(rigid body matrix),它所进行的变换称为刚体变换(rigid body transformation),或RBT。一个刚体变换保持了向量间的点乘关系,向量基的手性信息,以及点与点之间的距离关系。

3.6 Normals 法线

[在仿射变换中处理法线信息]
在计算机图形学中,我们常常使用表面的法线信息来决定表面上的一个点应当如何被着色。因此,我们需要了解当表面上的点发生由矩阵A所描述的仿射变换时,表面的法线会如何变化。

有人会猜测我们可以将法线坐标系简单的与 A 相乘。例如,当我们旋转几何体时,法线会以同样的方式旋转。但是使用矩阵A,事实上,并不总是正确。例如,如图3.2所示,我们沿着 y 轴方向挤压一个球体。在此情况中,实际上法线被沿着y方向拉伸而不是挤压。在这里,我们需要在所有情况下都能适用的正确变换。

[定义法线为垂直于无穷接近的两个点相减的向量]
让我们定义一个光滑表面上某一点的法线(normal)为一个向量,垂直于表面在该点处的切线平面。切线平面是由在该表面上接近(无穷小)的点相减得到的向量来定义的,由此,我们得到了

n⃗ (p1~p0~)=0

对于法线 n⃗  和两个在表面上非常近的点 p1~ p0~ 。在某些固定的正交坐标系统当中,它可以被表示为

[nxnynz]x1y1z11x0y0z01=0(3.4)

我们在第4项使用”*”,因为它会与0相乘因而无关紧要。

[推导变换后的法线向量]
假设我们使用一个仿射矩阵 A 来对我们所有的点进行仿射变换。那么什么向量对于所有切线向量都保持垂直呢?我们将等式(3.4)重写为

([nxnynz]A1)Ax1y1z11x0y0z01=0(3.5)

如果我们定义 [x,y,z,1]t=A[x,y,z,1]t 为一个变换后点的坐标系向量,并且让 [nx,ny,nz,]=[nx,ny,nz,1]A1 ,那么我们有

[nxnynz]x1y1z11x0y0z01=0(3.6)

由此我们可以看出 [nx,ny,nz] 是形状变换后法线的坐标系向量(由缩放决定)。

注意,我们不关心”*”处的取值,因此我们也不关心 A1 的第4列。同时, A 是一个仿射矩阵,因此A1也是,由此得出余下3列的第4行全部为0可以安全的被忽略。因此,使用简写

A=[l0t1](3.7)

我们可以看出

[nxnynz]=[nxnynz]l1(3.8)

[最终的法线向量]
并将整个表达式转置,我们就得到了

nxnynz=l1nxnynz(3.9)

其中 l1 是3乘3矩阵的逆转置(与转置的逆相等)。注意如果 l 是一个旋转矩阵,该矩阵是正交的,因此它的逆转置实际上与l相同。在这个情况下,一个法线的坐标系向量与一个点的坐标系向量表现相同。对于其他的线性变换,它们却有不同的表现(图3.2)。也需要注意下, A 的位移部分对法线没有影响。

这里写图片描述
左:有色形状和黑色的法线。中:形状在y方向上被减小,并且(未被归一化的)法线在 y 方向被拉伸。右:法线被重新校正为对挤压后形状来说正确的单位法线。

Exercises 练习

3.1 如果给出以下定义的对于点的运算:对于实数αi,有 α1p~1+α2p~2 ,其中 1=iαi 。证明它可以被解释为在3.1节开始部分描述过的对于点和向量的运算。

本章的PDF版可以去这里拿~

这篇关于[3D 图形学基础] 读书笔记(3) Part_I(Getting Started) - Affine 仿射的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/537977

相关文章

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

安装centos8设置基础软件仓库时出错的解决方案

《安装centos8设置基础软件仓库时出错的解决方案》:本文主要介绍安装centos8设置基础软件仓库时出错的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录安装Centos8设置基础软件仓库时出错版本 8版本 8.2.200android4版本 javas

Linux基础命令@grep、wc、管道符的使用详解

《Linux基础命令@grep、wc、管道符的使用详解》:本文主要介绍Linux基础命令@grep、wc、管道符的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录grep概念语法作用演示一演示二演示三,带选项 -nwc概念语法作用wc,不带选项-c,统计字节数-

python操作redis基础

《python操作redis基础》Redis(RemoteDictionaryServer)是一个开源的、基于内存的键值对(Key-Value)存储系统,它通常用作数据库、缓存和消息代理,这篇文章... 目录1. Redis 简介2. 前提条件3. 安装 python Redis 客户端库4. 连接到 Re

SpringBoot基础框架详解

《SpringBoot基础框架详解》SpringBoot开发目的是为了简化Spring应用的创建、运行、调试和部署等,使用SpringBoot可以不用或者只需要很少的Spring配置就可以让企业项目快... 目录SpringBoot基础 – 框架介绍1.SpringBoot介绍1.1 概述1.2 核心功能2

Spring Boot集成SLF4j从基础到高级实践(最新推荐)

《SpringBoot集成SLF4j从基础到高级实践(最新推荐)》SLF4j(SimpleLoggingFacadeforJava)是一个日志门面(Facade),不是具体的日志实现,这篇文章主要介... 目录一、日志框架概述与SLF4j简介1.1 为什么需要日志框架1.2 主流日志框架对比1.3 SLF4

Spring Boot集成Logback终极指南之从基础到高级配置实战指南

《SpringBoot集成Logback终极指南之从基础到高级配置实战指南》Logback是一个可靠、通用且快速的Java日志框架,作为Log4j的继承者,由Log4j创始人设计,:本文主要介绍... 目录一、Logback简介与Spring Boot集成基础1.1 Logback是什么?1.2 Sprin

MySQL复合查询从基础到多表关联与高级技巧全解析

《MySQL复合查询从基础到多表关联与高级技巧全解析》本文主要讲解了在MySQL中的复合查询,下面是关于本文章所需要数据的建表语句,感兴趣的朋友跟随小编一起看看吧... 目录前言:1.基本查询回顾:1.1.查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J1.2.按照部门

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib