Quartz 2d中的图形变换

来源:互联网 发布:php wms 编辑:程序博客网 时间:2024/06/05 21:17

我们已经知道,你的应用程序在用户空间的与分辨率无关的图形环境中构建图形,在计算机在设备上生成图形之前,它必须首先将图形移到设备空间中。计算机使用一种变换工具将图形从一个坐标系统移到另外一个坐标系统中。

Quartz 2D包括一系列用于创建和组合的变换工具。你的应用程序可以利用这些工具可以大大简化你的绘图过程。通常的做法是选择一个便利的坐标系统去绘制你的图形。然后你可以使用Quartz 2D API中的一些工具创建变换,建立坐标系统。用这种方式使用变换会花费一些时间,但是一旦你做了之后,你就会惊讶地发现以前没有它们我们是怎样进行绘图的。

许多计算机图形库使用矩阵描述变换,Quartz 2D也不例外。像其他的图形库一样,它用使用线性代数去进行变换一些几何物体像点,矩形,线。

The Basic Transformations

当你考虑变换的时候,你可以使用两种不同的方式思考它们。一种是你考虑给一系列的物体应用一种转换去改变这些物体的几何形状。用修改后的几何体在一个新的位置上重新绘制这些物体。如下图所示:


在上图中,左边时原始物体,经过逆时针旋转这个物体,然后将它向上和向右移动,变换成为右边的物体。在坐标系统固定的情形下去改变图形。

除了去变换图形外,你也可以变换坐标系统

当变换一个坐标系统时,相比之下,你必须有另外一个坐标系统。这种变换提供了一种从一个坐标系统变换到另外一个坐标系统的映射。如下图所示:


Affine Transform

Quartz 2D并不支持任意的图形变换。Quartz 2D支持的变换被称为放射变换。你可以结合简单的仿射变换生成更加复杂的图形。Quartz 2D支持的三种基本的变换类型Translations, Rotations, and Scalings。我们将会分别简单介绍然后将如何使用Quartz 2D API去进行结合。

Translations

Translations就是把一个物体从一个位置移到另外一个位置。如下图所示:


Translations变换中,你的代码中需要指定你想应用在xy方向的偏移量。

Rotations

Rotations允许你改变一个图形的方向,或者改变两个坐标系的相对位置。基本的旋转仿射矩阵是围绕着原点旋转的。如下图所示:


rotation中,你需要想计算机提供你想要旋转物体或者轴的角度值。在Quartz 2D中,角度的测量方法如下图所示:


角度和弧度的转换公式如下:


degrees (角度),radians(弧度)。

Scaling

Scaling就是让一个图形变大或者变小。如下图所示:


Quartz 2D中,你需要分别为坐标轴提供比例因子。在上图中,我们将y轴的每个单元扩大了2.25倍,x轴的每个单元扩大了1.5倍。

当你在坐标轴上扩大的值是负值的时候,就会出现一个有趣的现象。它不仅仅改变了每个单元的相对刻度,也改变了相应坐标轴的方向。

Concatenating Transformations

组合变换,Quartz 2D使用矩阵乘法,将一系列连锁的变换映射到单个矩阵上。如下图所示:


我们结合了三种不同的变换完成了旋转。图a显示了一张图形(一把雨伞)的初始位置。目标就是围绕着它的中心将它旋转30°。然而旋转仅仅围绕着原点旋转,所以我们需要使用一种变换将它放到原点位置图b,然后旋转它图c,最后用另一种变换技术将它移到最初的位置图d

如果雨伞的中心点在(100,100),下面的代码片段描述了这种变换:

CGAffineTransform affineTransform = CGAffineTransformIdentity;

affineTransform = CGAffineTransformConcat(

                   affineTransform,

                   CGAffineTransformMakeTranslation(-100, -100));

affineTransform = CGAffineTransformConcat(

                   affineTransform,

                   CGAffineTransformMakeRotation(pi / 6));

affineTransform = CGAffineTransformConcat(

                   affineTransform,

                   CGAffineTransformMakeTranslation(100, 100));

 

CGPathRef transformedPath = CopyPathWithTransformation(

                   umbrellaPath, affineTransform);

The Order Matters

当你在进行组合变换时,你必须以一个合适的顺序进行。