UIBezierPath路径的交集

时间:2015-04-26 10:35:05

标签: ios swift intersection uibezierpath

我正在尝试确定我绘制的UIBezierPath是否与另一个相交。

if path.containsPoint(touchPoint){
       println("captured \(touchPoint) ")              
}

但是,containsPoint(CGPoint:)对我不起作用,因为如果

则返回true

the point is considered to be within the path’s enclosed area or false if it is not

只是提供一个图形示例,这将返回true(我正在绘制虚线路径):

所以问题是:我如何检查我的touchPoint是否属于UIBezierPath,因为它遇到了该路径的特定点?

提前致谢

2 个答案:

答案 0 :(得分:1)

如果只是一个触摸点,你想要确定是否位于bezier路径的笔划内,你可以使用CGPathCreateCopyByStrokingPath来创建原始开放路径的封闭路径版本,试图进行测试。然后使用新创建的封闭路径,您可以使用containsPoint方法进行检查。

该博客文章详细介绍了该技术。 http://oleb.net/blog/2012/02/cgpath-hit-testing/

您可能需要扩展复制笔划的宽度以允许胖手指。例如,在博客文章中,他使命中测试路径至少达到35分。

答案 1 :(得分:0)

我对这个问题有点迟了,但最近我不得不解决类似的事情,这可能对那些偶然发现的人有所帮助:

是否接近该线?

我刚刚开源ClippingBezier可能会有所帮助。它在UIBezierPath上包含一个类别方法,用于确定输入点与路径的接近程度:

CGPoint pointOnPath = [path closestPointOnPathTo:touchPoint];
if(distance(pointOnPath, touchPoint) < 30){
   // point is close to path
}

这为您提供了与Ray的答案类似的解决方案。我不知道CGPathCreateCopyByStrokingPath的性能,但如果您需要使用手势实时进行此操作,您可能还想与ClippingBezier进行比较 - 它是为这种实时用例而设计的。

是否在最小边界框内?

相反,如果你想确定该点是否在Bezier路径的最小边界框内,而不仅仅是“关闭”路径,那么这有点棘手。

UIBezierPath的{​​{1}}属性不一定是最小边界框,它只是一个边界框。为了找到最低限度,我认为你必须:

  1. 围绕其中心逐渐旋转路径,检查每个90度旋转的最小边界
  2. 找到最小的旋转后,将相同的变换应用于touchPoint
  3. 然后检查将touchPoint转换为已转换路径的边界
  4. 这不会得到完全最小边界框,但在实践中它会足够接近。要获得确切的最小边界框,需要更多的数学运算as described in this SO answer