PRML 2017-12-16
CoreGraphics框架下的CGAffineTransform结构体,可以实现对视图或图层的旋转、缩放、平移及组合变换。
public struct CGAffineTransform { public var a: CGFloat public var b: CGFloat public var c: CGFloat public var d: CGFloat public var tx: CGFloat public var ty: CGFloat public init() public init(a: CGFloat, b: CGFloat, c: CGFloat, d: CGFloat, tx: CGFloat, ty: CGFloat) }
可以看到CGAffineTransform是一个结构体,它会被组装成如下矩阵
x' = ax+cy+tx
y' = bx+dy+ty
平移初始化方法如下
/* Return a transform which translates by `(tx, ty)': t' = [ 1 0 0 1 tx ty ] */ public init(translationX tx: CGFloat, y ty: CGFloat)
经过坐标变换,可以得到x' = x+tx
y' = y+ty
平移看起来非常简单,tx为正值则向x轴正向平移,反之向负向平移,ty值同理(x轴向右为正向,y轴向下为正向)
缩放初始化方法如下
/* Return a transform which scales by `(sx, sy)': t' = [ sx 0 0 sy 0 0 ] */ public init(scaleX sx: CGFloat, y sy: CGFloat)
经过坐标变换,可以得到x' = x*sx
y' = y*sy
根据传入sx, sy进行缩放,传入负值可进行水平或垂直镜像
旋转初始化方法如下
/* Return a transform which rotates by `angle' radians: t' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] */ public init(rotationAngle angle: CGFloat)
这里入参是一个弧度值,角度x转换为弧度angle = x*Double.pi/180
旋转是绕着视图中心点进行,angle为正值则视图绕着中心点顺时针旋转
下面推导一下这个变换矩阵
x=rcosϕ, y=rsinϕ
x′=rcos(θ+ϕ), y′=rsin(θ+ϕ)
通过三角函数展开得到
x′=rcosθcosϕ−rsinθsinϕ
y′=rsinθcosϕ+rcosθsinϕ
带入x和y表达式得到
x′=xcosθ−ysinθ
y′=xsinθ+ycosθ
写成矩阵的形式即:
我们用一个ImageView来演示一下
jfImageView.transform = CGAffineTransform(translationX: 50, y: -50)
jfImageView.transform = CGAffineTransform(scaleX: 2, y: 2)
jfImageView.transform = CGAffineTransform(rotationAngle: -.pi/4)
jfImageView.transform = CGAffineTransform(rotationAngle: -.pi/4).scaledBy(x: 2, y: 2)
jfImageView.transform = CGAffineTransform(rotationAngle: -.pi/4).scaledBy(x: 2, y: 2).translatedBy(x: 50, y: -50)
jfImageView.transform = CGAffineTransform(rotationAngle: -.pi/4).translatedBy(x: 50, y: -50).scaledBy(x: 2, y: 2)
后面两种组合变换得到的结果是不一样的先来看三种变换后的视图frame(4英寸屏幕大小下)
当对图层做变换的时候,比如旋转或者缩放,frame实际上代表了覆盖在图层旋转之后的整个轴对齐的矩形区域,也就是说frame的宽高可能和bounds的宽高不再一致了,就如我们的图片一样,frame = {6.56, 130.56, 306.88, 306.88},bounds = {0, 0, 128, 89}
组合变换2的translatedBy(x: 50, y: -50)被逆时针旋转了45度,放大了两倍,因此竖直向上移动了100√2≈141.42 组合变换3的translatedBy(x: 50, y: -50)只是被逆时针旋转了45度,因此竖直向上移动了50√2≈70.71
Demo下载
参考资料:
Documentation>Core Graphics>CGAffineTransform
旋转变换(一)旋转矩阵
《iOS Core Animation》