Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何获得到命中测试CGPath的距离?_Objective C_Core Graphics_Cgpath - Fatal编程技术网

Objective c 如何获得到命中测试CGPath的距离?

Objective c 如何获得到命中测试CGPath的距离?,objective-c,core-graphics,cgpath,Objective C,Core Graphics,Cgpath,我有一个开放的CGPath/UIBezierPath,我想检测用户是否触摸它,即一个点是否在距离路径一定距离内。路径是开放的(即直线/曲线,而不是形状)。它可以包含直线图元和曲线图元。如何获取到路径的距离以点击测试它?似乎CGPath/UIBezierPath都没有这样做的功能。编辑:根据@nielsbot的建议,您可以使用cgpathpapply(…)编写自定义实现。计算到弯曲部分的距离并不是那么简单 然而,我找到了一个实现我最初目标的好方法,点击测试路径:CGPathCreateCopyBy

我有一个开放的CGPath/UIBezierPath,我想检测用户是否触摸它,即一个点是否在距离路径一定距离内。路径是开放的(即直线/曲线,而不是形状)。它可以包含直线图元和曲线图元。如何获取到路径的距离以点击测试它?

似乎CGPath/UIBezierPath都没有这样做的功能。编辑:根据@nielsbot的建议,您可以使用
cgpathpapply(…)
编写自定义实现。计算到弯曲部分的距离并不是那么简单

然而,我找到了一个实现我最初目标的好方法,点击测试路径:
CGPathCreateCopyByStrokingPath(…)

为了获得更好的性能,您可以缓存hitPath。也可以通过使用swift 3.0的
CGPathAddPath(…)
将原始路径添加到hitPath来用于闭合路径:

final func isPoint(point: CGPoint, withinDistance distance: CGFloat, ofPath path: CGPath) -> Bool {

    if let hitPath = CGPath( __byStroking: path,
                             transform: nil,
                             lineWidth: distance,
                             lineCap: CGLineCap.round,
                             lineJoin: CGLineJoin.miter,
                             miterLimit: 0) {

        let isWithinDistance = hitPath.contains(point)
        return isWithinDistance
    }
    return false
}
使用:

当然,正如Patrick所指出的,最好是缓存hitPath,而不是每次都创建hitPath。如果您有UIBezierPath,只需执行以下操作:

 let inside = self.isPoint(point: location, withinDistance: 4, ofPath: myUIPath.cgPath!)

可以迭代路径中的所有绘制命令(移动、直线到、曲线到)。这不允许您实现自己的路径距离函数吗?看起来CGPathApply()可能正是您所需要的。@nielsbot:谢谢,这是一个有用的函数。但是,计算到曲线的距离有些复杂(需要数值迭代)。答案已更新。距离以米为单位吗?@sjoerdperf它是以原始路径的任何单位表示的(因为CGPath本身是无单位的),所以这取决于你从哪里得到它。
let inside = self.isPoint(point: location, withinDistance: 4, ofPath: myPath!)
if inside{...
 let inside = self.isPoint(point: location, withinDistance: 4, ofPath: myUIPath.cgPath!)