坐标系的概念和坐标系之间的变换
坐标系是建立图形与数之间对应联系的参考系。它可以直观方便的描述图形的几何信息、大小、位置。
在计算机图形学中,从对象的建模,到在不同显示设备上显示、处理图形时会使用一系列的坐标系。例如:在屏幕上,会使用像素构成的二维坐标系来表示图形的像素值。
对于一个给定的场景,我们通常并不是按照像素坐标来考虑。我们要考虑屏幕适配、组件复用、软件跨平台等等一系列工程化问题。因此,我们希望将程序中用于描述对象几何信息(形状,拓扑结构)的数值,和那些用于描述对象中大小和位置的数值区分开来。
前者通常被看作一个建模(moduling)的任务,后者是一个观察(viewing)的任务。
例如,教室里一张桌子,我们需要从不同距离和角度去描绘,并显示到屏幕。针对这个问题,我们当然可以把每次“建模-观察”的结果一一绘制到屏幕上。但是,我们需要注意到在这个过程中,桌子的几何信息客观上是固定不变的。因此,我们可以把“建模”的任务和“观察”的任务分离开来,每次绘制只需要改变观察任务的的数值即可。
当我们把“建模”与“观察”分开后,产生一个新的问题,即多坐标系问题。不同的坐标系具有它存在的必要性。
为了方便“建模”,我们给每一个建模任务构建一个自己的坐标系,叫做建模坐标系。同时,为了方便“观察”,我们也给每一个观察任务构建一个观察坐标系。为了完成某一次图形的显示,我们需要建立相应“建模”任务和相应“观察”任务的适当的映射关系,因此产生了世界坐标系的概念。为了使得计算机图形能够在特定的屏幕上正确显示,我们需要知道特定屏幕的屏幕坐标系,即设备坐标系。为了使得计算机图形能够在不同屏幕上正确显示,我们又定义了规范化坐标系。另外,对于一个大场景,我们可能只关注某一局部。因此,产生了裁剪坐标系。
在系统(场景)中用于描述其他坐标系位置和对象模型位置的参考坐标系,被称为 世界坐标系 。
在我的理解中,世界坐标系是一个特定场景中全局的、绝对的公共参照系。
注意这句话,“全局的”、“绝对的”,都是在我们所关心的特定的场景中,这个特定场景很多情况下并非真实世界或者宇宙,它可能是一间房,一个虚拟的游戏世界。
用于描述对象的几何信息的独立于世界坐标系的参照系,叫做 建模坐标系 。
建模坐标系又被称为局部坐标系。一旦定义了“局部”(相对于上面提到的世界坐标系的全局)的对象,就可以很容易地将“局部”对象放入世界坐标系中,使它由局部升为全局。
观察坐标系主要用于从观察者的角度对整个世界坐标系中的对象进行重新定位和描述。
依据观察窗口的方向和形状在世界坐标系中定义的坐标系被称为 观察坐标系 。
观察坐标系用于指定图形的输出范围。
对于世界坐标系来说,观察坐标系其实是一种特殊的建模坐标系。
适合特定输出设备输出对象的坐标系叫做 设备坐标系 。比如屏幕坐标系。
在多数情况下,每一个具体的显示设备,都有一个单独的坐标系统。
规范化坐标系独立于设备,能够很容易地转变为设备坐标系,是一个中间坐标系。
为使图形软件能在不同设备之间移植,采用规范化坐标系,其坐标轴取值范围是[-1, 1]或[0, 1]。
前面提到,对于给定的问题,我们大致分为“建模”和“观察”两个任务。对于一个给定的对象模型,我们已知它在建模坐标系下的坐标,我们如何在观察坐标系下得到该对象的定位和描述。
像这种已知对象在一个坐标系的坐标,要获得该对象在另一坐标系下的坐标,我们把这一过程叫做 坐标转换 。而这个过程离不开世界坐标系,因为世界坐标系决定了建模坐标系与观察坐标系的映射关系。
需要注意,坐标转换过程中,对象的实际位置和状态并未发生改变,我们仅仅是使用了不同的坐标系描述对象的位置。
例下图,在一个世界坐标系 中,一个点 在建模坐标系 中的坐标为 。现在得到观察坐标系 中 点的坐标。
从图中,我们可以很容易的得出,点 在观察坐标系 中的坐标为 。然而,在实际问题中,我们不可能总能通过观察得出新的坐标,这就需要通过变换计算得到。
就这个问题,我们先要得到建模坐标系 到观察坐标系 的变换矩阵R:
可以看到,坐标系A先平移向量 ,再平移向量 ,最后基于Y轴反射 得到坐标系B(实际应用中,连续的相同变换操作可以合并,如这里的连续平移可以合并为 ,这里为了更清晰表示变换过程—— ,将其拆分出来)。代入式(1)得到:
所以,由式(2)可知 基变换矩阵:
由式(3)可得坐标变换矩阵 :
则,点P在坐标系B中的坐标 为:
同样的,我们可以得出 的基变换矩阵 为:
他恰好就是 的坐标变换矩阵。因此,我们要求 的坐标变换矩阵就可以改为求 的基变换矩阵,可以少一次矩阵的逆运算。
通过这个示例,我们可以得出一个结论, 计算机中,图形的显示过程就是几何(对象)模型在不同坐标系之间的映射变换。
在图中我们可以观察到, 可以先经过两次平移,再经过一次反射得到,记作 ,也可以是先经过一次反射再经过两次平移得到,记作 ,或者更多的变换组合……,但结果肯定是惟一的。
我们尝试将式(2)中的 与 交换顺序以实现变换 :
得到的结果是:
这与式(3)的结果不一致,因为矩阵点乘一般不满足交换律。可是,这与我们观察到的 和 都可行的结果不一致。
其实 和 两种变换顺序都没有问题,只不过我们观察变换 时采用的的参考系出了问题。
的所有变换操作都隐藏了一个前提:基于目标坐标系(变换操作的参照系)原点的变换。如 实际应该是:
而 中第一步的反射并非基于世界坐标系 轴的变换,而是基于 的反射,所以应该先平移 ,再做反射操作。正确的表达式是:
修正后的变换过程我们记作 。
可以看到,结果与式(3)相同。
虽然 和 都可以得到正确的结果,但是为了防止出现如 一般的错误或为了减少计算量,在 连续不同坐标系变换 过程中,我们应该始终以 本次变换的目标坐标系 作为参考系进行先平移后作线性变换。