Core Animation 阅读随笔 第五章 - 变换

16/04/25 第五章 变换

仿射变换 CGAffineTransform

  1. CGAffineTransform是一个3*2的矩阵,可以和二维空间向量做乘法. 主要用于平移,旋转,缩放.
  2. 当对图层应用变换矩阵,图层矩形内的每一个点都被相应地做变换,从而形成一个新的四边形的形状。CGAffineTransform中的“仿射”的意思是无论变换矩阵用什么值,图层中平行的两条线在变换之后任然保持平行,CGAffineTransform可以做出任意符合上述标注的变换.
  3. Core Graphics提供了一系列函数来帮助完全没有数学基础的开发者.
  4. UIView可通过transform进行变换, 事实上UIViewtransform封装了CALayeraffineTransform.
  5. CALayer也有一个transform属性,类型是CATransform3D.
  6. 弧度与角度换算宏

    #define RADIANS_TO_DEGREES(x) ((x)/M_PI*180.0)
    #define DEGREES_TO_RADIANS(x) ((x)/180.0*M_PI)

-

混合变换

Core Graphics提供了一系列的函数可以在一个变换的基础上做更深层次的变换,如果做一个既要缩放又要旋转的变换,这就会非常有用了。例如下面几个函数:

CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
当操纵一个变换的时候,初始生成一个什么都不做的变换很重要–也就是创建一个CGAffineTransform类型的空值,矩阵论中称作单位矩阵,Core Graphics同样也提供了一个方便的常量:

CGAffineTransformIdentity
最后,如果需要混合两个已经存在的变换矩阵,就可以使用如下方法,在两个变换的基础上创建一个新的变换:

CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);

-

3D变换 - CATransform3D

CG的前缀告诉我们,CGAffineTransform类型属于Core Graphics框架,Core Graphics实际上是一个严格意义上的2D绘图API,并且CGAffineTransform仅仅对2D变换有效。

在第三章中,我们提到了zPosition属性,可以用来让图层靠近或者远离相机(用户视角),transform属性(CATransform3D类型)可以真正做到这点,即让图层在3D空间内移动或者旋转。

和CGAffineTransform类似,CATransform3D也是一个矩阵,但是和2x3的矩阵不同,CATransform3D是一个可以在3维空间内做变换的4x4的矩阵

  1. CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z)
    CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz)
    CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz)

  2. 以旋转为例, 当只是设置了旋转角度和坐标轴时, 显示结果并不是3D效果, 需要设置矩阵内的m34属性进行透视投影.

透视投影

  1. CATransform3D的透视效果通过一个矩阵中一个很简单的元素来控制:m34
  2. m34用于按比例缩放X和Y的值来计算到底要离视角多远.
  3. m34默认值为0,可通过设置m34为-1.0 / d来应用透视效果,d代表了想象中视角相机和屏幕之间的距离,以像素为单位. 距离并不重要,可以通过运行来估算一个. 通常为500-1000.

    1
    2
    3
    4
    5
    6
    7
      CATransform3D transform = CATransform3DIdentity;

    transform.m34 = - 1.0 / 500.0;

    transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);

    self.layerView.layer.transform = transform;

灭点

  1. 当在透视角度绘图的时候,远离相机视角的物体将会变小变远,当远离到一个极限距离,它们可能就缩成了一个点,于是所有的物体最后都汇聚消失在同一个点。

  2. 当改变一个图层的position,你也改变了它的灭点,做3D变换的时候要时刻记住这一点,当你视图通过调整m34来让它更加有3D效果,应该首先把它放置于屏幕中央,然后通过平移来把它移动到指定位置(而不是直接改变它的position),这样所有的3D图层都共享一个灭点。这样做非常麻烦, 可以通过sublayerTransform属性来统一设置灭点(灭点在容器图层中点),可以随意使用position和frame来放置子图层,而不需要把它们放置在屏幕中点,然后为了保证统一的灭点用变换来做平移

待续...