scratchapixel翻译 几何学 点,向量和法线

马铃薯
发布于

几何学是数学的一个分支,涉及形状、大小、图形的相对位置和空间的特性等问题

对于大多数读者来说,这一课将是冗长乏味的。如果你是计算机图形学的新手,请花时间仔细阅读。了解CG管道的这一部分至关重要,这将为您以后节省大量时间。

几何概论

点、向量、矩阵和法线对于计算机图形来说就像字母表对于文学一样;因此,大多数CG书都是从线性代数和几何一章开始的。然而,对于许多想要学习图形编程的人来说,在学习图形学之前先介绍大量的数学知识可能会非常令人沮丧。所以,如果你不认为CG编程适合你,因为你对数学不熟悉或者不理解矩阵是什么,那么现在就不要放弃。

我们从“3D渲染基础”部分开始,讲了一些不需要任何线性代数知识的课程。虽然这是一种相对非传统的教学CG编程技术的方式,更令人兴奋的是,你可以开始一些实用和有趣的东西:一个入门级的光线跟踪器,它只需要很少的数学知识和一些编程知识。编写渲染器是一种更加令人兴奋和有益的学习数学的方式,因为您可以逐步看到某些东西是如何被用来产生具体结果的(即,您的最终图像)。也就是说,点、向量和矩阵是制作CG图像的工具;我们将在每节课中广泛使用它们。

在本课中,您将了解这些构造是什么、它们是如何工作的,以及可以用来操纵它们的各种技术。本课还将解释CG研究人员多年来在解决问题和编写代码时使用的线性代数中的不同约定。您需要了解这些约定,因为它们通常在书中没有提及(在网络上也是)。然而,这些公约是必不可少的;在阅读或使用其他开发人员的代码或技术之前,必须检查他们的约定。

在我们开始之前,请注意一点。如果你是一个数学纯粹主义者,你可能会发现这里解释的东西在技术上与线性代数无关,这很奇怪。我们希望本课的范围保持广泛,并包括CG中常用的简单数学技术,这些技术可能仅与向量和矩阵相关。例如,从数学上讲,点与线性代数(数学的一个分支,只涉及向量)无关。我们选择使用点,因为它们在CG中无处不在(并且可以使用线性代数中的相同数学技术来处理它们)。如果您仍然需要了解点和向量之间的区别,请不要担心。我们将在本章中详细介绍这一点。

什么是线性代数?向量介绍

那么什么是线性代数,我们将在本课中学习什么?正如我们在上一节中提到的,线性代数是与向量研究有关的数学分支。现在您可能会问,“什么是矢量,它在 CG 世界中有什么用?” 我们不会详细介绍,但是向量可以表示为一组数字数组。这个数组可以采用任何所需的长度,有时在数学中也称为元组。如果我们想要具体说明向量的大小,我们可以选择说 n 元组,其中 n 表示向量中元素的数量。下面是一个包含 6 个元素的向量的数学符号示例:

V = (a, b, c, d, e, f).

其中 a、b、c、d、e、f 是实数(1、3、4.56、-11、-13.08、0 等)。

将这些数字分组背后的想法是,它们共同代表了另一个在问题上下文中有意义的值或概念。 例如,在计算机图形学中,矢量可以表示空间中的位置或方向。 我们还将能够通过一系列非常强大和紧凑的操作来转换(或修改)这些向量。 转换向量内容的过程是通过所谓的线性转换来实现的。 我们将在后面的部分花更多时间讨论转换; 现在,只需要承认它们是有用的。

点和向量

点和矢量用于多个科学领域。 在本课中,我们将在计算机图形学的背景下解释它们的含义。一个点是三维空间中的位置。 另一方面,矢量通常是指在三维空间中的方向(以及一些相应的量级或大小)。 向量可以被认为是指向各种方向的箭头。 三维点和向量相似,因为它们都由上述元组表示法表示。

V = (x, y, x).

同样,(x,y,z)是实数。

图1:一个点描述了空间中的位置。 向量可以看作是一个方向。

请记住,当与数学家或物理学家交谈时,他们对向量或点的理解可能会更加笼统。 它们不一定仅限于我们在CG中对它们的使用。 对于他们来说,向量可能是任意的甚至是极大的的(这意味着它可以包含根据需要的数量)。

我们将简要提及齐次坐标(homogeneous points)来完成本章。 有时,有必要为数学便利添加第四个要素。 下面给出了齐次坐标点的一个示例:

P_H=(x, y, z, w).

当涉及使用矩阵乘数时,使用齐次坐标点。 在这篇文章中国呢,不要考虑太多。 我们现在提到齐次坐标,因为它们有时会出现在文献中,并且会使读者感到困惑。 他们将在本课程的稍后详细解释。

快速介绍变换

您可能仍然想知道线性变换是如何影响点和向量的。这很简单。我们对CG中的点执行的最常见的操作之一是简单地在空间中移动它们。这种转换称为平移,在渲染中起着至关重要的作用。

平移是原始点(可被视为输入位置点)的线性变换。平移应用于向量(记住,向量是一个方向)时没有意义。这是因为向量的开始位置(即它的起点位置)不重要;无论位置如何,所有长度相同、指向相同方向的“箭头”都是等效的。相反,我们通常在向量上使用另一种线性变换:旋转。可以使用许多更常见的运算符,但让我们考虑点的平移和向量的旋转。

P -> Translate -> P_T

V -> Rotate -> V_T

字母T代表“转换”。

您可能已经注意到,我们尚未讨论向量的长度或大小的含义。 确实,向量的长度在CG中非常重要。 当向量的长度精确为1时,我们说向量已归一化(您会一直听到并读取此术语)。 使向量归一化涉及改变向量使其长度变为1,但其方向保持不变。 在大多数情况下,我们将希望我们的向量进行归一化标准化。 但是,在某些情况下,由于向量的长度有意义,因此不将其归一化。

例如,假设你追踪一条从A点到B点的线。创建的线是一个向量,指示A点到B点的位置。它给出了B的方向,就好像你站在A点看向B点。在这种情况下,向量的长度指示A到B的距离。有的时候需要这个距离。

向量的归一化通常是应用程序中bug的来源。因此,每次您声明一个向量(甚至使用一个向量)时,我们建议您有意识地问自己这个向量是不是或应该不应该被归一化。

图2:法线垂直于平面切线。

法线是计算机图形学(和几何学)中的一个技术术语,用于描述几何物体表面上某一点的方向。从技术上讲,点P处的表面法线可以被看成垂直于表面切线的向量。法线在着色中起着重要作用,用于计算对象的亮度(请参见有关灯光和着色的进一步课程)。

法线可以被认为是向量,但它们的变换方式与向量不同。这是我们花时间区分它们的主要原因之一。您将在变换法线一章中找到有关此主题的详细信息。目前,了解它们是什么才是最重要的。

从理论到C++

在C++代码中,我们不会区分点、向量和法线;我们用Vec3类(一个模板类,以便我们可以根据需要创建float、int或double版本)来表示这三个类。一些开发人员更喜欢区分它们。这限制了出错的可能性。根据经验,我们发现处理一个唯一的类(就像OpenEXR库那样)更有效(首先编写的代码更少)。然而,我们仍然需要仔细调用一些特定的函数,这取决于我们正在处理的Vec3是否代表点、向量或法线。您可能还记得,当我们使用转换时,这一点尤为重要。本课程的下载部分提供了完整的源代码。

template<typename T> 
class Vec3 
{ 
public: 
    // 3 most basic ways of initializing a vector
    Vec3() : x(T(0)), y(T(0)), z(T(0)) {} 
    Vec3(const T &xx) : x(xx), y(xx), z(xx) {} 
    Vec3(T xx, T yy, T zz) : x(xx), y(yy), z(zz) {} 
    T x, y, z; 
}; 
typedef Vec3<float> Vec3f; 
Vec3<float> a; 
Vec3f b;

总结

从第一章开始,你应该记住,在数学上,向量可以是任何维度。然而,在CG中,我们使用了更具体的定义:向量是3D空间中的方向(因此由三个数字表示)。此外,我们将点作为位置的表示(也在3D空间中,由三个数字表示)。齐次点用四个数字表示,但这是我们稍后将研究的一个特殊情况。

可以使用线性变换来变换点和向量。

您将看到经常使用的术语线性变换。例如,如果线在变换时保持不变,那么我们就称之为线性变换(乘以矩阵就是线性变换)。

这种变换的典型示例是点的平移和向量的旋转。向量的长度可以设置为1,在这种情况下,我们说它是归一化的。向量的长度(在归一化之前)表示两点之间的距离,有时在特定算法中需要。因此,开发人员必须小心何时以及为什么可能选择归一化向量。

下一步是什么?


我们仍然需要解释的一件重要事情是,定义点和向量的三个数字代表什么。这些数字表示点(在2D或3D空间中)相对于参考(有时也称为原点)的坐标。这个参考,我们技术上称之为坐标系,是我们下一章的主题。

10
评论 2
收藏 3
  • skycode
    新手认真学习中,期待下一课
    1
  • MR7
    MR7
    感谢将译文发布到Piccolo社区,翻译不易,期待下篇。