如何确定CGPath的交集

时间:2011-07-20 05:48:26

标签: iphone objective-c

我的问题类似于this

我有2个CGPathRef,1个将通过手指触摸移动。我想找到2 CGPathRef是否相交?这个问题差不多是在两年前提出的,我想知道是否在某些时候找到了一些东西。

4 个答案:

答案 0 :(得分:9)

这是相当陈旧的,但我发现它寻找类似的解决方案,在我的问题中我想找到一个圆圈与路径重叠(你的问题的一个特例)。

我通过使用CGPathCreateCopyByStrokingPath使用圆的半径作为笔划宽度来创建原始路径的描边版本来解决这个问题。如果圆的中心点与描边路径重叠,则原始路径与圆重叠。

BOOL CGPathIntersectsCircle(CGPathRef path, CGPoint center, CGFloat radius)
{
    CGPathRef fuzzyPath;
    fuzzyPath = CGPathCreateCopyByStrokingPath(path, NULL, radius,
                                               kCGLineCapRound,
                                               kCGLineJoinRound, 0.0);
    if (CGPathContainsPoint(fuzzyPath, NULL, center, NO))
    {
        CGPathRelease(fuzzyPath);
        return YES;
    }
    CGPathRelease(fuzzyPath);
    return NO;
}

编辑:未发布fuzzyPath的小错误。

答案 1 :(得分:6)

我为CGPathRefs编写了一个基于小像素的路径冲突检测API。它要求你为项目添加一些源目录,它只适用于ARC,但它至少应该告诉你如何做这样的事情。它基本上在两个不同的上下文中绘制两条路径,然后逐像素检查以查看两条路径上是否有任何像素。显然,每次用户拖动手指时运行速度都会很慢,但它确实可以每半秒左右完成一次,甚至可能不在主线程上。

这是我发现做这样的事情的最简单方法,除了使用大量数学之外,很可能没有更好的方法。

答案 2 :(得分:1)

一般来说,找到两个任意CGPath的交集会非常复杂。

有几种方法可以进行近似。检查边界框的交叉点是一个很好的第一步。您还可以细分曲线并重复该过程以获得更好的近似值。另一个选择是展平路径并查看展平路径的任何线段是否相交。

然而,对于一般情况,事情变得非常讨厌非常快。例如,考虑这样一个事实,即两个立方贝塞尔曲线段(从不介意整个路径......只有一个曲线)可以与最多6个点的另一个曲线相交。路径中的段越多,潜在的交叉点就越多。还存在退化贝塞尔曲线的问题,其中段具有刚好接触另一段的一个点的尖点。这算是一个交集吗? (有时是,有时没有)

您的问题并不清楚,但您可能还想考虑应用于曲线的笔划的交叉点,并正确考虑线条连接和间距。那变得更难了。 Macromedia FreeHand(类似于Adobe Illustrator的绘图程序)具有非常大,复杂,强烈的数学库,用于发现任意贝塞尔曲线交点。问题不容易解决。

答案 3 :(得分:1)

要找到两个CAShapeLayers的交集,我们可以使用下面的方法,CAShapeLayer不会返回帧。但我们可以使用 CGPathGetBoundingBox 获取refPath帧。但是这个会给矩形框架。你可以理解的东西。

if (CGRectIntersectsRect(CGPathGetBoundingBox(layer.path), CGPathGetBoundingBox(layer.path)))