0

在以下屏幕截图中:

在此处输入图像描述

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

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

在此处输入图像描述

我会使用以下代码:

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

常数在哪里重新调整点 2 和点 4 的 y 位置以制作曲线?

4

2 回答 2

6

您需要利用这样一个事实,即从数学上讲,直线段只是一种曲线段。

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

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

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

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

那么,秘诀呢?

即使是笔直的尾巴,也要使用曲线

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

从尾部底部的两个点中的每一个,您希望控制点之一位于目的地的大约一半处。这么多是无条件的。

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

笔直的尾巴

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

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

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

斜尾

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

此处,尖端不再水平地位于两个基点之间。控制点移动了,但只是跟随:每个控制点仍然在相应基点和尖端之间的直线的一半处。

弯曲的尾巴

弯曲的尾巴的图片。

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

这比用代码描述要容易得多,因此您可能需要考虑使用诸如 PaintCode 或 Opacity 之类的东西来使用钢笔工具绘制每种尾巴,然后查看它们为它生成的代码是什么样子的。

于 2013-05-28T01:14:22.170 回答
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

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

于 2013-05-27T00:31:39.300 回答