在iOS中,Quartz 2D提供了坐标变换支持。
一、特殊的坐标变换(平移、缩放、旋转)
1. - void CGContextTranslateCTM ( CGContextRef c, CGFloat tx, CGFloat ty )
:平移坐标系统。
该方法相当于把原来位于 (0, 0) 位置的坐标原点平移到 (tx, ty) 点。在平移后的坐标系统上绘制图形时,所有坐标点的 X 坐标都相当于增加了 tx,所有点的 Y 坐标都相当于增加了 ty。
2. - void CGContextScaleCTM ( CGContextRef c, CGFloat sx, CGFloat sy )
:缩放坐标系统。
该方法控制坐标系统水平方向上缩放 sx,垂直方向上缩放 sy。在缩放后的坐标系统上绘制图形时,所有点的 X 坐标都相当于乘以 sx 因子,所有点的 Y 坐标都相当于乘以 sy 因子。
3. - void CGContextRotateCTM ( CGContextRef c, CGFloat angle )
:旋转坐标系统。
该方法控制坐标系统旋转 angle 弧度。在缩放后的坐标系统上绘制图形时,所有坐标点的 X、Y 坐标都相当于旋转了 angle弧度之后的坐标。
为了让开发者在进行坐标变换时无须计算多次坐标变换后的累加结果,Quartz 2D还提供了如下两个方法来保存、恢复绘图状态。
- void CGContextSaveGState ( CGContextRef c )
:保存当前的绘图状态。
- void CGContextRestoreGState ( CGContextRef c )
:恢复之前保存的绘图状态。
需要说明的是,CGContextSaveGState() 函数保存的绘图状态,不仅包括当前坐标系统的状态,也包括当前设置的填充风格、线条风格、阴影风格等各种绘图状态。但 CGContextSaveGState() 函数不会保存当前绘制的图形。
二、通用的坐标变换(通过变换矩阵进行变换)
除了以上3个坐标转换方法之外,Quartz 2D提供更通用的坐标转换方法。
1、void CGContextConcatCTM ( CGContextRef c, CGAffineTransform transform ):使用 transform 变换矩阵对 CGContextRef 的坐标系统执行变换,通过使用坐标矩阵可以对坐标系统执行任意变换。
2、CGAffineTransform CGContextGetCTM ( CGContextRef c ):获取CGContextRef的坐标系统的变换矩阵。
上述两个方法中都涉及一个关于矩阵的API:CGAffineTransform。
创建CGAffineTransform的4种方式:
CGAffineTransform CGAffineTransformMakeTranslation ( CGFloat tx, CGFloat ty )
:创建进行位移变换的变换矩阵。该函数的两个参数与前面介绍的位移变换的两个参数的作用相同。CGAffineTransform CGAffineTransformMakeScale ( CGFloat sx, CGFloat sy )
:创建进行缩放变换的变换矩阵。该函数的两个参数与前面介绍的缩放变换的两个参数的作用相同。CGAffineTransform CGAffineTransformMakeRotation ( CGFloat angle )
:创建进行旋转变换的变换矩阵。该函数的参数与前面介绍的旋转变换的参数的作用相同。CGAffineTransform CGAffineTransformMake ( CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty )
:该函数使用自定义变换矩阵执行变换。
其中 ( a, b, c, d )会形成变换矩阵,tx、ty为横向和纵向的位移,变换后结果应该为:
a, b
(x, y) x (c, d) + (tx, ty) = (xa x yc, xb x yd) + (tx, ty) =(xa x yc + , xb x yd + ty)。
一般坐标变换矩阵
1)水平镜像(绕 Y 轴做对称变化):CGAffineTransformMake ( -1, 0, 0, 1, 0, 0 )
-1, 0
0, 1
- 垂直镜像(绕 X 轴做对称变化):CGAffineTransformMake ( 1, 0, 0, -1, 0, 0 )
1, 0
0, -1
3)绕 x=y轴做对称变化:CGAffineTransformMake ( 0, 1, 1, 0, 0, 0 )
0, 1
1, 0
4)绕x =-y轴做对称变化:CGAffineTransformMake ( 0, -1, -1, 0, 0, 0 )
0, -1
-1, 0
5)做“水平倾斜”的变换,此时 Y 坐标无须变换,只要将 X 坐标增加 tan( angle ) x X 即可(angle 代表顺时针转过的角度):CGAffineTransformMake ( 1, 0, tan(angle), 1, 0, 0 )
1, 0
tan(angle), 1
6)做“垂直倾斜”的变换,此时 X 坐标无须变换,只要将 Y 坐标减少 tan( angle ) x X 即可:CGAffineTransformMake ( 1, -tan(angle), 0, 1 )
1, -tan(angle)
0, 1
三、复合矩阵坐标变换
CGAffineTransform CGAffineTransformTranslate ( CGAffineTransform t, CGFloat tx, CGFloat, ty ):对已有的变换矩阵 t 额外增加位移变换。
CGAffineTransform CGAffineTransformScale ( CGAffineTransform t, CGFloat sx, CGFloat sy ):对已有的变换矩阵 t 额外增加缩放变换。
CGAffineTransform CGAffineTransformRotate ( CGAffineTransform t, CGFloat angle ):对已有的变换矩阵 t 额外增加旋转变换。
CGAffineTransform CGAffineTransformInvert ( CGAffineTransform t ):对已有的变换矩阵 t 进行反转。
CGAffineTransform CGAffineTransformConcat ( CGAffineTransform t1, CGAffineTransform t2 ):将两个变换矩阵进行叠加。
四、对CGPoint、CGSize和CGRect进行坐标变换
CGPoint CGPointApplyAffineTransform ( CGPoint point, CGAffineTransform t ):对指定的CGPoint执行变换,函数返回坐标变换后的CGPoint。
CGSize CGSizeApplyAffineTransform ( CGSize size, CGAffineTransform t ):对指定的CGSize执行变换,函数返回坐标变换后的CGSize。
CGRect CGRectApplyAffineTransform ( CGRect rect, CGAffineTransform t ):对指定的CGRect执行变换,函数返回坐标变换后的CGRect。
五、对UIView进行坐标变换
UIView提供了一个transform属性,该属性支持设置CGAffineTransform变换矩阵,这样就可对UIView控件本身进行坐标变换,从而改变UIView控件本身的外观。