CodeV

4.4-检索路径的Bounds and Centers

UIBezierPath类包括bounds属性。它返回一个完全包含路径中所有点的矩形,包括控制点。如果将此属性想象成为路径的frame,但是原点几乎从不在零的位置,相反,它表示最顶部和最左边的点,或者用于构建路径的控制点。

Bounds是有用的,因为它们快速计算并为许多绘图任务提供足够好的近似值。图4-6显示了一个固有的缺点。当你使用比较严格的布局时,bounds不考虑图的曲线的真实范围。因此,bounds几乎总是超过实际边界范围。

图4-6

图4-6绿色渲染显示路径。紫色圆圈是用于构建该路径的控制点。虚线矩形表示路径的bounds属性(外部矩形)和真实边界(内部矩形)。虽然尺寸接近,但它们不相同,而且当您想要创建完美的图像时,这种差异可能很重要。

代码清单4-3转向使用Quartz CGPathGetPathBoundingBox()函数来检索更好的路径边界。这种方法需要更多的计算,因为函数必须在控制点之间进行插值以沿着每条曲线建立点,结果是远远优越于之前方法的。您需要对时间和处理器需要的开销进行精确权衡。

PathBoundingBox()函数返回如图4-6的内部矩形中所示的较近的边界。相关函数PathBoundingBoxWithLineWidth()扩展了这些边界,以考虑路径的lineWidth属性。在路径的边缘绘制描边,因此路径通常在每个方向上扩展线宽的一半。

代码清单4-3还包括使用普通:PathCenter()和精确:PathBoundingCenter()的结果计算路径中心的函数。后一版本为转换提供了更好的解决方案,其中精度很重要。(轻微误差会通过仿射变换而放大。)使用这些测量路径边界框的函数可确保更一致的最终结果。

Note

在我自己的开发中,我将清单4-3中的例程实现为UIBezierPath类别。

清单4-3 A Path’s Calculated Bounds

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Return calculated bounds
CGRect PathBoundingBox(UIBezierPath *path)
{
return CGPathGetPathBoundingBox(path.CGPath);
}

// Return calculated bounds taking line width into account
CGRect PathBoundingBoxWithLineWidth(UIBezierPath *path)
{
CGRect bounds = PathBoundingBox(path);
return CGRectInset(bounds, -path.lineWidth / 2.0f, -path.lineWidth / 2.0f);
}

// Return the calculated center point
CGPoint PathBoundingCenter(UIBezierPath *path)
{
return RectGetCenter(PathBoundingBox(path));
}

// Return the center point for the bounds property
CGPoint PathCenter(UIBezierPath *path)
{
return RectGetCenter(path.bounds);
}

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