CodeV

5.4-路径后面的数学

正如你现在看到的,UIBezierPath类支持三种贝塞尔段:直线,二次曲线和三次曲线。其中每个都能参与创建UIKit和Quartz绘图程序的复杂形状。检索组件直线和曲线使您能够计算其长度并沿其路径插值。有了这些知识,您可以在计算的点应用绘图函数,如图5-3所示。

图5-3

图5-3这胡萝卜是沿着胡萝卜路径以等间隔放置的贝塞尔兔子图像绘制的。

不幸的是,CGPathElement结构体在这里帮不上忙。它提供了一个元素类型,可以是以下之一:移动到点,添加线到点,添加三次曲线到点,添加二次曲线到点,或关闭路径。那么如何计算一个点和下一个点之间的中间点呢?

使用线性项目,很容易。您计算从一个点到下一个点的向量,并将其缩放为进度的百分比。代码清单5-4显示了一个内插函数。

清单5-4在线段上插值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Interpolate between p1 and p2
CGPoint InterpolateLineSegment(
CGPoint p1, CGPoint p2,
CGFloat percent, CGPoint *slope)
{
CGFloat dx = p2.x - p1.x;
CGFloat dy = p2.y - p1.y;

if (slope)
*slope = CGPointMake(dx, dy);

CGFloat px = p1.x + dx * percent;
CGFloat py = p1.y + dy * percent;

return CGPointMake(px, py);
}

但是给定一个曲线,你如何内插呢?幸运的是,您可以应用UIBezierPath类使用的相同的曲线数学。清单5-5提供了三次(两个控制点)和二次(一个控制点)插值的函数,来计算这些值。您提供进度的百分比(从0到1),起始值,结束值和一个或两个控制值。函数则返回插值点。

清单5-5内插贝塞尔曲线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Calculate Cubic curve
CGFloat CubicBezier(CGFloat t, CGFloat start,
CGFloat c1, CGFloat c2, CGFloat end)
{
CGFloat t_ = (1.0 - t);
CGFloat tt_ = t_ * t_;
CGFloat ttt_ = t_ * t_ * t_;
CGFloat tt = t * t;
CGFloat ttt = t * t * t;

return start * ttt_ + 3.0 * c1 * tt_ * t
+ 3.0 * c2 * t_ * tt + end * ttt;
}

// Calculate quad curve
CGFloat QuadBezier(CGFloat t, CGFloat start,
CGFloat c1, CGFloat end)
{
CGFloat t_ = (1.0 - t);
CGFloat tt_ = t_ * t_;
CGFloat tt = t * t;

return start * tt_ + 2.0 * c1 * t_ * t + end * tt;
}

// Interpolate points on a cubic curve
CGPoint CubicBezierPoint(CGFloat t, CGPoint start, CGPoint c1, CGPoint c2, CGPoint end)
{
CGPoint result;
result.x = CubicBezier(t, start.x, c1.x, c2.x, end.x);
result.y = CubicBezier(t, start.y, c1.y, c2.y, end.y);
return result;
}

// Interpolate points on a quad curve
CGPoint QuadBezierPoint(CGFloat t,
CGPoint start, CGPoint c1, CGPoint end)
{
CGPoint result;
result.x = QuadBezier(t, start.x, c1.x, end.x);
result.y = QuadBezier(t, start.y, c1.y, end.y);
return result;
}

本文翻译自《iOS Drawing Practical UIKit Solutions》作者:Erica Sadun,翻译:Cheng Dong。如果觉得本书不错请购买支持正版:亚马逊购买传送门,本书所有源代码可在GitHub上下载。译者虽然力求做到信,达,雅,但是由于时间仓促加之译者水平十分有限,文中难免会出现不正确,不准确,词不达意,难于理解的地方,还望各位批评指正,共同进步,谢谢。转载请注明出处。