CodeV

4.9-构建多边形路径

虽然UIBezierPath提供了简单的椭圆和矩形路径构建方法,但它不提供一个简单的多边形生成器。代码清单4-8填补了这个缺口,返回你要求边数的Bezier路径。它创建的一些基本形状如图4-10所示。

图4-10

图4-10这些多边形贝塞尔曲线路径由清单4-8生成。形状分别具有3,4,5和8边。

此函数通过将圆(2π弧度)分成所需的边数的段,然后从一个目标点到下一个目标点绘制线来创建其形状,最后一段关闭路径,避免在形状的起点绘制伪影(artifacts)。图4-11显示了当你没有正确闭合你的形状时你会遇到的效果。Quartz将该角点(拐角)视为两个线段,而不是正确的连接。

图4-11

图4-11通过闭合从最后一个点到原点的路径避免描边间隙。

所有返回的路径都使用单位大小,即它们适合在{0,0,1,1}形式的矩形内。你可以根据需要调整路径大小。此外,第一个点始终放在形状的顶部,因此,如果你打算返回一个正方形而不是一个菱形,请确保旋转90度。

清单4-8 生成多边形

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
UIBezierPath *BezierPolygon(NSUInteger numberOfSides)
{
if (numberOfSides < 3)
{
NSLog(@"Error: Please supply at least 3 sides");
return nil;
}

UIBezierPath *path = [UIBezierPath bezierPath];

// Use a unit rectangle as the destination
CGRect destinationRect = CGRectMake(0, 0, 1, 1);
CGPoint center = RectGetCenter(destinationRect);
CGFloat r = 0.5f; // radius

BOOL firstPoint = YES;
for (int i = 0; i < (numberOfSides – 1); i++)
{
CGFloat theta = M_PI + i * TWO_PI / numberOfSides;
CGFloat dTheta = TWO_PI / numberOfSides;

CGPoint p;
if (firstPoint)
{
p.x = center.x + r * sin(theta);
p.y = center.y + r * cos(theta);
[path moveToPoint:p];
firstPoint = NO;
}

p.x = center.x + rx * sin(theta + dTheta);
p.y = center.y + ry * cos(theta + dTheta);
[path addLineToPoint:p];
}

[path closePath];

return path;

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