如何获得到CGPath的距离以进行命中测试? [英] How to get the distance to a CGPath for hit-testing?
问题描述
我有一个开放的CGPath/UIBezierPath,我想为其检测用户是否触摸了它,即一个点是否在距路径一定距离之内.路径是开放的(即线/曲线,而不是形状).它可以同时包含&"和&";弯曲的元素.我如何获得到路径的距离以进行命中测试?
I have an open CGPath/UIBezierPath for which I want to detect if the user touches it, i.e. whether a point is within a certain distance from the path. The path is open (i.e. a line/curve, not a shape). It can contain both straight & curved elements. How do I get the distance to the path to hit-test it?
推荐答案
似乎CGPath/UIBezierPath都没有执行此操作的功能.根据@nielsbot的建议,您可以使用 CGPathApply(…)
编写自定义实现.但是,计算到弯曲部分的距离并不是一件容易的事.
It seems neither CGPath/UIBezierPath has a function to do this. As per @nielsbot's suggestion, you could write a custom implementation using CGPathApply(…)
. Computing the distance to the curved parts is not so trivial though.
但是,我找到了一种实现原始目标的巧妙方法,对路径进行了命中测试: CGPathCreateCopyByStrokingPath(...)
.
However I have found a neat way to achieve my original goal, hit-testing the path: CGPathCreateCopyByStrokingPath(…)
.
- (BOOL)isPoint:(CGPoint)p withinDistance:(CGFloat)distance ofPath:(CGPathRef)path
{
CGPathRef hitPath = CGPathCreateCopyByStrokingPath(path, NULL, distance*2, kCGLineCapRound, kCGLineJoinRound, 0);
BOOL isWithinDistance = CGPathContainsPoint(hitPath, NULL, p, false);
CGPathRelease(hitPath);
return isWithinDistance;
}
为了获得更好的性能,您可以缓存hitPath.通过使用 CGPathAddPath(...)
For better performance, you can cache hitPath. Could also be used for closed paths by adding the original path to hitPath using CGPathAddPath(…)
这篇关于如何获得到CGPath的距离以进行命中测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!