给定一个CGPath,如何使其曲线?

在以下屏幕截图中:

在这里输入图像说明

当您拖动单词气球的尾部(从气球连接到人嘴的东西)时,形状曲线(如图片中两个气球尾部之间的差异所示)。 我想知道,这是怎么做的? 我假设你需要从一个CGPath开始,做一些事情,有没有人碰巧知道这是什么?

更新:所以,如果我想曲线以下形状:

在这里输入图像说明

我会使用下面的代码:

CGPathAddCurveToPoint(mutablePath, NULL, x1, y1, x2, y2 + constant, x5, y5); CGPathAddCurveToPoint(mutablePath, NULL, x3, y3, x4, y4 + constant, x5, y5); 

常数重新调整点2和点4的y位置以形成曲线?

您需要利用事实,在math上,一条直线段只是一种曲线段。

(比听起来容易,相信我。)

贝塞尔path段有一个叫做“顺序”的东西,它基本上决定了段中有多less个点,不计算你来自哪个点。

  • 直线段是一阶曲线,意味着它只有目标点。 这些“曲线”总是直线,因为没有任何控制点向着弯曲的方向。
  • 二次曲线是二阶曲线(一个控制点加上目的地)。
  • 三次曲线是三阶曲线(两个控制点)。
  • (math对此没有任何限制,但是Quartz在这里停止,没有你自己的光栅化器没有四阶曲线。)

这是重要的,因为任何低阶曲线(包括直线)都可以表示为高阶曲线

那秘密呢?

即使是一个直的尾巴, 使用曲线

(也就是说,一个三次曲线,因为你希望曲线沿着两个不同的方向:一个或多或less进入尾部,另一个或多或less沿着气球的边缘。

从尾部底部的两个点中的每一个点,都希望其中一个控制点位于目的地的一半左右。 这很多是无条件的。

每个控制点的方向给你三个选项:

直线尾巴

尾部的图片直线向下,尾部的尖端水平位于两个基点之间,控制点正好位于每个基点和尖端之间的中点。

注意沿着图像垂直中心的蓝线的两个控制点。

注意这两个控制点相对于它所连接的基点的方向。 它们向内倾斜,朝着尖端 – 实际上,正好在尖端的直线上。

斜尾

倾斜的尾巴的图片,但不是弯曲的。

在这里,尖端点不再在两个基点之间水平。 控制点已经移动,但是只能沿着对应的基点和尖端之间的直线的中点。

弯曲的尾巴

弯曲的尾巴的图片。

对于弯曲的尾巴,移动尖端, 但是将控制点保持在与直尾相同的位置 。 因此,尾巴开始直出(跟随控制点),但是当它离基点越远,它们的影响就会减弱,尾巴就开始向尖端弯曲。

这比在代码中直观描述要容易得多,因此您可能需要考虑使用类似PaintCode或Opacity的东西来使用钢笔工具绘制每种types的尾部,然后查看它为其生成的代码的样子。

您可以使用CGContextAddCurveToPoint()函数:

 CGContextMoveToPoint(ctx, x, y); CGContextAddCurveToPoint(ctx, outTangentX, outTangentY, inTangentX, inTangentY, newX, newY); ... // more points or whatever you need here CGContextFillPath(ctx); // Fill with white CGContextStrokePath(ctx); // stroke the edges with black 

input/输出切线可以被硬编码为基于图片的嘴上的点以及其与气泡气泡相遇的点看起来不错的东西。 你可能会尝试一些东西,比如把他们的angular度在垂直线和两点之间的直线的斜率之间的中间位置或者类似的东西当作出发点。