给定CGPath,如何使其曲线?

时间:2013-05-26 21:07:30

标签: iphone ios cocoa-touch core-graphics

在以下屏幕截图中:

enter image description here

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

更新:如果我想弯曲以下形状:

enter image description here

我会使用以下代码:

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

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

2 个答案:

答案 0 :(得分:6)

你需要利用这样一个事实:在数学上,直线段只是一种曲线段。

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

Bézier路径段具有称为“顺序”的东西,它基本上决定了段中有多少点,而不是计算你来自的点。

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

这很重要,因为任何低阶曲线 - 包括一条直线 - 都可以表示为高阶曲线

那么,秘密?

即使是直尾,也会使用曲线

(即,一条三次曲线,因为您希望曲线沿两个不同的方向前进:一个,或多或少进入尾部,另一个,或多或少沿着气球的边缘。)

从尾部底部的两个点中的每个点开始,您希望其中一个控制点大约是目的地的一半。这是无条件的。

每个控制点的方向为您提供三个选项:

直线尾巴

Picture of a tail straight down, with the tip of the tail horizontally between the two base points, and the control points exactly halfway between each base point and the tip point.

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

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

斜尾

Picture of a tail that is slanted, but not curved.

这里,尖端点在两个基点之间不再是水平的。控制点已移动,但仅限于:每个控制点仍然沿着相应基点和尖端之间的直线的一半。

弯曲的尾巴

Picture of a tail that is curved.

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

这在视觉上比在代码中更容易描述,因此您可能需要考虑使用PaintCode或Opacity这样的东西来使用钢笔工具绘制每种尾部,然后看看它们为它生成的代码看起来是什么等。

答案 1 :(得分:2)

您可以使用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

进/出切线可以硬编码为基于图片嘴上的点和它与气泡相遇的点看起来很好的东西。您可以尝试将它们的角度设置为在垂直和两点之间的直线斜率之间的中间位置或类似的起点。