用于点检测的宽贝塞尔曲线路径

Wide bezier path for point detection

我有一个复杂的路径,其中有几个贝塞尔曲线段连接在一起。该路径是动态的,用户可以在该路径内添加和删除点。

当我绘制路径时,我保存 UIBezierPath 副本,像这样:

CGContextBeginPath(context);
for (NSUInteger i = 0; i < _points.count - 1; i++)
{
    // ...
    CGContextAddCurveToPoint(context, cp1x, cp1y, cp2x, cp2y, endX, endY);
}
_path = [UIBezierPath bezierPathWithCGPath:CGContextCopyPath(context)];
CGContextStrokePath(context);

我用长按手势创建新点:

- (void)handleLongPress:(UILongPressGestureRecognizer *)recognizer
{
    // ...
    CGPoint point = [recognizer locationInView:self];
    if ([_path containsPoint:point])
    {
        // process point
    }
    // ...
}

但这需要用户在非常靠近路径的地方点击。我希望在路径周围有更宽的区域,我认为任何点击都是有效的(如线宽)。

如何配置UIBezierPath以允许更大的区域?我想让它控制这个区域的宽度。

以下是可能的解决方案:

CGPathRef pathCopy = CGContextCopyPath(context);
// 16 is the width of path where we want to have hit test
CGPathRef tapPath = CGPathCreateCopyByStrokingPath(pathCopy, NULL, 16, kCGLineCapButt, kCGLineJoinMiter, 0.6);
// this path will be used for hit test
_linePath = [UIBezierPath bezierPathWithCGPath:tapPath];
[_linePath closePath];

现在我们需要它的地方:

CGPoint point = [recognizer locationInView:self];
if ([_linePath containsPoint:point])
{
    // work with point
}