Quartz 2D编程指南 (四) —— Paths路径(一)

版本记录

版本号 时间
V1.0 2018.09.04

前言

Quartz 2D框架相信大家都知道,也都一直在使用。Quartz 2D的API是纯C语言的,它是一个二维绘图引擎,同时支持iOS和Mac系统。Quartz 2D的API来自于Core Graphics框架,数据类型和函数基本都以CG作为前缀,接下来几篇我们就一起来看一下这个框架。感兴趣可以看上面几篇文章。
1. Quartz 2D编程指南 (一) —— 简介(一)
2. Quartz 2D编程指南 (二) —— Quartz 2D概览(二)
3. Quartz 2D编程指南 (三) —— 图形上下文(三)

Paths - 路径

路径定义一个或多个形状或子路径。 子路径可以包含直线,曲线或两者。 它可以是开放的或封闭的。 子路径可以是简单的形状,例如线,圆,矩形或星形,或者更复杂的形状,例如山脉的轮廓或抽象涂鸦。 图3-1显示了您可以创建的一些路径。 直线(图中左上角)是虚线;线条也可以是实心的。 弯曲的路径(在中间的顶部)由几条曲线组成,是一条开放的路径。 同心圆被填充,但没有被描边。 加利福尼亚州是一条封闭的道路,由许多曲线和线条组成,路径既有描边也有填充。 星星说明了填充路径的两个选项,您将在本章后面阅读这些选项。

Quartz 2D编程指南 (四) —— Paths路径(一)_第1张图片
Figure 3-1 Quartz supports path-based drawing

在本章中,您将了解构成路径的构建块,如何描边和绘制路径以及影响路径外观的参数。


Path Creation and Path Painting - 路径创建与路径绘制

路径创建和路径绘制是单独的任务。 首先,您创建一个路径。 如果要渲染路径,请求Quartz绘制它。 如图3-1所示,您可以选择描边路径,填充路径,或者描边和填充路径。 您还可以使用路径来约束路径边界内其他对象的绘制,实际上是创建剪切区域。

图3-2显示了已绘制的路径,其中包含两个子路径。 左边的子路径是一个矩形,右边的子路径是由直线和曲线组成的抽象形状。 每个子路径都被填充并且其轮廓被描边。

Quartz 2D编程指南 (四) —— Paths路径(一)_第2张图片
Figure 3-2 A path that contains two shapes, or subpaths

图3-3显示了独立绘制的多条路径。 每条路径都包含一条随机生成的曲线,其中一些曲线已填充,另一些曲线则被描边。绘图通过裁剪区域约束到圆形区域。

Quartz 2D编程指南 (四) —— Paths路径(一)_第3张图片
Figure 3-3 A clipping area constrains drawing

The Building Blocks - 构建Block

子路径由线,弧和曲线构成。 Quartz还提供了便捷功能,可通过单个函数调用添加矩形和椭圆。 点也是路径的基本构建块,因为点定义了形状的起始和结束位置。

1. Points - 点

点是x和y坐标,用于指定用户空间中的位置。 您可以调用函数CGContextMoveToPoint来指定新子路径的起始位置。 Quartz跟踪当前点,这是用于路径构建的最后位置。 例如,如果调用函数CGContextMoveToPoint将位置设置为(10,10),则会将当前点移动到(10,10)。 如果然后绘制一条长50个单位的水平线,则该线上的最后一个点(60,10)将成为当前点。 始终从当前点开始绘制直线,圆弧和曲线。

大多数情况下,通过向Quartz函数传递两个浮点值来指定一个点来指定x和y坐标。 某些函数要求您传递CGPoint数据结构,该结构包含两个浮点值。

2. Lines - 线

一条线由其端点定义。 它的起始点始终假定为当前点,因此在创建线时,只指定其端点。 使用函数CGContextAddLineToPoint将单行线附加到子路径。

您可以通过调用函数CGContextAddLines将一系列连接的线添加到路径中。 您将此函数传递给一系列点。 第一点必须是第一行的起点,剩下的点是端点。 Quartz在第一个点开始一个新的子路径,并将一个直线段连接到每个端点。

3. Arcs - 弧

弧是圆弧段。 Quartz提供了两个创建弧的函数。 函数CGContextAddArc从圆创建一个弯曲的段。 您可以指定圆的中心,半径和径向角(以弧度表示)。 您可以通过指定2 pi的径向角度来创建整圆。 图3-4显示了独立绘制的多条路径。 每条路径包含一个随机生成的圆;有些被填满,有些被描边。

Quartz 2D编程指南 (四) —— Paths路径(一)_第4张图片
Figure 3-4 Multiple paths; each path contains a randomly generated circle

当您想要对矩形的角进行圆角时,CGContextAddArcToPoint函数是理想的选择。 Quartz使用您提供的端点来创建两条切线。 您还提供了Quartz切割圆弧的圆的半径。 弧的中心点是两个半径的交点,每个半径垂直于两条切线中的一条。 弧的每个端点都是其中一条切线上的切点,如图3-5所示。 圆圈的红色部分实际上是绘制的。

Quartz 2D编程指南 (四) —— Paths路径(一)_第5张图片
Figure 3-5 Defining an arc with two tangent lines and a radius

如果当前路径已包含子路径,则Quartz会将当前点的直线段附加到弧的起始点。 如果当前路径为空,Quartz会在弧的起始点创建一个新的子路径,并且不会添加初始直线段。

4. Curves - 曲线

二次和三次Bézier曲线是代数曲线,可以指定任意数量的有趣曲线形状。 通过将多项式公式应用于起点和终点以及一个或多个控制点来计算这些曲线上的点。 以这种方式定义的形状是矢量图形的基础。 公式比位数组更紧凑更容易存储,并且具有可以在任何分辨率下重新创建曲线的优点。

图3-6显示了通过独立绘制多个路径创建的各种曲线。 每条路径包含一条随机生成的曲线;有些被填满,有些被描边。

Quartz 2D编程指南 (四) —— Paths路径(一)_第6张图片
Figure 3-6 Multiple paths; each path contains a randomly generated curve

在许多数学文本和描述计算机图形的在线资源中讨论了产生二次和三次Bézier曲线的多项式公式,以及如何从公式生成曲线的细节。 这里不讨论这些细节。

使用CGContextAddCurveToPoint函数,使用您指定的控制点和端点,从当前点追加三次贝塞尔曲线。 图3-7显示了由图中所示的当前点,控制点和端点产生的三次Bézier曲线。 两个控制点的放置决定了曲线的几何形状。 如果控制点都在起点和终点之上,则曲线向上拱起。 如果控制点都低于起点和终点,则曲线向下拱起。

Quartz 2D编程指南 (四) —— Paths路径(一)_第7张图片
Figure 3-7 A cubic Bézier curve uses two control points

您可以通过调用CGContextAddQuadCurveToPoint函数并指定控制点和端点,从当前点追加二次Bézier曲线。 图3-8显示了使用相同端点但控制点不同的两条曲线。 控制点确定曲线拱起的方向。 由于二次曲线仅使用一个控制点,因此不可能使用二次贝塞尔曲线创建尽任意多的有趣形状。 例如,无法使用单个控制点创建交叉。

Quartz 2D编程指南 (四) —— Paths路径(一)_第8张图片
Figure 3-8 A quadratic Bézier curve uses one control point

5. Closing a Subpath - 关闭子路径

要关闭当前子路径,应用程序应调用CGContextClosePath。 此函数添加从当前点到子路径起点的线段,并关闭子路径。 以子路径起点结束的直线,圆弧和曲线实际上不会关闭子路径。 您必须显式调用CGContextClosePath才能关闭子路径。

一些Quartz函数将路径的子路径视为应用程序关闭它们。 这些命令将每个子路径视为您的应用程序调用CGContextClosePath来关闭它,隐式地将一个线段添加到子路径的起始点。

关闭子路径后,如果应用程序进行额外调用以向路径添加直线,圆弧或曲线,Quartz将从刚刚关闭的子路径的起点开始一个新的子路径。

6. Ellipses - 椭圆

椭圆本质上是一个压扁的圆圈。 您可以通过定义两个焦点来创建一个焦点,然后绘制位于一定距离的所有点,以便将椭圆上任意点到一个焦点的距离加上到从该点到另一个焦点的距离这个和始终是相同的值。 图3-9显示了独立绘制的多条路径。 每条路径包含一个随机生成的椭圆;有些被填满,有些被描边。

Quartz 2D编程指南 (四) —— Paths路径(一)_第9张图片
Figure 3-9 Multiple paths; each path contains a randomly generated ellipse

您可以通过调用函数CGContextAddEllipseInRect将椭圆添加到当前路径。 您提供了一个定义椭圆边界的矩形。 Quartz使用一系列Bézier曲线近似椭圆。 椭圆的中心是矩形的中心。 如果矩形的宽度和高度相等(即正方形),则椭圆为圆形,半径等于矩形宽度(或高度)的一半。 如果矩形的宽度和高度不相等,则它们定义椭圆的长轴和短轴。

添加到路径的椭圆以移动操作开始,以关闭子路径操作结束,所有移动都以顺时针方向定向。

7. Rectangles - 矩形

您可以通过调用函数CGContextAddRect将矩形添加到当前路径。 您提供了一个CGRect结构体,其中包含矩形的原点及其宽度和高度。

添加到路径的矩形以移动操作开始,以关闭子路径操作结束,所有移动都以逆时针方向定向。

您可以通过调用CGContextAddRects函数并提供CGRect结构数组,将许多矩形添加到当前路径。 图3-10显示了独立绘制的多条路径。 每个路径包含一个随机生成的矩形;有些被填满,有些被描边。

Quartz 2D编程指南 (四) —— Paths路径(一)_第10张图片
Figure 3-10 Multiple paths; each path contains a randomly generated rectangle

Creating a Path - 创建路径

如果要在图形上下文中构造路径,可以通过调用函数CGContextBeginPath来发出Quartz信号。接下来,通过调用函数CGContextMoveToPoint,在路径中设置第一个形状或子路径的起点。建立第一个点后,可以在路径中添加直线,圆弧和曲线,请记住以下内容:

  • 在开始新路径之前,请调用函数CGContextBeginPath
  • 从当前点开始绘制直线,圆弧和曲线。空路径没有当前点;你必须调用CGContextMoveToPoint来设置第一个子路径的起始点,或者调用一个方便的函数,隐式地为你做这个。
  • 如果要关闭路径中的当前子路径,请调用函数CGContextClosePath以将段连接到子路径的起始点。即使您未明确设置新的起点,后续路径调用也会开始新的子路径。
  • 绘制弧时,Quartz在当前点和弧的起点之间绘制一条线。
  • 添加椭圆和矩形的Quartz例程向路径添加新的闭合子路径。
  • 您必须调用绘制函数来填充或描边路径,因为创建路径不会绘制路径。有关详细信息,请参阅Painting a Path。

绘制路径后,将从图形上下文中刷新它。您可能不希望如此轻易地丢失路径,特别是如果它描绘了您想要反复使用的复杂场景。因此,Quartz提供了两种用于创建可重用路径的数据类型-CGPathRef和CGMutablePathRef。您可以调用函数CGPathCreateMutable来创建可变的CGPath对象,您可以在其中添加直线,圆弧,曲线和矩形。 Quartz提供了一组CGPath函数,这些函数与The Building Blocks中讨论的函数并行。路径函数在CGPath对象上运行,而不是在图形上下文上运行。这些函数是:

  • CGPathCreateMutable,它替换了CGContextBeginPath
  • CGPathMoveToPoint,它取代了CGContextMoveToPoint
  • CGPathAddLineToPoint,它取代了CGContextAddLineToPoint
  • CGPathAddCurveToPoint,它取代了CGContextAddCurveToPoint
  • CGPathAddEllipseInRect,替换CGContextAddEllipseInRect
  • CGPathAddArc,它取代了CGContextAddArc
  • CGPathAddRect,它取代了CGContextAddRect
  • CGPathCloseSubpath,替换CGContextClosePath

有关路径函数的完整列表,请参阅Quartz 2D Reference Collection

如果要将路径附加到图形上下文,请调用函数CGContextAddPath。路径保留在图形上下文中,直到Quartz绘制它。您可以通过调用CGContextAddPath再次添加路径。

注意:您可以通过调用函数CGContextReplacePathWithStrokedPath将图形上下文中的路径替换为路径的描边版本。

后记

本篇主要讲述了Paths路径,感兴趣的给个赞或者关注~~~

Quartz 2D编程指南 (四) —— Paths路径(一)_第11张图片

你可能感兴趣的:(Quartz 2D编程指南 (四) —— Paths路径(一))