天天看点

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

第四章 Transforms 变换

​ 变换是一种操作,它接受点,向量或颜色等实体,并以某种方式对其进行转换。 对于计算机图形从业者来说,掌握转换极为重要。 有了它们,您就可以定位,重塑形状和设置对象,灯光和照相机的动画。 您还可以确保所有计算都在同一坐标系中进行,并以不同方式将对象投影到平面上。 这些只是可以通过转换执行的操作中的少数操作,但是它们足以说明转换角色在实时图形或任何形式的计算机图形中的重要性。

​ 线性变换是保留矢量加法和标量乘法的变换。

f(x) + f(y) = f(x + y), (4.1)

kf(x) = f(kx). (4.2)

​ 例如,f(x)= 5x是一个采用向量并将每个元素乘以5的变换。 为了证明这是线性的,需要满足两个条件(公式4.1和4.2)。 第一个条件成立,因为任何两个向量乘以五然后相加将与将向量相加然后相乘相同。 标量乘法条件(方程式4.2)已明确满足。 此功能称为缩放变换,因为它可以更改对象的缩放比例(大小)。 旋转变换是另一个线性变换,它使向量绕原点旋转。 缩放和旋转变换,实际上是三元素向量的所有线性变换,都可以使用3×3矩阵表示。

​ 但是,矩阵的大小通常不够大。 三元素向量x的函数(例如f(x)= x +(7,3,2))不是线性的。 在两个单独的向量上执行此功能将把(7,3,2)的每个值相加两次以形成结果。 将固定向量添加到另一个向量执行翻译,例如,它将所有位置移动相同的数量。 这是一种有用的变换类型,我们想结合各种变换,例如,将对象缩放到一半大小,然后将其移动到其他位置。 到目前为止,将函数保持在简单的形式上使很难轻松地组合它们。

可以使用仿射变换(affine transform)将线性变换和平移结合起来,通常以4×4矩阵形式存储。 仿射变换是先执行线性变换然后执行平移的变换。 为了表示四元素向量,我们使用同构符号,以相同的方式表示点和方向(使用粗体小写字母)。 方向向量表示为

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

点表示为

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

所有平移,旋转,缩放,反射和剪切矩阵都是仿射的。 仿射矩阵的主要特征是它保留了线的平行性,但不一定保留长度和角度。 仿射变换也可以是各个仿射变换的串联的任何序列。

本章将从最基本的基本仿射变换开始。 本部分可以看作是简单转换的“参考手册”。 然后描述了更加专业的矩阵,随后对四元数(一种强大的转换工具)进行了讨论和描述。 然后是顶点融合和变形,这是表达网格动画的两种简单但有效的方法。 最后,描述了投影矩阵。 这些转换中的大多数,它们的符号,功能和特性总结在表4.1中,其中正交矩阵是其逆矩阵为转置矩阵。

变换是用于操纵几何的基本工具。 大多数图形应用程序编程接口允许用户设置任意矩阵,有时库可能与实现本章讨论的许多转换的矩阵运算一起使用。 但是,仍然有必要了解函数调用背后的真实矩阵及其相互作用。 知道这样的函数调用之后矩阵的功能是一个开始,但是了解矩阵本身的属性将使您更进一步。 例如,这种理解使您可以辨别何时处理正交矩阵(正交是其转置),从而可以更快地进行矩阵求逆。 这样的知识可以导致加速代码。

4.1 Basic Transforms

​ 本节介绍最基本的变换,例如平移,旋转,缩放,剪切,变换级联,刚体变换,法线变换(不是很正常)和逆计算。

各种变换:

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

4.1.1 translation matrix T(t) 平移

从一个位置移动到另一个位置

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

点p =(px,py,pz,1)与T(t)相乘会产生一个新的点p’=(px + tx,py + ty,pz + tz,1),很显然是平移。

平移矩阵的逆是T-1(t)= T(-t),即向量t取反。

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

4.1.2Rotation 旋转

旋转变换将矢量(位置或方向)绕经过原点的给定轴旋转给定角度。 像平移矩阵一样,它是一个刚体变换,即它保留了变换后的点之间的距离,并保留了惯用性(即,它不会导致左右两侧互换)。 这两种类型的转换在计算机图形学中用于定位和定向对象显然非常有用。 方向矩阵是与摄像机视图或对象相关联的旋转矩阵,它定义其在空间中的方向,即其向上和向前的方向。

在二维上,旋转矩阵很容易得出。 假设我们有一个向量v =(vx,vy),我们将其参数化为v =(vx,vy)=(rcosθ,rsinθ)。 如果将那个矢量旋转φ弧度(逆时针),则将得到u =(r cos(θ+φ),r sin(θ+φ))。 可以改写成

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

所有可以得到分别按照X Y Z轴旋转的公式

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

例子: 假设我们想绕着z轴旋转一个φ弧度的对象,并且旋转中心是某个点p。 什么是转换? 图4.2中描述了这种情况。 由于绕点旋转的特征在于该点本身不受旋转的影响,因此变换首先通过平移对象使p与原点重合开始,这是通过T(-p)完成的。 此后跟随实际旋转:Rz(φ)。 最后,必须使用T(p)将对象平移回其原始位置。 然后,得到的变换X由下式给出

X = T(p)Rz(φ)T(-p)。

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

4.1.3 Scaling 缩放

缩放矩阵S(s)= S(sx,sy,sz)分别沿x,y和z方向缩放因子为sx,sy和sz的实体。 这意味着可以使用缩放矩阵来放大或缩小对象。 si(i∈{x,y,z})越大,则按比例缩放的实体在该方向上越大。 将s的任何分量设置为1自然可以避免在该方向上缩放比例发生变化。 公式4.10显示S:

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

4.1.4 Shearing 剪裁

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

4.1.5 Concatenation of Transform 转换的级联

由于矩阵的乘法运算具有不可交换性,因此矩阵出现的顺序很重要。 因此,变换的级联被认为是顺序相关的。

作为一个顺序相关性的示例,考虑两个矩阵S和R。S(2,0.5,1)将x分量缩放2倍,将y分量缩放0.5倍。 Rz(π/ 6)绕z轴逆时针旋转π/ 6弧度(在右手坐标系中从本书的页面向外指向)。 这些矩阵可以用两种方法相加,结果完全不同。 这两种情况如图4.4所示。

将一系列矩阵连接成单个矩阵的明显原因是为了提高效率。 例如,假设您的游戏场景具有数百万个顶点,并且场景中的所有对象都必须缩放,旋转并最终平移。 现在,不是将所有顶点与这三个矩阵中的每一个相乘,而是将这三个矩阵连接到一个矩阵中。 然后将此单个矩阵应用于顶点。 该复合矩阵为C = TRS。 注意这里的顺序。 比例矩阵S应该首先应用于顶点,因此在合成中显示在右侧。 该排序意味着TRSp =(T(R(Sp))),其中p是要转换的点。 顺便说一句,TRS是场景图系统常用的顺序。

值得注意的是,虽然矩阵级联是依赖于顺序的,但是矩阵可以根据需要进行分组。 例如,假设使用TRSp,您只需计算一次刚体运动变换TR。 将这两个矩阵(TR)(Sp)分组在一起并用中间结果替换是有效的。 因此,矩阵级联是关联的。

4.1.6 The Rigid-Body Transform 刚体变换

​ 当一个人抓住一个坚固的物体时,例如从桌子上用笔将其移动到另一个位置,也许移动到衬衫的口袋里,只有物体的方向和位置会发生变化,而物体的形状通常不会受到影响。 这种仅由平移和旋转的串联组成的变换称为刚体变换。 它具有保留长度,角度和惯用性的特性。

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

例子:

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

对准相机:图形中的常见任务是调整相机的方向,使其对准特定位置。在这里,我们将介绍gluLookAt()(来自OpenGL Utility Library,简称GLU)的作用。即使现在很少使用此函数调用,该任务仍然很常见。假设摄像机位于c处,我们希望摄像机看着目标l,并且摄像机的给定方向为u’,如图4.5所示。我们要计算一个由三个向量{r,u,v}组成的基础。我们首先以v =(c − l)/ ||| c − l ||计算视点矢量,即从目标到摄像机位置的归一化矢量。然后可以将向右看的向量计算为r = −(v×u’)/ || v×u’||。通常不能保证u’向量正好指向上,因此最终的向上向量是另一个叉积u = v×r,由于v和r都通过构造进行了归一化和垂直处理,因此可以保证归一化。在我们将构建的相机变换矩阵M中,其思想是首先转换所有内容,使相机位置位于原点(0,0,0),然后更改基数,以使r与(1 ,0,0),u(0、1、0)和v(0、0、1)。这是通过

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

4.1.7 Normal Transform 正态变换

单个矩阵可用于一致地变换点,线,三角形和其他几何形状。 同一矩阵还可以沿这些线或在三角形的曲面上变换切向量。 但是,此矩阵不能始终用于变换一个重要的几何特性,即表面法线(和顶点照明法线)。 图4.6显示了如果使用相同的矩阵会发生什么。

适当的方法不是使用矩阵本身乘以,而是使用矩阵的伴随项的转置[227]。 伴随的计算在我们的在线线性代数附录中进行了描述。 伴随关系始终保证存在。 规范不保证变换后具有单位长度,因此通常需要将其标准化。

转换法线的传统答案是计算逆矩阵的转置[1794]。 此方法通常有效。 但是,完全逆不是必需的,并且有时无法创建。 逆是伴随数除以原始矩阵的行列式。 如果该行列式为零,则矩阵是奇异的,并且不存在逆。

即使只计算一个完整的4×4矩阵的伴随,也可能很昂贵,并且通常没有必要。 由于法线是矢量,因此翻译不会对其产生影响。 此外,大多数建模转换都是仿射的。 它们不更改传入的齐次坐标的w分量,即不执行投影。 在这些(常见)情况下,正常变换所需的全部是计算左上3×3分量的伴随。

4.2特殊矩阵变换和运算

在图形学编程里,都是用四元数来表示一个顶点,下面两节介绍了为什么用四元数而不是三元数。

在本节中,将介绍和导出对实时图形必不可少的几种矩阵变换和运算。 首先,我们介绍欧拉变换(及其参数提取),这是描述方向的直观方法。 然后,我们谈到从单个矩阵中检索一组基本变换。 最后,推导了一种绕任意轴旋转实体的方法。

4.2.1 欧拉变换

这种转换是构造矩阵以将自己(即摄像机)或任何其他实体定向到某个方向的一种直观方法。 它的名字来自伟大的瑞士数学家莱昂哈德·欧拉(Leonhard Euler,1707–1783)。

首先,必须建立某种默认的视图方向。 如图4.7所示,它通常沿负z轴放置,头部沿y轴放置。 欧拉变换是三个矩阵的乘积,即图中所示的旋转。 更正式地说,表示为E的变换由下式给出

E(h,p,r) = Rz®Rx§Ry(h).

本质思想是把物体的旋转(在图形学中的应用比如相机的旋转)分解为绕三个互相垂直轴(x,y,z)的三个旋转组成的序列。

矩阵的顺序可以以24种不同的方式选择[1636];这可以通过选择矩阵的顺序来实现。 我们介绍这个是因为它是常用的。 由于E是旋转的级联,因此它也显然是正交的。 因此,它的逆可以表示为

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换
Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

尽管当然,更容易直接使用E的转置。欧拉角h,p和r表示头,俯仰和横滚应以哪种顺序以及绕其各自的轴旋转多少。 有时,所有角度都称为“侧倾”,例如,我们的“头”为“ y侧”,而我们的“俯仰”为“ x侧”。 同样,“头部”有时也称为“偏航”,例如在飞行模拟中。

这种转换很直观,因此很容易用外行的语言进行讨论。 例如,改变头角度会使观看者摇头“否”,改变音高会使他们点头,而滚动则会使他们的头向侧面倾斜。 与其谈论绕x轴,y轴和z轴的旋转,不如谈论改变头,俯仰和横滚。 请注意,此变换不仅可以定向摄影机,还可以定向任何对象或实体。 可以使用世界空间的全局轴或相对于局部参考系执行这些变换。

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

重要的是要注意,一些欧拉角的表示将z轴作为初始向上方向。 这种差异纯粹是一种符号上的变化,尽管可能会造成混淆。 在计算机图形学中,如何看待世界以及如何形成内容有一个区分:y向上或z向上。 大多数制造工艺(包括3D打印)都认为z方向在世界范围内是向上的。 航空和海上交通工具认为-z上升。 建筑和GIS通常使用z-up,因为建筑平面图或地图是二维的x和y。 与媒体相关的建模系统通常将y方向视为世界坐标上的向上方向,以匹配我们始终在计算机图形学中描述相机的屏幕向上方向的方式。 这两个世界矢量选择之间的差异仅相差90°旋转(并且可能是反射),但不知道假定哪个会导致问题。 在本卷中,除非另有说明,否则我们使用y向上的世界方向。

我们还想指出,相机在其视野中的向上方向与世界的向上方向没有特别关系。 转动头,视野就会倾斜,其世界空间向上方向与世界方向不同。 再举一个例子,假设世界使用y-up,而我们的相机则直视下方的地形,鸟瞰。 此方向表示相机已向前倾斜90o,因此其在世界空间中的向上方向为(0,0,−1)。 在这种方向上,相机没有y分量,而是认为-z在世界空间中向上,但根据定义,“ y在上方”在视图空间中仍然适用。

欧拉角虽然适用于较小的角度变化或观看者方向,但还有其他一些严重的限制。 很难同时使用两组欧拉角。 例如,在一组和另一组之间进行插值并不是对每个角度进行插值的简单问题。 实际上,两组不同的欧拉角可以给出相同的方向,因此任何插值都不应旋转对象。 这些是使用本章稍后讨论的替代方向表示形式(例如四元数)值得追求的一些原因。 使用欧拉角,您还可以获得称为万向锁,将在第4.2.2节中对其进行说明。

4.2.2 Extracting Parameters from the Euler Transform 从Euler变换中提取参数

当您使用Euler变换时,可能会发生万向锁,当发生万向锁的之后,再发生旋转的时候,会失去了一个自由度。

例如,假设转换顺序为x / y / z。 考虑绕π/ 2旋转,只是y轴,这样做会将本地z轴旋转为与原始x轴对齐,因此围绕z的旋转消失了。

欧拉角在建模中通常以x / y / z顺序表示围绕每个局部轴的旋转,其他排序是可行的。 例如,z / x / y用于动画,z / x / z用于动画和物理。 对于某些应用最后一个z / x / z可能更好,仅当绕x旋转π弧度时(半旋转)。

但没有一个完美的序列可以避免万向锁发生。尽管如此,欧拉还是经常被使用,因为动画师更喜欢曲线编辑器来指定角度如何随时间变化。

关于万向锁,

可以参考这个视频:

“欧拉角旋转”产生“万向锁”的来源,以及如何避免万向锁

4.2.3矩阵分解

到目前为止,我们一直在假设我们知道所使用的变换矩阵的起源和历史的情况下进行工作。 通常情况并非如此。

例如,仅将级联矩阵与某个变换后的对象相关联。 从级联矩阵中检索各种变换的任务称为矩阵分解。

检索一组转换的原因很多。 用途包括:

•仅提取对象的比例因子。

•查找特定系统所需的转换。 (例如,某些系统可能不允许使用任意4×4矩阵。)

•确定模型是否仅经历了刚体变换。

•在动画的关键帧之间进行插值,其中仅用于对象可用。

•从旋转矩阵上移除剪子。

我们已经提出了两种分解方法,即推导用于刚体变换的平移和旋转矩阵(第4.1.6节)和从正交矩阵推导Euler角(第4.2.2节)。

如我们所见,转换矩阵很简单,因为我们只需要4×4矩阵的最后一列中的元素。 我们还可以通过检查矩阵的行列式是否为负来确定是否发生了反射。 要分离出旋转,缩放和剪切需要花费更多的精力。

幸运的是,有几篇关于该主题的文章以及在线提供的代码。 托马斯[1769]和戈德曼[552,553]各自针对不同类型的转换提出了一些不同的方法。 Shoemake [1635]改进了他们的仿射矩阵技术,因为他的算法与参考系无关,并尝试分解矩阵以获得刚体变换。

4.2.4绕任意轴旋转

有时,使用使实体绕任意轴旋转某个角度的过程会很方便。 假设旋转轴r已归一化,并且应该创建一个围绕r旋转α弧度的变换。

为此,我们首先变换到一个空间,我们要围绕其旋转的轴是x轴。 这是通过一个称为M的旋转矩阵完成的。然后执行实际旋转,然后使用M-1变换回[314]。 此过程如图4.8所示。

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

我们create了一个旋转矩阵,如下,此矩阵将向量r转换为x轴,将s转换为y轴,将t转换为z轴。

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

因此,围绕标准化向量r旋转α弧度的最终变换成

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换
Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

4.3 Quaternions 四元数

因为三元数有万向锁的问题,所以引入了四元数表示一个顶点

Real-Time Rendering读书笔记 第四章: Transforms 变换 (未完成)第四章 Transforms 变换

公式太多,知乎上有人翻译过,直接贴一下链接:

https://zhuanlan.zhihu.com/p/97186723

有个视频介绍

四元数的可视化

4.4 Vertex Blending 顶点混合

想象一下,数字角色的手臂使用前臂和上臂两部分进行动画处理,如图4.11左侧所示。 该模型可以使用刚体变换进行动画处理(第4.1.6节)。 但是,这两个部分之间的关节将不会像真正的肘部。 这是因为使用了两个单独的对象,因此,关节由来自这两个单独的对象的重叠部分组成。 显然,最好只使用一个对象。 但是,静态模型零件无法解决使接头具有柔性的问题。

顶点混合是解决此问题的一种流行方法[1037,1903]。该技术还有其他几个名称,例如线性混合蒙皮,包络或骨架子空间变形。尽管此处介绍的算法的确切来源尚不清楚,但定义骨骼并让皮肤对变化做出反应是计算机动画中的一个古老概念[1100]。在最简单的形式中,前臂和上臂像以前一样分别进行动画处理,但是在关节处,两个部分通过有弹性的“皮肤”相连。因此,该弹性部件将具有一组由前臂矩阵转换的顶点和另一组由上臂矩阵转换的顶点。与每个三角形使用单个矩阵相比,这会导致三角形的顶点可以通过不同的矩阵进行变换。见图4.11。

通过进一步执行此步骤,可以使单个顶点可以由几种不同的矩阵进行变换,并将得到的位置加权并混合在一起。 这是通过为动画对象设置骨骼骨骼来完成的,其中每个骨骼的变换可能会通过用户定义的权重影响每个顶点。 由于整个手臂可能是“弹性的”,即所有顶点可能受到一个以上矩阵的影响ß,因此整个网格通常称为皮肤(在骨骼上)。 见图4.12。 许多商业建模系统具有相同的骨架骨骼建模功能。 尽管名称如此,骨骼并不一定必须是刚性的。 例如,Mohr和Gleicher [1230]提出了添加附加关节以实现诸如肌肉隆起等效果的想法。 James和Twigg [813]讨论了使用可以挤压和拉伸的骨骼的动画蒙皮。

4.5 Morphing : 变形

在执行动画时,从一个三维模型变形到另一个三维模型可能会很有用。 假设一个模型在时间t0显示,我们希望它在时间t1变成另一个模型。 对于介于t0和t1之间的所有时间,都使用某种插值获得了连续的“混合”模型。 变形的一个例子如图4.14所示。

变形涉及解决两个主要问题,即顶点对应问题和插值问题。 给定两个任意模型,它们可能具有不同的拓扑,不同数量的顶点以及不同的网格连接,通常必须从建立这些顶点对应关系开始。 这是一个困难的问题,并且在该领域已经进行了很多研究。 我们推荐感兴趣的读者阅读Alexa的调查。

但是,如果两个模型之间已经存在一对一的顶点对应关系,则可以在每个顶点的基础上进行内插。 也就是说,对于第一个模型中的每个顶点,在第二个模型中必须仅存在一个顶点,反之亦然。 这使插值变得容易。 例如,线性插值可以直接在顶点上使用(有关插值的其他方法,请参见第17.1节)。 为了计算时间t∈[t0,t1]的变形顶点,我们首先计算s =(t-t0)/(t1- t0),然后线性顶点混合,

4.6 Geometry Cache Playback. 几何缓存播放

​ 在剪辑场景中,可能希望使用极高质量的动画,例如,对于无法使用上述任何方法表示的运动。简单的方法是存储所有帧的所有顶点,从磁盘读取它们并更新网格。但是,对于短动画中使用的30,000个顶点的简单模型,这可能达到50 MB / s。 Gneiting [545]提出了几种将内存成本降低到大约10%的方法。

首先,使用量化。例如,位置和纹理坐标使用每个坐标的16位整数存储。在执行压缩后无法恢复原始数据的意义上,这一步骤是有损的。为了进一步减少数据,进行了空间和时间预测,并对差异进行了编码。对于空间压缩,可以使用平行四边形预测[800]。对于三角形带,下一个顶点的预测位置就是在当前三角形边缘周围的三角形平面中反射的当前三角形,从而形成平行四边形。与这个新位置的差异然后被编码。有了良好的预测,大多数值将接近零,这对于许多常用的压缩方案是理想的。与MPEG压缩类似,在时间维度上也进行预测。即,每n帧执行一次空间压缩。在这两者之间,将在时间维度上进行预测,例如,如果某个特定顶点通过增量矢量从帧n-1移动到帧n,则很可能以与帧n + 1相似的量移动。这些技术减少了存储量足以使该系统可用于实时流数据。

4.7 Projection: 投影

4.7.1 Orthographic Projection 正投影

正投影投影的一个特征是,平行线在投影之后保持平行。 当使用正射投影观看场景时,无论与相机的距离如何,对象都保持相同的大小。 矩阵Po,如下所示,是一个简单的正交投影矩阵,它使一个点的x和y分量保持不变,而将z分量设置为零,即正交投影到平面z = 0上:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-exFvtyIU-1597571129046)(/Users/yangrong/Library/Application Support/typora-user-images/image-20200815154415990.png)]

4.7.2 Perspective Projection 透视投影

透视投影比正交投影更复杂的变换是透视投影,它通常在大多数计算机图形应用程序中使用。 在此,平行线在投影后通常不平行;相反,在投影之后平行。 相反,它们可能会在极端情况下收敛到单个点。 透视更紧密地匹配我们如何感知世界,即,更远的物体更小。

首先,我们将对投影到平面z = -d,d> 0上的透视投影矩阵进行有益的推导。我们从世界空间中推导,以简化对世界视图转换的理解。 此推导之后是例如OpenGL中使用的更常规的矩阵

​ 假设摄像机(视点)位于原点,并且我们要将一个点p投影到平面z = -d,d> 0,从而产生一个新点q =(qx,qy,-d) 。 图4.19描绘了这种情况。 从该图所示的相似三角形中,得出q的x分量的以下推导:

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8evn43sD-1597571129047)(/Users/yangrong/Library/Application Support/typora-user-images/image-20200816172357224.png)]