CoreGraphics 学习摘记之 Transforms

本文深入探讨了Quartz2D中的坐标转换技术,包括用户空间与设备空间的区别,如何通过平移、旋转、缩放等操作来实现坐标转换,并提供了关键函数的使用示例。

The Quartz 2D drawing model defines two completely separate coordinate spaces: user space, which represents the document page, and device space, which represents the native resolution of a device. User space coordinates are floating-point numbers that are unrelated to the resolution of pixels in device space. When you want to print or display your document, Quartz maps user space coordinates to device space coordinates.

You can modify the default user space by operating on the current transformation matrix, or CTM. 

Modifying the Current Transformation Matrix

Before you transform the CTM, you need to save the graphics state so that you can restore it after drawing.

Translation moves the origin of the coordinate space by the amount you specify for the x and y axes. You call the function CGContextTranslateCTM to modify the x and y coordinates of each point by a specified amount. Figure 5-3 shows an image translated by 100 units in the x-axis and 50 units in the y-axis, using the following line of code:

CGContextTranslateCTM (myContext, 100, 50);
Figure 5-3  A translated image A translated image

Rotation moves the coordinate space by the angle you specify. You call the function CGContextRotateCTM to specify the rotation angle, in radians. Figure 5-4 shows an image rotated by –45 degrees about the origin, which is the lower left of the window, using the following line of code:

CGContextRotateCTM (myContext, radians(–45.));

The image is clipped because the rotation moved part of the image to a location outside the context. You need to specify the rotation angle in radians.

It’s useful to write a radians routine if you plan to perform many rotations.

#include <math.h>
static inline double radians (double degrees) {return degrees * M_PI/180;}
Figure 5-4  A rotated image A rotated image

Scaling changes the scale of the coordinate space by the x and y factors you specify, effectively stretching or shrinking the image. The magnitude of the x and y factors governs whether the new coordinates are larger or smaller than the original. In addition, by making the x factor negative, you can flip the coordinates along the x-axis; similarly, you can flip coordinates horizontally, along the y-axis, by making the y factor negative. You call the function CGContextScaleCTM to specify the x and y scaling factors. Figure 5-5 shows an image whose x values are scaled by .5 and whose y values are scaled by .75, using the following line of code:

CGContextScaleCTM (myContext, .5, .75);
Figure 5-5  A scaled image A scaled image

Concatenation combines two matrices by multiplying them together. You can concatenate several matrices to form a single matrix that contains the cumulative effects of the matrices. You call the function CGContextConcatCTM to combine the CTM with an affine transform. Affine transforms, and the functions that create them, are discussed in “Creating Affine Transforms.”

Another way to achieve a cumulative effect is to perform two or more transformations without restoring the graphics state between transformation calls. Figure 5-6 shows an image that results from translating an image and then rotating it, using the following lines of code:

CGContextTranslateCTM (myContext, w,h);
CGContextRotateCTM (myContext, radians(-180.));
Figure 5-6  An image that is translated and rotated An image that is translated and rotated

Creating Affine Transforms

The affine transform functions available in Quartz operate on matrices, not on the CTM. You can use these functions to construct a matrix that you later apply to the CTM by calling the function  CGContextConcatCTM
Table 5-1  Affine transform functions for translation, rotation, and scaling

Function

Use

CGAffineTransformMakeTranslation

To construct a new translation matrix from x and y values that specify how much to move the origin.

CGAffineTransformTranslate

To apply a translation operation to an existing affine transform.

CGAffineTransformMakeRotation

To construct a new rotation matrix from a value that specifies in radians how much to rotate the coordinate system.

CGAffineTransformRotate

To apply a rotation operation to an existing affine transform.

CGAffineTransformMakeScale

To construct a new scaling matrix from x and y values that specify how much to stretch or shrink coordinates.

CGAffineTransformScale

To apply a scaling operation to an existing affine transform.

Quartz also provides an affine transform function that inverts a matrix, CGAffineTransformInvert. Inversion is generally used to provide reverse transformation of points within transformed objects. Inversion can be useful when you need to recover a value that has been transformed by a matrix: Invert the matrix, and multiply the value by the inverted matrix, and the result is the original value. You usually don’t need to invert transforms because you can reverse the effects of transforming the CTM by saving and restoring the graphics state.

In some situations you might not want to transform the entire space, but just a point or a size. You operate on a CGPoint structure by calling the function CGPointApplyAffineTransform. You operate on a CGSize structure by calling the function CGSizeApplyAffineTransform. You can operate on a CGRect structure by calling the function CGRectApplyAffineTransform

Evaluating Affine Transforms

You can determine whether one affine transform is equal to another by calling the function  CGAffineTransformEqualToTransform .  The function CGAffineTransformIsIdentity is a useful function for checking whether a transform is the identity transform. The identity transform performs no translation, scaling, or rotation. 

Getting the User to Device Space Transform

Quartz provides a number of convenience functions to transform the following geometries between user space and device space. You might find these functions easier to use than applying the affine transform returned from the function CGContextGetUserSpaceToDeviceSpaceTransform.



先展示下效果 https://pan.quark.cn/s/a4b39357ea24 遗传算法 - 简书 遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向(最优解)进化,进化过程中,会自动选择优良基因,淘汰劣等基因。 遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。 进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择、杂交等。 搜索算法的共同特征为: 首先组成一组候选解 依据某些适应性条件测算这些候选解的适应度 根据适应度保留某些候选解,放弃其他候选解 对保留的候选解进行某些操作,生成新的候选解 遗传算法流程 遗传算法的一般步骤 my_fitness函数 评估每条染色体所对应个体的适应度 升序排列适应度评估值,选出 前 parent_number 个 个体作为 待选 parent 种群(适应度函数的值越小越好) 从 待选 parent 种群 中随机选择 2 个个体作为父方和母方。 抽取父母双方的染色体,进行交叉,产生 2 个子代。 (交叉概率) 对子代(parent + 生成的 child)的染色体进行变异。 (变异概率) 重复3,4,5步骤,直到新种群(parentnumber + childnumber)的产生。 循环以上步骤直至找到满意的解。 名词解释 交叉概率:两个个体进行交配的概率。 例如,交配概率为0.8,则80%的“夫妻”会生育后代。 变异概率:所有的基因中发生变异的占总体的比例。 GA函数 适应度函数 适应度函数由解决的问题决定。 举一个平方和的例子。 简单的平方和问题 求函数的最小值,其中每个变量的取值区间都是 [-1, ...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值