ios 仿射变换详解

1原理

在有限维的情况,每个仿射变换可以由一个矩阵A和一个向量b给出,它可以写作A和一个附加的列b。一个仿射变换对应于一个矩阵和一个向量的乘法,而仿射变换的复合对应于普通的 矩阵乘法,只要加入一个额外的行到矩阵的底下,这一行全部是0除了最右边是一个1,而列向量的底下要加上一个1。
AffineTransform类描述了一种 二维仿
仿射变换流程图

仿射变换流程图

射变换的功能,它是一种二维 坐标到二维坐标之间的 线性变换,保持二维图形的“平直性”(译注: straightness,即变换后直线还是直线不会打弯,圆弧还是圆弧)和“平行性”(译注:par
常用的仿射变换:旋转、倾斜、平移、缩放

常用的仿射变换:旋转、倾斜、平移、缩放

allelness,其实是指保二维图形间的相对位置关系不变, 平行线还是平行线,而直线上点的位置顺序不变,另特别注意向量间夹角可能会发生变化。)仿射变换可以通过一系列的原子变换的复合来实现,包括: 平移(Translation)、 缩放(Scale)、 翻转(Flip)、 旋转(Rotation)和 错切(Shear)。
此类变换可以用一个3×3的矩阵来表示,其最后一行为(0, 0, 1)。该 变换矩阵将原坐标(x, y)变换为新坐标(x', y'),这里原坐标和新坐标皆视为最末一行为(1)的三维列向量,原列向量左乘变换矩阵得到新的列向量:

2示例

几种典型的仿射变换:
public static AffineTransform getTranslateInstance(doubl
仿射变换-例

仿射变换-例

e tx, double ty)
平移变换,将每一点移动到(x+tx, y+ty),变换矩阵为:
[ 1 0 tx ]
[ 0 1 ty ]
[ 0 0 1 ]
(译注:平移变换是一种“ 刚体变换”,rigid-body transformation,中学学过的物理,都知道啥叫“刚体”吧,就是不会产生形变的理想物体,平移当然不会改变二维图形的形状。同理,下面的“ 旋转变换”也是 刚体变换,而“缩放”、“错切”都是会改变图形形状的。)
public static AffineTransform getScaleInstance(double sx, double sy)
缩放变换,将每一点的横坐标放大(缩小)至sx倍,纵坐标放大(缩小)至sy倍,变换矩阵为:
[ sx 0 0 ]
[ 0 sy 0 ]
[ 0 0 1 ]
当sx=sy时,称为尺度缩放,sx不等于sy时,这就是我们平时所说的拉伸变换。
public static AffineTransform getShearInstance(double shx, double shy)
剪切变换,变换矩阵为:
[ 1 shx 0 ]
[ shy 1 0 ]
[ 0 0 1 ]
相当于一个横向剪切与一个纵向剪切的复合
[ 1 0 0 ][ 1 shx 0 ]
[ shy 1 0 ][ 0 1 0 ]
[ 0 0 1 ][ 0 0 1 ]
(译注:“剪切变换”又称“错切变换”,指的是类似于 四边形不稳定性那种性质,街边小商店那种铁拉门都见过吧?想象一下上面铁条构成的菱形拉动的过程,那就是“错切”的过程。)
public static AffineTransform getRotateInstance(double theta)



典型的仿射变换-平移变换

典型的仿射变换-平移变换

典型的仿射变换-缩放变换

典型的仿射变换-缩放变换

典型的仿射变换-剪切变换

典型的仿射变换-剪切变换

典型的仿射变换-旋转变换

典型的仿射变换-旋转变换

典型的仿射变换-旋转变换

典型的仿射变换-旋转变换








仿射变换可以理解为
・对坐标进行放缩,旋转,平移后取得新坐标的值。
・经过对坐标轴的放缩,旋转,平移后原坐标在在新坐标领域中的值。
 
如上图所示,XY坐标系坐标轴旋转θ,坐标原点移动(x0,y0)。
XY坐标系中的坐标(X,Y),则求新坐标系xy中的坐标值的方程组为:
 
X = X・cosθ - Y・sinθ + x0
Y = X・sinθ + Y・cosθ + y0
 
写成矩阵形式为
 
| x |              | cosθ   sinθ |   | x0 |
|   | = | X Y | * |               | + |    |
| y |              | -sinθ cosθ |   | y0 |
 
为将原点移动的值放入矩阵,则可以加入一个不影响原方程组的解的冗余方程。于是可以写成
 
X = X・cosθ - Y・sinθ + x0
Y = X・sinθ + Y・cosθ + y0
1 = X・0     + Y・0     + 1
 
写成矩阵形式为
| x |                 | cosθ   sinθ   0|
| y | = | X Y 1 | * | -sinθ cosθ   0|
| 1 |                 | x0      y0      1|
 
这个矩阵就是Helmert变换矩阵。
 
考虑到新坐标系对于原坐标系在x,y两个坐标轴上的放缩率,可分别表示为λx和λy,则Helmert变换方程组可以修改为
 
X = (λx)X・cosθ - (λy)Y・sinθ + x0
Y = (λx)X・sinθ + (λy)Y・cosθ + y0
 
同样按照前述方法写成三阶矩阵为
 
| x |                 | (λx)cosθ   (λx)sinθ   0|
| y | = | X Y 1 | * | (λy)-sinθ (λy)cosθ   0|
| 1 |                 |  x0           y0          1|
 
这个矩阵就是affine变换矩阵,仿射矩阵。


仿射变换是二维平面中一种重要的变换,在图像图形领域有广泛的应用。许多人对“仿射”没有一个感官的认识,我觉得很有必要先来说一下“仿射”。

所谓的“仿射变换”就是一种简单的变换,它的变化包括旋转、平移、伸缩,原来的直线仿射变换后还是直线,原来的平行线经过仿射变换之后还是平行线,这就是仿射。

仿射变换的矩阵是其次坐标形式的变换矩阵


这个矩阵包含的变换有旋转和平移,其实是两个矩阵的混合体,许多文章都对这个做了很详细的描述。仿射变换的数学公式里,是如何做到坐标点位置的平移呢?清楚这个才是弄明白仿射变换的关键。

这里有一个非常重要的图,这张图百度百科中就有。利用此图可以完成仿射变换公式的推导,推导如下:


一个点P在原始坐标系下的坐标是(Xsp,Ysp)。然后要完成旋转操作,旋转操作是基于原点的,如何得到旋转之后的点的坐标,这里用到一个技巧,坐标系中某个点的旋转可以等价地去旋转坐标轴,所以有了上图中以(Xs0,Ys0)为中心的虚线与屏幕水平垂直的坐标系。在这个坐标系中确定P的坐标,和在蓝色坐标系中确定旋转之后P的坐标是等价的。基于这个结论,我们可以通过简单的立体几何知识确定P在新坐标系中的坐标。P在新坐标系中的X坐标和Y坐标分别是


经典的仿射变换的模型呼之欲出了。整理上面两个式子得:


这就是仿射变换模型中旋转部分的原理,还有一步,就是平移。

旋转变换之后,我们确定了P点在新坐标系中的位置,然后在这个位置的基础上加上其在X轴和Y轴的偏移即可


仿射变换的矩阵横空出世。当然上图中对这个变换的处理更巧妙,它还是利用了不移动点移动坐标系的策略,将坐标系向相反方向移动了相应的距离。于是有了上图这个经典仿射变换模型的图示展现。上图中我们可以看到,整个在对P点进行仿射变换的过程中,P点的位置并没有移动,我们是通过不断的坐标系的调整来间接达到P点移动的效果,这充分说明了一件事:运动都是相对的。矩阵理论是运动是相对的这一哲学思想的深刻体现,有兴趣大家可以阅读一下这篇文章http://blog.csdn.net/xiaojidan2011/article/details/8213873。


其他参考文章:

http://www.cnblogs.com/shijibao001/articles/1225962.html  


  
  
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值