【问题标题】:how to get buffer zone around a uibezierpath如何在uibezierpath周围获得缓冲区
【发布时间】:2011-06-29 11:48:36
【问题描述】:

我有一些 uibezierpaths。作为路径,它们并没有真正的厚度。 但是,我希望找到一种方法来定义路径周围的区域,例如这张图片中线条周围的灰色区域

基本上,我想测试绘制的线条是否落在线条周围的缓冲区内。 我以为这很简单,但事实证明它比我想象的要复杂得多。我可以使用 CGPathApply 函数来检查路径上的点,然后得到一个范围 + 或 - 每个点,但它比角度和曲线更复杂。有什么想法吗?

【问题讨论】:

    标签: ios nsbezierpath uibezierpath bounding


    【解决方案1】:

    扩展路径的宽度实际上是相当困难的。但是,你可以用更粗的宽度抚摸它,并获得几乎相同的效果。比如……

    CGContextSetRGBStrokeColor(context, 0.4, 0.4, 0.4, 1.0);
    [path setLineWidth:15];
    [path stroke];
    CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);
    [path setLineWidth:3];
    [path stroke];
    

    ...会产生与您问题中的图片类似的图片。但我怀疑这对你来说是新闻。

    真正的诀窍是测试“绘制的线是否在缓冲区内”。这个问题与我刚刚在another question 中为自己回答的问题非常相似。看看我在那里分享的LineSample.zip 代码。这实现了位图/按位数据比较,以像您需要的那样检测行上的命中。您可以将较粗的“缓冲区”路径绘制到位图中进行测试,并在您的视图中显示较细的线条。

    【讨论】:

    • 谢谢!我想知道如何处理这样的线宽。 (我在这里放的图像是通过简单的复制和粘贴+更改线条粗细制作的。但我想不出如何获得更改后粗细的边框,因为路径本身是相同的。我会看看 cos你分享了。非常感谢。
    • 这是一个很棒的应用程序。我需要一些时间来查看代码,但它应该对我的目标很有帮助。快速提问,在您的应用程序中,当我画一条穿过幽灵线的新线时,它会保持黑色,就好像它没有越过任何东西一样。我不知道这是不是故意的。
    • 是的,幽灵线(“失败”的线)只是留下了,所以你可以真正看到它们遵循的路径。 “阻挡”其他线条的唯一线条是黑色和绿色线条。请注意,在代码中,虚线是在视图中绘制的(这就是它们可见的原因),而不是在命中测试上下文中(这是测试新线段的一部分)。但是,请注意:我在该代码中采用了一些快捷方式,如果您使用它,您需要重新考虑。我可能会在稍作调整后更新示例,但我认为基本原则是合理的。
    • 好的。我实际上看过您之前引用的网站,但不太了解。使用您的代码,现在我可能会取得一些进展。我是一个初学者,所以可能需要一些时间才能弄清楚。但是,似乎基本逻辑是创建一个与我的路径相同的位图上下文层,但线要粗得多。然后测试绘制的线是否在其范围内。是对的吗?如果我能做到,那听起来很完美。由于我的一些台词实际上确实交叉,它可能最终会比你做的更容易。至少如果我能做到的话……
    • 祝你好运!仅供参考,该示例已更新,以摆脱我提到的快捷方式。如果您不必担心绘制的线与自身相交,则可以删除所有引用 hitProgressContext 的内容。
    【解决方案2】:

    基本上,您想检查是否有任何点落在路径周围指定大小的区域内。

    其实做起来很简单。首先,您需要一个值来定义要测试的路径周围的空间量。比如说20分。所以你需要做的是开始一个 FOR 循环,从 -20 到 20,在每次迭代时,创建路径的副本,转换路径的 x 和 y 坐标,检查它们。

    所有这些都在这个代码示例中更加清晰。

    CGPoint touchPoint = /*get the point*/;
    
    NSInteger space = 20;
    
    for (NSInteger i = -space; i < space; i++) {
    
        UIBezierPath *pathX = [UIBezierPath bezierPathWithCGPath:originalPath.CGPath];
        [pathX applyTransform:CGAffineTransformMakeTranslation(i, 0)];
    
        if ([pathX containsPoint:touchPoint]) {
            /*YEAH!*/
        }
    
        else {
            UIBezierPath *pathY = [UIBezierPath bezierPathWithCGPath:originalPath.CGPath];
            [pathY applyTransform:CGAffineTransformMakeTranslation(0, i)];
    
            if ([pathY containsPoint:touchPoint]) {
                /*YEAH!*/
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-28
      • 1970-01-01
      • 2018-05-27
      • 1970-01-01
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多