How can I check if a user tapped near a CGPath?
In iOS 5.0 and later, this can be done more simply using CGPathCreateCopyByStrokingPath
:
CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(path, NULL, 15,
kCGLineCapRound, kCGLineJoinRound, 1);
BOOL pointIsNearPath = CGPathContainsPoint(strokedPath, NULL, point, NO);
CGPathRelease(strokedPath);
if (pointIsNearPath) ...
Well, I figured out an answer. It uses CGPathApply:
clickArea = CGPathCreateMutable();
CGPathApply(path,clickArea,&createClickArea);
void createClickArea (void *info, const CGPathElement *elem) {
CGPathElementType type = elem->type;
CGMutablePathRef path = (CGMutablePathRef)info;
static CGPoint last;
static CGPoint subpathStart;
switch (type) {
case kCGPathElementAddCurveToPoint:
case kCGPathElementAddQuadCurveToPoint:
break;
case kCGPathElmentCloseSubpath:
case kCGPathElementMoveToPoint: {
CGPoint p = type == kCGPathElementAddLineToPoint ? elem->points[0] : subpathStart;
if (CGPointEqualToPoint(p,last)) {
return;
}
CGFloat rad = atan2(p.y - last.y, p.x - last.x);
CGFloat xOff = CLICK_DIST * cos(rad);
CGFloat yOff = CLICK_DIST * sin(rad);
CGPoint a = CGPointMake(last.x - xOff, last.y - yOff);
CGPoint b = CGPointMake(p.x + xOff, p.y + yOff);
rad += M_PI_2;
xOff = CLICK_DIST * cos(rad);
yOff = CLICK_DIST * sin(rad);
CGPathMoveToPoint(path, NULL, a.x - xOff, a.y - yOff);
CGPathAddLineToPoint(path, NULL, a.x + xOff, a.y + yOff);
CGPathAddLineToPoint(path, NULL, b.x + xOff, b.y + yOff);
CGPathAddLineToPoint(path, NULL, b.x - xOff, b.y - yOff);
CGPathCloseSubpath(path);
last = p;
break; }
case kCGPathElementMoveToPoint:
subpathStart = last = elem->points[0];
break;
}
}
Basically it's just my own method for ReplacePathWithStrokedPath, but it only works with lines for right now.