我正在开发的应用程序有问题。假设我有两个相当复杂的 CGPath,我将它们都添加到 CGMutablePath 中(从而将它们组合起来)。好吧,两条路径相交的地方将有彼此内部的点。我想消除那些内部点并基本上绘制路径的外部或轮廓。我很难弄清楚我将如何去做。
编辑:这是我正在谈论的一个例子。蓝色和红色框表示沿 CGPath 的点。红色框是两条路径内的点。我想以某种方式消除红点并仅重绘路径的轮廓。
您所描述的是路径内部的结合。
如果您的路径包含曲线,这是一个难题。
但是,您的示例仅显示直线段,因此我假设您只关心仅包含直线段的路径。
在这种情况下,您需要一个多边形联合函数。这种算法在称为“计算几何”的领域中非常基础。我不知道多边形联合的任何特定于 Objective-C 的实现。您可能能够找到一个纯 C 库,但找到 C++ 库要容易得多。如果将文件扩展名从 更改为 ,则可以使用 C .m
++ .mm
。以下是一些可以计算多边形并集的 C++ 库:
Polygon::Union
union_
CGPathApply
请注意,在所有情况下,如果您还没有其他格式的顶点,您都需要使用它来提取路径的顶点。
多边形问题中的经典点。删除每个多边形中引用另一个多边形返回 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 测试中对点使用光线追踪,请尝试查看此页面
使用CGPathAddPath。超级容易使用。
简单地合并两组点是不够的。为了确定组合多边形,您需要执行以下操作。对不起,我只有伪代码,我才刚刚开始研究这个问题。
我们将考虑这两个多边形是 A 和 B。哪个是哪个都没有关系。
请注意,此解决方案仅适用于直边多边形。就贝塞尔路径而言,计算交点变得更加困难,更不用说将平滑角与尖角或曲线与直线段相结合的复杂性。