iOS CGAffineTransform 仿射变换
CGAffineTransform
介绍:
CGAffineTransformIdentity : 单位矩阵变换,一般用于仿射变换的初始化或者还原。
CGAffineTransformEqualToTransform(CGAffineTransform t1, CGAffineTransform t2) : 判断两个变换矩阵是否相等
CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2) : 得到两个矩阵相加后得到的最终矩阵
CGPoint CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t) : 某点通过矩阵变换之后的点
CGSize CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t) : 某个size通过矩阵变换之后的size
CGRect CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t) : 某个Rect通过矩阵变换之后的区域
矩阵的加减乘 http://www.ruanyifeng.com/blog/2015/09/matrix-multiplication.html
一、2D仿射变换
UIView的transform属性是一个CGAffineTransform类型,用于在二维空间做旋转,缩放和平移。
CGAffineTransform是一个可以和二维空间向量(例如CGPoint)做乘法的3X2的矩阵:
矩阵平移(如下图):
CGAffineTransform transform = CGAffineTransformMakeTranslation(10, 10); 结果: (CGAffineTransform) transform = (a = 1, b = 0, c = 0, d = 1, tx = 10, ty = 10)
CGAffineTransform transform = CGAffineTransformMakeScale(0.8, 0.8); 结果: (CGAffineTransform) transform = (a = 0.80000000000000004, b = 0, c = 0, d = 0.80000000000000004, tx = 0, ty = 0)
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_4); 结果 : (CGAffineTransform) transform = (a = 0.70710678118654757, b = 0.70710678118654746, c = -0.70710678118654746, d = 0.70710678118654757, tx = 0, ty = 0)
修改仿射变换矩阵
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle) // 在矩阵t上添加旋转效果 CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy) // 在矩阵t上添加缩放效果 CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty) // 在矩阵t上添加平移效果
//create a new transform CGAffineTransform transform = CGAffineTransformIdentity; //scale by 50% transform = CGAffineTransformScale(transform, 0.5, 0.5); //rotate by 30 degrees transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0); //translate by 200 points transform = CGAffineTransformTranslate(transform, 200, 0); //apply transform to layer self.layerView.layer.affineTransform = transform;
参考资料:
https://zsisme.gitbooks.io/ios-/content/chapter5/affine-fransforms.html
二、3D变换:
CG的前缀告诉我们,CGAffineTransform
类型属于Core Graphics框架,Core Graphics实际上是一个严格意义上的2D绘图API,并且CGAffineTransform
仅仅对2D变换有效。
zPosition
属性,可以用来让图层靠近或者远离相机(用户视角),transform
属性(CATransform3D
类型)可以真正做到这点,即让图层在3D空间内移动或者旋转。
和CGAffineTransform
类似,CATransform3D
也是一个矩阵,但是和3x2的矩阵不同,CATransform3D
是一个可以在3维空间内做变换的4x4的矩阵。
CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z) CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz) CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz)
if ([key isEqualToString:@"rotationY"]) {//绕Y旋转 CATransform3D transform = CATransform3DMakeRotation(M_PI_4, 0, 1, 0); exampleVC.myImageView.layer.transform = transform; } else if ([key isEqualToString:@"rotationY_and_m34"]) {//绕Y旋转_透视投影 //create a new transform CATransform3D transform = CATransform3DIdentity; //apply perspective transform.m34 = - 1.0 / 500.0; //rotate by 45 degrees along the Y axis transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0); //apply to layer exampleVC.myImageView.layer.transform = transform; } else if ([key isEqualToString:@"sublayerTransform"]) {//共享m34 /** CALayer有一个属性叫做sublayerTransform。它也是CATransform3D类型,但和对一个图层的变换不同,它影响到所有的子图层。 这意味着你可以一次性对包含这些图层的容器做变换,于是所有的子图层都自动继承了这个变换方法。 **/ CATransform3D perspective = CATransform3DIdentity; perspective.m34 = - 1.0 / 500.0; exampleVC.containerView.layer.sublayerTransform = perspective; //rotate layerView1 by 45 degrees along the Y axis CATransform3D transform1 = CATransform3DMakeRotation(M_PI_4, 0, 1, 0); exampleVC.layerView1.layer.transform = transform1; //rotate layerView2 by 45 degrees along the Y axis CATransform3D transform2 = CATransform3DMakeRotation(-M_PI_4, 0, 1, 0); exampleVC.layerView2.layer.transform = transform2; }else if ([key isEqualToString:@"background"]) {//背面 CATransform3D transform = CATransform3DMakeRotation(M_PI, 0, 1, 0); exampleVC.myImageView.layer.transform = transform; //背面不绘制 默认yes exampleVC.myImageView.layer.doubleSided = NO;//不绘制就看不到了 }else if ([key isEqualToString:@"outer_inner"]) {// 扁平化图层 CATransform3D outer = CATransform3DMakeRotation(0, 0, 0, 1); exampleVC.layerView1.layer.transform = outer; CATransform3D inner = CATransform3DMakeRotation(-0, 0, 0, 1); exampleVC.layerView2.layer.transform = inner; }
参考资料:
https://zsisme.gitbooks.io/ios-/content/chapter5/3d-transform.html
https://tech.imdada.cn/2016/06/21/ios-core-animation/