CG中的仿射(affine transformation)和法线变换

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CG中的仿射(affine transformation)和法线变换相关的知识,希望对你有一定的参考价值。

参考技术A

这是对 MIT Foundation of 3D Computer Graphics 第3章的翻译,本章讲解了仿射变换的基本概念,变换矩阵的由来以及分解、通用法线变换的推导等内容。本书内容仍在不断的学习中,因此本文内容会不断的改进。若有任何建议,请不吝赐教 ninetymiles@icloud.com

已经完成的章节

将点和矢量看作是两种不同的概念是有用的。点表示在几何世界中的某种固定位置,而矢量表示世界中两个点之间的运动。我们会使用两种不同的标记区分点和矢量。矢量 会有一个箭头在顶部,而点 会有波浪线在顶部。

如果我们认为矢量表达两点之间的运动,那么矢量操作(加法和标量乘法)就有明确的意义。如果我们把两个矢量加起来,我们在表达两个运动的串接(concatenation)。如果我们用一个标量乘以矢量,我们就在通过某个因子增加或减少运动。零矢量(zero vector)为一个特别矢量,其代表没有运动。

这些操作对于点不会真正产生任何意义。把两个点加起来应该表示什么含义,比如说,哈佛广场加上剑桥肯德尔广场(这里是两个地点名称)是什么?一个点被一个标量相乘又指得什么?什么是北极点的7倍?是否存在一个零点(zero point)和其它点的行为不一样?

存在一种在两个点之间确实有意义的操作:减法。当我们从另一个点减去一个点,我们应该会得到从第二个点到第一个点路径之间的运动,

反过来说,如果我们从一个点开始,然后移动一个矢量(位移),我们应该会到达另一个点。

对一个点应用线性变换同样有意义。例如我们可以想象一个点围绕某个固定原点的旋转。而且平移点也是有意义的(但是这个概念对于矢量没有任何意义)。要表达平移,我们需要开发仿射变换(或并行变换 affine transformation)的概念。要完成这个任务,我们借助 矩阵。这些矩阵不仅对于处理本章的仿射(并行)变换很方便,而且对于描述(随后在第十章会看到的)相机投射变换也是很有帮助。

在仿射空间(affine space)中,我们描述任何点 首先从某个原点 开始,然后给其加上一个矢量的线性组合。这些矢量使用坐标 和一个矢量基(basis of vectors)来表示。


此处 被定义为 。

而下面这行表达

被称为一个仿射帧(affine space);它就像一个基(basis),但是由3个矢量和一个点组成。

为了借助一个帧指定一个点,我们使用拥有4个条目(entries)的4部件坐标矢量(coordinate 4-vector),其中最后一个条目总为1。要借助一个帧表达一个矢量,我们使用一个让0作为第4坐标的坐标矢量(也就是说,它只是基矢量之和)。当我们建模针孔相机的行为时,要表达几何形状(还有 矩阵),4部件坐标矢量的使用都会很便利。

相似于线性变换的情形,我们想要通过在一个4部件坐标矢量和一个帧之间放置一个合适的矩阵的形式,来定义出仿射变换的概念。

让我们将仿射矩阵定义为一个如下形式的 矩阵

然后我们对一个点 应用仿射变换如下

或者简写为

我们可以验证上面表达的第二行描述了一个有效的点,因为乘法

给出了我们一个带有1作为第4条目的4部件坐标矢量。另一方面,我们也能够看到乘法

此处 被定义为 ,给出了一个由3个矢量和一个原点组成的有效帧。

同时也要注意到,如果矩阵的最后一行不是 这种形式,变换就通常给出一个无效的结果。

类似于线性变换的情形,我们可以针对一个帧应用仿射变换(affine transformation)为

或者简写为

假如我们有一个表达线性变换的 矩阵。我们可以将其嵌入 矩阵的左上方角落,并且借助这个更大的矩阵对一个点(或者帧)应用变换。

这个变换在 上拥有相同效果,就如之前其所参与的线性变换。如果我们把点 当作从原点 偏移矢量 ,我们就明白这个变换和应用线性变换到偏移矢量上具有相同效果。因而,以例子来说,如果 矩阵为旋转矩阵,这个变换将围绕原点旋转这个点(参考图示 )。正如下面我们将在第4章中看到的,当对一个点应用一个线性变换,帧的原点位置扮演了一个重要的角色。

我们借助下列缩写用于描述一个 矩阵,其只是应用了一个线性变换。

此处 是一个 矩阵, 是一个 矩阵,右上角的0代表 由0组成的矩阵,右下角的1是一个标量(scalar)。

可以对点应用平移变换是很有用的。这种变换不是线性的(参考课后练习6)。仿射变换的主要新威力就是在线性变换之上表达平移的能力。实际上,如果我们应用变换

我们看到变换在坐标上的效果为

针对平移,我们使用简写

此处 为 一个 矩阵, 为一个 同一矩阵(identity matrix),右上角的 为一个表达平移的 矩阵,左下角的0表示一个由0组成的 矩阵,右下角的1为一个变量。

注意如果 在第4坐标中为0,如此就表达了一个矢量而不是一个点,从而不会被平移所影响。

任何仿射矩阵(affine matrix)都可以被分解为线性部分和平移部分。

或者简写为

注意因为矩阵乘法不是可互换顺序的,乘法 中的顺序很关键。一个仿射矩阵(affine matrix)也可以借助一个不同的平移矩阵 被分解为 (线性部分是不会发生变化的),但是我们不会使用这种形式。

如果 , 的线性部分,是一个旋转,我们把这种形式记作

在这种情形中,我们称 矩阵为刚体矩阵(rigid body matrix),它所对应的变化,刚体变换(rigid body transform),简称 。刚体变换保留了矢量之间的点积(dot product),基的手(螺旋)性(handedness),还有点之间的距离。

在计算机图形学中,我们经常借助表面法线确定一个表面点如何被着色。所以当表面点经历由矩阵 表示的仿射变换时,我们需要懂得表面法线是如何变换的。

你可能猜测我们只要用矩阵 乘以法线的坐标就可以了。例如,如果我们旋转几何形状,法线会以完全相同的方式旋转。但是事实上使用矩阵 不总是正确的。例如在图示 中,我们顺着 轴挤压一个球体。在这种情形中,实际的法线变换会顺着 轴拉伸而不是挤压。在这里我们要推导出可以应用在所有情形中的正确变换。

让我们定义位于点上平滑表面的法线为一个矢量,这个矢量正交于那个点表面的切线平面。切线平面是矢量平面,这个矢量平面通过临近的(距离无限小地)表面点之间的减法来定义,所以,针对法线 和两个非常接近的点 和 ,我们有如下表达。

在某种固定的正交标准化坐标系中,这可以被表达为

在这个公式中我们在前面的插槽中使用 是因为它被0乘,从而和结果不相关。

假设存在一个由仿射矩阵 表示的仿射变换,我们把这个变换应用到所有的点上。什么矢量会和任意的切线矢量保持正交状态?让我们重写方程式(3.4)为

如果我们定义 为被变换点的坐标,同时让 ,那么我们就得到如下表达

并且我们看到 是被变换的几何体法线的坐标(要依靠伸缩变换来获得标准态)。

注意因为我们不关注 值,因而我们不需要关注 的第四列。同时,因为A是一个仿射矩阵(affine matrix),所以 也是,进而剩下三列的第四行全部是0,从而可以安全地被忽略。因而,参考简写方式

我们可以得到这种关系

此时调换整个表达式,我们就获得最终表达式

此处 是 矩阵的反转加调换(等价于调换加反转)。注意如果 为一个旋转矩阵,且这个矩阵是正交标准化的,那么它的反转加调换事实上仍然是 。在这种情形中法线的坐标表现的就像点的坐标一样。然而对于其它线性变换,法线的表现就不相同了。(参考图示 。)同时也要注意到A的平移部分对法线没有影响。

affine transformation matrix 仿射变换矩阵 与 OpenGL

变换模型是指根据待匹配图像与背景图像之间几何畸变的情况,所选择的能最佳拟合两幅图像之间变化的几何变换模型。可采用的变换模型有如下几种:刚性变换、仿射变换、透视变换和非线形变换等,如下图:

技术分享

参考: http://wenku.baidu.com/view/826a796027d3240c8447ef20.html

 

其中第三个的仿射变换就是我们这节要讨论的。

仿射变换(Affine Transformation)
Affine Transformation是一种二维坐标到二维坐标之间的线性变换,保持二维图形的“平直性”(译注:straightness,即变换后直线还是直线不会打弯,圆弧还是圆弧)和“平行性”(译注:parallelness,其实是指保二维图形间的相对位置关系不变,平行线还是平行线,相交直线的交角不变。)。

技术分享

c和d的区别可以看下图:

技术分享

仿射变换可以通过一系列的原子变换的复合来实现,包括:平移(Translation)、缩放(Scale)、翻转(Flip)、旋转(Rotation)和剪切(Shear)。

技术分享

仿射变换可以用下面公式表示:

技术分享

参考:http://wenku.baidu.com/view/826a796027d3240c8447ef20.html

这个矩阵乘法的计算如下:

技术分享

具体到二维的仿射变换的计算如下:

技术分享

几种典型的仿射变换如下:

平移变换 Translation

将每一点移动到(x+tx, y+ty),变换矩阵为:
技术分享

平移变换是一种“刚体变换”,rigid-body transformation,就是不会产生形变的理想物体。

效果:

技术分享

缩放变换(Scale)

将每一点的横坐标放大(缩小)至sx倍,纵坐标放大(缩小)至sy倍,变换矩阵为:

技术分享

变换效果如下:

技术分享

 

剪切变换(Shear)

变换矩阵为:

技术分享

相当于一个横向剪切与一个纵向剪切的复合

技术分享

效果:

技术分享

 

旋转变换(Rotation)

目标图形围绕原点顺时针旋转theta弧度,变换矩阵为:

技术分享

效果:

技术分享

组合

 

旋转变换,目标图形以(x, y)为轴心顺时针旋转theta弧度,变换矩阵为:

技术分享

相当于两次平移变换与一次原点旋转变换的复合:

技术分享

先移动到中心节点,然后旋转,然后再移动回去。

参考:
http://wenku.baidu.com/link?url=AtomIQH400RVIckGwh-V5vPBGmTEVN7ZBtzEjHFeEPxkqu2llowVdW1IFFPqJWaZGUQsQG1hK0OtdrFJ4JBsru3rO8bP9VKQ8Iae0Xm_wt7

 

这个转换矩阵也可以下面这样描述。
技术分享

以上是关于CG中的仿射(affine transformation)和法线变换的主要内容,如果未能解决你的问题,请参考以下文章

仿射affine--小结

affine transformation matrix 仿射变换矩阵 与 OpenGL

何为仿射变换(Affine Transformation)

利用最小二乘法求解仿射变换参数

数学知识整理:仿射函数(affine function)

MATLAB点云处理(二十):三维刚体几何变换矩阵(regid3d)与仿射几何变换矩阵(affine3d)