在iOS上组合相交CGPath

时间:2012-05-23 15:31:53

标签: ios drawing quartz-2d cgpath

我在正在处理的应用中遇到问题。假设我有两个相当复杂的CGPath,我将它们都添加到CGMutablePath(因此将它们组合在一起)。那么,在两条路径相交的地方,会有彼此内部的点。我想消除那些内部点,并基本上绘制路径的外部或轮廓。我很难搞清楚如何解决这个问题。

编辑:以下是我所谈论的一个例子。蓝色和红色框表示沿CGPath的点。红色框是两个路径中的点。我想以某种方式消除红点并重新绘制路径的轮廓。

enter image description here

4 个答案:

答案 0 :(得分:3)

你所描述的是路径内部的结合。

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

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

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

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

答案 1 :(得分:1)

多边形问题中的经典点。删除返回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]

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

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

答案 2 :(得分:1)

使用CGPathAddPath。超级好用。

答案 3 :(得分:0)

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

我们将这两个多边形视为A和B.无论哪个是哪个。

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

请注意,此解决方案仅适用于直边多边形。在涉及贝塞尔曲线路径的情况下,计算交点时变得更加困难,更不用说将光滑角与锐角组合的复杂性,或者是直线段的曲线。