您的位置:首页 > 其它

CATransform3D和CGAffineTransform之详细解说测试

2017-04-17 13:39 387 查看

1、本片博客重点在于两个类的解说,使用解说的不多。

        3D 效果的基本类 CGAffineTransform ,还有他的兄弟CGAffineTransform类。这里对改两个类的方法等做了详细的测试和实验。

2、呼朋唤友

群的特点:
  1、iOS 开发交流群,每周都有更新新的内容。
  2、群里有3~5年的资深开发者。
  3、群员在App开发过程中遇到什么问题,可以在群里提问。
  4、群员在App开发中,如果遇到难实现的功能或者模块,可以在群里提出,有人员帮助你实现。
  5、加入群后,可以get到App 开发中的一些小功能模块。
  群号是:185341804   群名字:成功QQ吧
  群主号:1542100658 (qq)

3、代码测试块

第一、CATransform3D的介绍

#pragma mark --- ExplainCATransform3D

-(void)ExplainCATransform3D{

    

    /**

     CATransform3D 是一个奇次三维变换矩阵

     原型:

     struct CATransform3D

     {

     CGFloat m11, m12, m13, m14;

     CGFloat m21, m22, m23, m24;

     CGFloat m31, m32, m33, m34;

     CGFloat m41, m42, m43, m44;

     };

     

     个参数的意思

     m11 : 以XY轴中心为中心,随着m11值由
1-->0 变小,图像向X轴中心压缩;随着m11值由
1-->MAX 变大,图像以X轴中心向外拉伸图像。

     m12 : 以XY轴中心为中心,随着m12值由
0-->MAX 变大,图像顺时针方向在Y轴,做切变。随着m12值由
0-->MIN 变小,图像逆时针方向在Y轴,做切变。

     名词介绍:

        切变:两个距离很近、大小相等、方向相反的平行力作用于同一物体上所引起的形变。

     m13 : 以X轴为中心的垂直线为界限,如果m13>0图像的左边将会被切掉
; m13<0 图像的右边边将会被切掉。

     m14 :以X轴为中心的垂直线为界限,随着m14值由
0-->MAX 变大,图像左侧向Z轴翻转,并做拉伸。随着m14值由
0-->MIN 变小,图像右边向Z轴翻转,做拉伸。

     

     m21 :以XY轴中心为中心,随着m21值由
0-->MAX 变大,图像顺时针方向在X轴,做切变。随着m21值由
0-->MIN 变小,图像逆时针方向在X轴,做切变。

     m22 : 以XY轴中心为中心,随着m22值由
1-->0 变小,图像向Y轴中心压缩;随着m22值由
1-->MAX 变大,图像以Y轴中心向外拉伸图像。

     m23 : 以Y轴为中心的垂直线为界限,如果m23>0图像的上边将会被切掉
; m23<0 图像的下边边将会被切掉。

     m24 :以Y轴为中心的垂直线为界限,随着m24值由
0-->MAX 变大,图像上面向Z轴翻转,并做拉伸。随着m24值由
0-->MIN 变小,图像下面边向Z轴翻转,并做拉伸。

     m31:和m13一起决定y轴的旋转

     m32:和m23一起决定x轴的旋转

     m33:z轴方向进行缩放

     m34:透视效果m34= -1/D,D越小,透视效果越明显,必须在有旋转效果的前提下,才会看到透视效果

     m41 : 让图像沿着X轴左右平移。m41>0
,向右平移;m41<0
,向左平移。

     m42 : 让图像沿着Y轴上下平移。m42>0
,向上平移;m41<0
,向下平移。

     m43 : 让图像沿着Z轴上下平移。m43>0
,向上平移;m43<0
,向下平移。

     m44 : 图像的放大和缩小,当m44
由 MAX --> 0
放大;0-->
缩小。

     */

}

2、整体介绍,不一一介绍

//

//  ViewController+CATransform3DExplain.m

//  立体效果之CATransform3D

//

//  Created by MAC on 2017/4/13.

//  Copyright © 2017年 NetworkCode小贱. All rights reserved.

//

#import "ViewController.h"

#import <QuartzCore/QuartzCore.h>

@implementation ViewController (CATransform3DExplain)

-(void)viewDidLoad{

    /**

     一个类的解说

     */

    [self
ExplainCATransform3D];

    /**

     事例

     */

    [self
createImageView];

    /**

     创建一个滑块

     */

    [self
createSlider];

}

#pragma mark --- ExplainCATransform3D

-(void)ExplainCATransform3D{

    

    /**

     CATransform3D 是一个奇次三维变换矩阵

     原型:

     struct CATransform3D

     {

     CGFloat m11, m12, m13, m14;

     CGFloat m21, m22, m23, m24;

     CGFloat m31, m32, m33, m34;

     CGFloat m41, m42, m43, m44;

     };

     

     个参数的意思

     m11 : 以XY轴中心为中心,随着m11值由
1-->0 变小,图像向X轴中心压缩;随着m11值由
1-->MAX 变大,图像以X轴中心向外拉伸图像。

     m12 : 以XY轴中心为中心,随着m12值由
0-->MAX 变大,图像顺时针方向在Y轴,做切变。随着m12值由
0-->MIN 变小,图像逆时针方向在Y轴,做切变。

     名词介绍:

        切变:两个距离很近、大小相等、方向相反的平行力作用于同一物体上所引起的形变。

     m13 : 以X轴为中心的垂直线为界限,如果m13>0图像的左边将会被切掉
; m13<0 图像的右边边将会被切掉。

     m14 :以X轴为中心的垂直线为界限,随着m14值由
0-->MAX 变大,图像左侧向Z轴翻转,并做拉伸。随着m14值由
0-->MIN 变小,图像右边向Z轴翻转,做拉伸。

     

     m21 :以XY轴中心为中心,随着m21值由
0-->MAX 变大,图像顺时针方向在X轴,做切变。随着m21值由
0-->MIN 变小,图像逆时针方向在X轴,做切变。

     m22 : 以XY轴中心为中心,随着m22值由
1-->0 变小,图像向Y轴中心压缩;随着m22值由
1-->MAX 变大,图像以Y轴中心向外拉伸图像。

     m23 : 以Y轴为中心的垂直线为界限,如果m23>0图像的上边将会被切掉
; m23<0 图像的下边边将会被切掉。

     m24 :以Y轴为中心的垂直线为界限,随着m24值由
0-->MAX 变大,图像上面向Z轴翻转,并做拉伸。随着m24值由
0-->MIN 变小,图像下面边向Z轴翻转,并做拉伸。

     m31:和m13一起决定y轴的旋转

     m32:和m23一起决定x轴的旋转

     m33:z轴方向进行缩放

     m34:透视效果m34= -1/D,D越小,透视效果越明显,必须在有旋转效果的前提下,才会看到透视效果

     m41 : 让图像沿着X轴左右平移。m41>0
,向右平移;m41<0
,向左平移。

     m42 : 让图像沿着Y轴上下平移。m42>0
,向上平移;m41<0
,向下平移。

     m43 : 让图像沿着Z轴上下平移。m43>0
,向上平移;m43<0
,向下平移。

     m44 : 图像的放大和缩小,当m44
由 MAX --> 0
放大;0-->
缩小。

     */

}

#pragma mark  ---  createImageView

-(void)createImageView{

    UIView * iview = [[UIView
alloc]initWithFrame:CGRectMake(100,
160, 160,
140)];

    iview.backgroundColor = [UIColor
redColor];

    [self.view
addSubview:iview];

    _imageView = ({

        UIImageView * imageView = [[UIImageView
alloc]initWithFrame:CGRectMake(100,
160, 160,
140)];

        imageView.image = [UIImage
imageNamed:@"test.jpg"];

        [self.view
addSubview:imageView];

        imageView;

    });

}

#pragma mark ---  createSlider

-(void)createSlider{

    _slider = [[UISlider
alloc]initWithFrame:CGRectMake(10,
self.view.frame.size.height-50,
self.view.frame.size.width-20,
40)];

    [_slider
addTarget:self
action:@selector(changeValue)
forControlEvents:UIControlEventValueChanged];

    [self.view
addSubview:_slider];

}

-(void)changeValue{

    

    [self
transformAffineTransform];

 }

#pragma mark --- verdictDefaultTrans

-(void)verdictDefaultTrans:(CATransform3D)transform3D{

    if (CATransform3DIsIdentity(transform3D)) {

        NSLog(@"默认矩阵,CATransform3DIdentity");

    }else{

        NSLog(@"矩阵发生变化");

    }

    /**

     输出:

     2017-04-13 15:43:50.432 立体效果之CATransform3D[2669:1457665]
默认矩阵,CATransform3DIdentity

     2017-04-13 15:44:15.189 立体效果之CATransform3D[2669:1457665]
矩阵发生变化

     */

}

#pragma mark ---verdictEqualTrans:andTrans:

-(void)verdictEqualTrans:(CATransform3D)transform3D andTrans:(CATransform3D)transform3D1{

    if (CATransform3DEqualToTransform(transform3D, transform3D1)) {

        NSLog(@"两个矩阵相等");

    }else{

        NSLog(@"两个矩阵不相等");

    }

    /**

     输出:

     2017-04-13 15:58:55.242 立体效果之CATransform3D[2702:1487783]
两个矩阵不相等

     2017-04-13 15:59:34.279 立体效果之CATransform3D[2717:1492132]
两个矩阵相等

     */

}

#pragma mark ---  translationTransTransX:transX:transY:transZ

-(void)translationTransTransX:(CGFloat)tX transY:(CGFloat)tY transZ:(CGFloat)tZ{

    /**

     这个是改变矩阵的 m41 ~ m43
的值

     发生图像的平移

     */

    CATransform3D  transform3D =
CATransform3DIdentity;

    transform3D = CATransform3DMakeTranslation(tX, tY, tZ);

    [_imageView.layer
setTransform:transform3D];

}

#pragma mark --- transMakeScaleSx:scaleSy:scaleSz

-(void)transMakeScaleSx:(CGFloat)sX scaleSy:(CGFloat)sY scaleSz:(CGFloat)sZ{

    /**

     这是改变矩阵的 m11 / m22/ m33 
,来缩放图像

     */

    CATransform3D  transform3D =
CATransform3DIdentity;

    transform3D = CATransform3DMakeScale(sX, sY,sZ);

    [_imageView.layer
setTransform:transform3D];

}

#pragma mark ---  transMakeRotationAngle:rotationX:rotationY:rotationZ

-(void)transMakeRotationAngle:(CGFloat)angle rotationX:(CGFloat)rX rotationY:(CGFloat)rY
rotationZ:(CGFloat)rZ{

    /**

     angle : 各个方向轴旋转的角度

     类似于在各个方向上切变

     */

    CATransform3D  transform3D =
CATransform3DIdentity;

    transform3D = CATransform3DMakeRotation(angle,rX, rY,rZ);

    [_imageView.layer
setTransform:transform3D];

}

#pragma mark ---  transformInvert

-(void)transformInvert:(CATransform3D)transform3D{

    /**

     矩阵翻转

     就是将原矩阵乘以

     1  -1  1  -1

    -1   1 -1   1

     1  -1  1  -1

    -1  -1 -1   1

     */

    [_imageView.layer
setTransform:CATransform3DInvert(transform3D)];

}

#pragma mark  ---  transLinksTransA:transB:

-(void)transLinks{

    /**

     矩阵的复合效果,即效果叠加

     */

    CATransform3D transScal =
CATransform3DMakeScale(0.5*
_slider.value,
0.6, 0.8*_slider.value);

    CATransform3D transTran = 
CATransform3DMakeTranslation(20,
80* _slider.value,
100* _slider.value);

    CATransform3D comban  =
CATransform3DConcat(transScal, transTran);

    [_imageView.layer
setTransform:comban ];

}

-(void)transformAffineTransform{

    /**

     仿射:

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

     */

    CATransform3D transScal =
CATransform3DMakeScale(0.5*
_slider.value,
0.6, 0);

    CGAffineTransform  from =
CATransform3DGetAffineTransform(transScal);

    [_imageView.layer
setTransform:CATransform3DMakeAffineTransform(from) ];

}

@end

第二、仿射矩阵的介绍模块

/**

 自己设置仿射矩阵的初始值

 */

-(void)setAffineTrans{

    /**

     自定义仿射矩阵

     1 0 0 1 0 0

      

     各个参数的含义:

     

     a: 是控制图像在X轴,上的伸缩。

     b: 是控制图像在Y轴,上的切变和伸缩。

     c: 是控制图像在Z轴的旋转。

     d: 是控制图像在Y轴上,上的伸缩。

     tx : 是控制图像的X轴,上的平移。

     ty : 是控制图像的Y轴,上的平移。

     */

    CGAffineTransform  aTf =
CGAffineTransformMake(1,
0, 0,
1,0,0);

    _imageView.layer.affineTransform
= aTf;

}

2、整体介绍仿射的方法

//

//  ViewController+AffineExplainViewController.m

//  立体效果之CATransform3D

//

//  Created by MAC on 2017/4/14.

//  Copyright © 2017年 NetworkCode小贱. All rights reserved.

//

#import "ViewController.h"

@implementation ViewController (AffineExplainViewController)

//-(void)viewDidLoad{

//    //[self createImageView];

//    /**

//     创建一个滑块

//     */

//   // [self createSlider];

//

//}

#pragma mark ---  createSlider

-(void)createSlider{

    _slider = [[UISlider
alloc]initWithFrame:CGRectMake(10,
self.view.frame.size.height-50,
self.view.frame.size.width-20,
40)];

    [_slider
addTarget:self
action:@selector(changeValue)
forControlEvents:UIControlEventValueChanged];

    [self.view
addSubview:_slider];

}

-(void)changeValue{

    

    [self
affineTransformInvert];

}

/**

 仿射矩阵的翻转

 */

-(void)affineTransformInvert{

    CGAffineTransform  aTf =
CGAffineTransformMakeRotation(100 *_slider.value
* M_PI/180);

    _imageView.layer.affineTransform
= CGAffineTransformInvert(aTf);

}

/**

 范围的仿射

 */

-(void)rectAffineTrans{

    CGAffineTransform  aTf =
CGAffineTransformMakeRotation(100 *_slider.value
* M_PI/180);

    CGRect A =
_imageView.frame;

    CGRect  ATPoint =
CGRectApplyAffineTransform(A, aTf);

    _imageView.frame = ATPoint;

    NSLog(@"%f---%f",ATPoint.size.width
,ATPoint.size.height);

}

/**

 大小的仿射

 */

-(void)sizeAffineTrans{

    CGAffineTransform  aTf =
CGAffineTransformMakeRotation(100 *_slider.value
* M_PI/180);

    CGSize A =
CGSizeMake(100,
20);

    CGSize  ATPoint =
CGSizeApplyAffineTransform(A, aTf);

    NSLog(@"%f---%f",ATPoint.width ,ATPoint.height);

}

/**

 点的仿射

 */

-(void)pointAffineTrans{

    CGAffineTransform  aTf =
CGAffineTransformMakeRotation(100 *_slider.value
* M_PI/180);

    CGPoint A =
CGPointMake(100,
20);

    CGPoint  ATPoint =
CGPointApplyAffineTransform(A, aTf);

    NSLog(@"%f---%f",ATPoint.x,ATPoint.y);

}

/**

 仿射矩阵的复合

 */

-(void)AffineTransformConcat{

    CGAffineTransform  aTf =
CGAffineTransformMakeRotation(100 *_slider.value
* M_PI/180);

    CGAffineTransform  aTfR =
CGAffineTransformMakeScale(_slider.value ,
0.5);

    _imageView.layer.affineTransform
= CGAffineTransformConcat(aTf, aTfR);

}

/**

 判断是否仿射矩阵相等

 */

-(void)judgeAffineTransformEqualToTransform{

    if (CGAffineTransformEqualToTransform(CGAffineTransformIdentity,CGAffineTransformIdentity))
{

        NSLog(@"仿射矩阵相同");

    }else{

        NSLog(@"仿射矩阵不想等");

    }

}

/**

 判断是否是仿射矩阵

 */

-(void)judgeAffineTransIsIdentity{

    

    if (CGAffineTransformIsIdentity(CGAffineTransformIdentity))
{

        NSLog(@"是仿射矩阵");

    }else{

        NSLog(@"不是仿射矩阵");

    }

}

/**

 仿射矩阵的旋转

 */

-(void)AffineTransRotation{

    /**

     angle :是旋转的角度   X *  PI/180.

     */

    CGAffineTransform  aTf =
CGAffineTransformMakeRotation(100 *_slider.value
* M_PI/180);

    _imageView.layer.affineTransform
= aTf;

}

/**

 仿射矩阵的缩放

 */

-(void)AffineTransScale{

    /**

     仿射矩阵的缩放

     sx  & sy ,一般不要为0,否则将不显示图像

     */

    CGAffineTransform  aTf =
CGAffineTransformMakeScale(_slider.value ,
0.5);

    _imageView.layer.affineTransform
= aTf;

}

/**

 仿射矩阵的平移

 */

-(void)AffineTransTranslation{

    /**

     平移仿射矩阵

     tx: 图像在X轴平移。

     ty: 图像在Y轴平移。

     */

    CGAffineTransform  aTf =
CGAffineTransformMakeTranslation(10 *
_slider.value    ,
0);

    _imageView.layer.affineTransform
= aTf;

}

/**

 自己设置仿射矩阵的初始值

 */

-(void)setAffineTrans{

    /**

     自定义仿射矩阵

     1 0 0 1 0 0

      

     各个参数的含义:

     

     a: 是控制图像在X轴,上的伸缩。

     b: 是控制图像在Y轴,上的切变和伸缩。

     c: 是控制图像在Z轴的旋转。

     d: 是控制图像在Y轴上,上的伸缩。

     tx : 是控制图像的X轴,上的平移。

     ty : 是控制图像的Y轴,上的平移。

     */

    CGAffineTransform  aTf =
CGAffineTransformMake(1,
0, 0,
1,0,0);

    _imageView.layer.affineTransform
= aTf;

}

/**

 默认仿射矩阵

 */

-(void)defaultAffineTrans{

    /**

     默认矩阵

     图形不会发生变化

     */

    CGAffineTransform  aTf =
CGAffineTransformIdentity;

    _imageView.layer.affineTransform
= aTf;

}

#pragma mark  ---  createImageView

-(void)createImageView{

    UIView * iview = [[UIView
alloc]initWithFrame:CGRectMake(100,
160, 160,
140)];

    iview.backgroundColor = [UIColor
redColor];

    [self.view
addSubview:iview];

    _imageView = ({

        UIImageView * imageView = [[UIImageView
alloc]initWithFrame:CGRectMake(100,
160, 160,
140)];

        imageView.image = [UIImage
imageNamed:@"test.jpg"];

        [self.view
addSubview:imageView];

        imageView;

    });

}

@end


3、demo的下载地址

https://pan.baidu.com/s/1eScL6KU
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息