【问题标题】:Combining Intersecting CGPaths on iOS在 iOS 上组合相交的 CGPath
【发布时间】:2012-05-23 15:31:53
【问题描述】:

我正在开发的应用程序出现问题。假设我有两个相当复杂的 CGPath,我将它们都添加到 CGMutablePath 中(从而将它们组合起来)。好吧,两条路径相交的地方将有彼此内部的点。我想消除那些内部点并基本上绘制路径的外部或轮廓。我很难弄清楚该怎么做。

编辑:这是我所说的一个例子。蓝色和红色框表示沿 CGPath 的点。红色框是两条路径内的点。我想以某种方式消除红点并仅重绘路径的轮廓。

【问题讨论】:

标签: ios drawing quartz-2d cgpath


【解决方案1】:

您所描述的是路径内部的联合。

如果你的路径包含曲线,这是一个难题。

但是,您的示例仅显示直线段,因此我假设您只关心仅包含直线段的路径。

在这种情况下,您需要一个多边形联合函数。这种算法在称为“计算几何”的领域中非常基础。我不知道多边形联合的任何特定于 Objective-C 的实现。您可能能够找到一个纯 C 库,但找到 C++ 库要容易得多。如果将文件扩展名从 .m 更改为 .mm,则可以使用 C++。以下是一些可以计算多边形并集的 C++ 库:

请注意,在所有情况下,您都需要使用 CGPathApply 来提取路径的顶点(如果您还没有其他格式的顶点)。

【讨论】:

    【解决方案2】:

    多边形问题中的经典点。删除每个多边形中引用另一个多边形返回 1 的所有点:

    int pnpoly(int npol, float *xp, float *yp, float x, float y)
    {
      int i, j, c = 0;
      for (i = 0, j = npol-1; i < npol; j = i++) {
        if ((((yp[i] <= y) && (y < yp[j])) ||
             ((yp[j] <= y) && (y < yp[i]))) &&
            (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
          c = !c;
      }
      return c;
    }
    

    将两条路径与删除的点组合起来。

    整个过程的伪代码:

    define starPoly with 10 points
    define simplePoly with 7 points
    
    for each point in starPoly
        if ( pnpoly( 7, simplePoly.Xs[], simplePoly.Ys[], point.x, point.y ) == 0 )
            clipedStarPoly += point;
    
    for each point in simplePoly
        if ( pnpoly( 10, starPoly.Xs[], starPoly.Ys[], point.x, point.y ) == 0 )
            clipedSimplePoly += point;
    
    for each point in clipedStarPoly
        solutionPoly += point;
    
    for each point in clipedSimplePoly
        solutionPoly += point;
    
    solutionPoly += solutionPoly.point[0]
    

    如果您认为不必使用剪裁多边形的端点,您可以直接从点测试中构建解决方案多边形。

    您可能希望在多边形测试中对点使用光线追踪,尝试查看此page

    【讨论】:

    • 稍微解释一下如何使用它,在哪里使用它,以及它在做什么。
    • 嘿戴夫,解释够了吗?
    • 我想我理解得很好。我知道这只是伪代码,但我认为查看使用 CGPaths 的工作示例确实会有所帮助。
    • gjpc 这不是我问题的完整解决方案。我从来没有证实过,我只是简单地说我想我明白你的建议是什么。您只是在删除点,但由于我已经为这个问题尝试了很长一段时间的解决方案,它比这复杂得多。您不仅必须删除不需要的点,还必须在新的交叉点添加新点。此外,您的解决方案非常模糊,因为它不使用 CGPath 的细节,因此对于应该如何编写它有点混乱。
    • 我已经编程两年了,如果可以的话,我总是试图自己找出解决方案,但我不知道你在写什么,比如:“( pnpoly( 7, simplePoly.Xs[], simplePoly.Ys[], point.x, point.y ) == 0 )" 当我写“simplePoly.Xs[]”时我到底传递了什么?我从哪里得到“point.x”和“point.y”?原谅我的无知,但这似乎不是对我的问题的彻底或完整的答案,并且在目前的状态下并不保证赏金(无论我是否已经失去了它都无关紧要)。
    【解决方案3】:

    使用CGPathAddPath。超级好用。

    【讨论】:

      【解决方案4】:

      简单地合并两组点是不够的。为了确定组合多边形,您需要执行以下操作。对不起,我只有伪代码,我才刚刚开始研究这个问题。

      我们会认为这两个多边形是 A 和 B。不管哪个是哪个。

      • 在多边形 A 周围移动,寻找不在多边形 B 内的任何点。
      • 将此点添加到多边形。
      • 继续围绕多边形,依次测试和添加每个点。
      • 当您发现一个位于多边形 B 内的点时,请查看它与前一个点之间的线。
      • 找出多边形 B 上的哪条线与这条线相交。
      • 确定这两条线的交点并将其添加到多边形中。
      • 确定定义属于多边形 B 的相交线的两个点中的哪一个不在多边形 A 内,并将其添加到新多边形中。
      • 确定您需要围绕多边形 B 的哪个方向,以便下一个点不会是相交线另一端的那个点,然后添加它。
      • 从 3 开始重复,除了使用多边形 B 而不是多边形 A
      • 继续直到到达起点,必要时在多边形之间交换。

      请注意,此解决方案仅适用于直边多边形。就贝塞尔路径而言,计算交点变得更加困难,更不用说将平滑角与尖角或曲线与直线段相结合的复杂性了。

      【讨论】:

        猜你喜欢
        • 2012-06-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多