2023-01-07 更新
原著用 5 章讲述的内容,其中绝大部分在我们念中学时就已经学过了。笔记不多,合成一页。
1 坐标
选择精度时请参考计算机图形学第一原则——近似原则:
如果它看上去是对的,那么它就是对的。
2D 坐标系都是等价的,而 3D 坐标系不一定是,3D 坐标系有左右手之分。注意手指与坐标轴的对应关系,拇指、食指和其余手指分别代表 x 、 y 、 z 轴的正方向。只需翻转一个轴,就能实现左右手系的变换,同时翻转两个轴与不翻转的效果一样。3D 空间有 8 个卦限,每个卦限又有 6 种姿势,因此 3D 坐标系共有 48 种组合。
常用的 3D 坐标系有:
- 世界坐标系是囊括我们关心的所有物体的最大坐标系,它不必是整个世界,通常用于设定全局环境和初始位置。
- 模型坐标系是仅与特定物体关联的坐标系,通常用于自身的运动。
- 摄像坐标系的作用是世界坐标系中特定视角所见内容投影到屏幕上,左手系 z 轴指向屏幕内,右手系指向使用者。
- 惯性坐标系是模型坐标系到世界坐标系转换的中间结果,原点位于模型坐标系原点,坐标轴平行于世界坐标系。
模型坐标系在世界坐标系中运动,具有天然的父子关系。
2 向量
重点关注一下零向量。虽然在图中表示零向量用的是一个点,但是认为零向量就是一个点并不准确,因为零向量没有定义位置,所以零向量表示“没有位移”,零标量表示“没有数量”。向量与自身的叉乘等于零向量。
3D 向量类的设计决策:
- float 的精度够用了。
- 不要将 x 、 y 、 z 搞成数组用下标访问。
- 只重载 4 个运算符:乘除标量、求反、加减向量、点乘向量。
- 不要重载大于小于,因为很少用到,不如定义非成员函数。
- 不要重载分量乘除,因为很少用到,不如定义非成员函数。
- 不要为求模重载运算符,没有任何理由。
- 不要为叉乘重载运算符,没有多余符号。
- 默认构造函数要么不执行任何初始化操作,要么初始化为零向量。
- 零向量声明为全局常量。
- 不要使用虚函数。
- 不要使用
getX()
、setX()
之类的函数,全部公开。 - 不存在 Point3 类,点就是向量,向量就是点。
没有证据证明对向量类的优化能显著提高性能。在浮点数乘法非常慢的年代,程序员曾用过一种叫做“定点数”的优化技术,先在定点数里保存小数位,再将浮点数调成整数计算,当然现在已经用不着了。返回类对象的确会影响性能,但它不值得我们为此付出高昂的时间成本。