代码改变世界

【吐槽向】iOS 中的仿射变换

2017-09-29 20:36  l4y  阅读(436)  评论(0编辑  收藏  举报

什么是仿射变换矩阵

CGAffineTransform 实际上就是一个用于绘制 2D 图形的的仿射变换矩阵。仿射变换矩阵用于旋转、缩放、平移、扭曲(skew)在图形上下文中绘制的对象。CGAffineTransform 提供了了一些列的函数来创建、连接或者运用这些变换。

仿射变换通过一个 3 行 3 列的矩阵来表示:

那么对于一个点 (x,y) 来说,使用上边的矩阵来进行变换 (x',y') 是这样的:

结果是这样的:

上边就是仿射变换所有的核心内容,接下来说一下,Core Graphics 针对 CGAffineTransorm 为开发者提供的 API。

生成仿射变换矩阵

Core Graphics 一共提供了如下 4 个相关 API。

CGAffineTransform CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty);

其各个参数的用途,参考这个矩阵:

CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle);

该函数对应这个矩阵:

CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);

该函数对应的矩阵如下:

CGAffineTransform CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty);

该函数对应的矩阵如下:

改变已有的仿射变换矩阵

CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty);
CGAffineTransform CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy);
CGAffineTransform CGAffineTransformRotate(CGAffineTransform t, CGFloat angle);
CGAffineTransform CGAffineTransformInvert(CGAffineTransform t);
CGAffineTransform CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);

上边列举的前四个 API 都有 1 个类型为 CGAffineTransform 的参数 t,这四个 API 分别对 t 进行平移、缩放、旋转、求逆。

第五个相对特殊,它有两个类型为 CGAffineTransform 的参数,该函数返回值为 t1*t2 。

除了上边列举的 API,还提供有判断两个矩阵是否等价、是否为单元矩阵,对 CGPoitn
CGSizeCGRect 进行仿射变换等 API,同时有相关 API 针对 CTM 做变换。

结束了

写到这里,本文的主要内容就结束了。对,文章没有任何有深度的内容,都是线性代数的入门知识。那我为什么要写?

因为,今天在微博上看到有人这么说:

你告诉我,你先 translate 后 rotate 和 rotate 之后再 translate 效果凭什么要一样?


文中非吐槽部分的所有配图均来自苹果开发者文档。