您的位置:首页 > 移动开发 > IOS开发

iOS 2D绘图详解(Quartz 2D)之Transform(CTM,Translate,Rotate,Scale)

2015-10-27 11:52 387 查看
原创Blog,转载请注明出处

http://blog.csdn.net/hello_hwc?viewmode=list

我的stackoverflow





前三篇基础博客路径

iOS 2D绘图详解(Quartz 2D)之概述

iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)

iOS 2D绘图详解(Quartz 2D)之路径(stroke,fill,clip,subpath,blend)

前言:Quartz默认采用设备无关的user space来进行绘图,当context(画板)建立之后,默认的坐标系原点以及方向也就确认了,可以通过CTM(current transformation matrix)来修坐标系的原点。从数组图像处理的角度来说,就是对当前context state乘以一个状态矩阵。其中的矩阵运算开发者可以不了解。

以下,会一一个Demo图解,坐标系的位移,旋转,sacle

最初的状态和代码

新建一个CustomView,.m文件

@implementation CustomView

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextAddRect(context, CGRectMake(10,10,40, 20));
CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
CGContextFillPath(context);
}
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
self.opaque = NO;
self.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.layer.borderWidth = 1.0;
}
return self;
}
@end


调用

CustomView * customView = [[CustomView alloc] initWithFrame:CGRectMake(100, 100,100, 100)];
[self.view addSubview:customView];


图解



Translate

假如我们在绘制之前,进行坐标系移动会是什么效果呢?

代码

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context,10, 10);

CGContextAddRect(context, CGRectMake(10,10,40, 20));
CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
CGContextFillPath(context);
}


效果



代码中,我们是还是在(10,10)点绘制,但是要注意,当前坐标系的原点已经移了

Rotate

在Transform的基础上我们再Rotate,45度,注意
CGContextRotateCTM
传入的参数是弧度

代码

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context,10, 10);
CGContextRotateCTM(context,M_PI_4);
CGContextAddRect(context, CGRectMake(10,10,40, 20));
CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
CGContextFillPath(context);
}


效果



Scale

对于Scale相对来说,好理解一点,无非就是成比例放大缩小。

这里不花坐标系了

代码

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context,10, 10);
CGContextRotateCTM(context,M_PI_4);
CGContextScaleCTM(context,0.5, 0.5);
CGContextAddRect(context, CGRectMake(10,10,40, 20));
CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
CGContextFillPath(context);
}


效果



状态保存,恢复

在复杂的绘图中,我们可能只是想对一个subpath进行旋转移动,缩放。这时候,状态堆栈就起到作用了。

代码

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
//保存状态,入栈
CGContextSaveGState(context);
CGContextTranslateCTM(context,10, 10);
CGContextRotateCTM(context,M_PI_4);
CGContextScaleCTM(context,0.5, 0.5);
CGContextAddRect(context, CGRectMake(10,10,40, 20));
CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
CGContextFillPath(context);
CGContextRestoreGState(context);// 推出栈顶部状态

//这里坐标系已经回到了最开始的状态
CGContextAddRect(context, CGRectMake(0, 0, 10, 10));
CGContextFillPath(context);
}


效果



Affine Transforms

可以通过以下方法先创建放射矩阵,然后然后再把放射矩阵映射到CTM

CGAffineTransform

CGAffineTransformTranslate

CGAffineTransformMakeRotation

CGAffineTransformRotate

CGAffineTransformMakeScale

CGAffineTransformScale
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios quartz 2d 绘图