您所描述的操作是联合。通常,计算一组多边形的联合相当复杂。以高效和准确的方式执行此操作更加复杂。iOS没有提供此操作的公共API。
我建议您考虑使用现有的C或C ++库来执行此操作。以下是一些:
您可以从这些页面的链接或使用您喜欢的搜索引擎找到其他库。有用的搜索词包括“多边形”,“几何”,“联合”和“剪辑”。
我了解到您只是绘制一个多边形。尽管如此,在至少Clipper库的情况下,联合操作可以实现您所要求的操作:
白色背景上的多边形是我通过点击创建的星形。它与自己相交。我使用Clipper的联合操作创建了绿色背景上的多边形。我将点击出的多边形作为主体,没有剪辑多边形:
- (UIBezierPath *)pathWithManyPoints:(CGPoint const *)points count:(NSUInteger)count {
Path subject;
for (NSUInteger i = 0; i < count; ++i) {
subject << IntPoint(points[i].x, points[i].y);
}
Clipper clipper;
clipper.AddPath(subject, ptSubject, true);
Paths solutions;
clipper.Execute(ctUnion, solutions, pftNonZero, pftNonZero);
UIBezierPath *path = [UIBezierPath bezierPath];
for (size_t i = 0; i < solutions.size(); ++i) {
Path& solution = solutions[i];
if (solution.size() > 0) {
[path moveToPoint:cgPointWithIntPoint(solution[0])];
for (size_t j = 1; j < solution.size(); ++j) {
[path addLineToPoint:cgPointWithIntPoint(solution[j])];
}
[path closePath];
}
}
return path;
}
另一方面,如果给定一个更复杂的输入多边形,您可能希望进行一些修改:
- (UIBezierPath *)pathWithManyPoints:(CGPoint const *)points count:(NSUInteger)count {
Path subject;
for (NSUInteger i = 0; i < count; ++i) {
subject << IntPoint(points[i].x, points[i].y);
}
Clipper clipper;
clipper.AddPath(subject, ptSubject, true);
Paths intermediateSolutions;
clipper.Execute(ctUnion, intermediateSolutions, pftNonZero, pftNonZero);
clipper.Clear();
for (size_t i = 0; i < intermediateSolutions.size(); ++i) {
if (Orientation(intermediateSolutions[i])) {
reverse(intermediateSolutions[i]);
}
}
clipper.AddPaths(intermediateSolutions, ptSubject, true);
Paths solutions;
clipper.Execute(ctUnion, solutions, pftNonZero, pftNonZero);
UIBezierPath *path = [UIBezierPath bezierPath];
for (size_t i = 0; i < solutions.size(); ++i) {
Path& solution = solutions[i];
if (solution.size() > 0) {
[path moveToPoint:cgPointWithIntPoint(solution[0])];
for (size_t j = 1; j < solution.size(); ++j) {
[path addLineToPoint:cgPointWithIntPoint(solution[j])];
}
[path closePath];
}
}
return path;
}
要使用JavaScript代码,您可以查看this答案:
在iOS 7中引入的JavascriptCore框架中的Objective-C接口允许从Javascript调用Objective-C方法。有关这些功能的详细介绍,请参阅苹果开发人员网络上2013 WWDC介绍“将JavaScript集成到本地应用程序中”的会话:https://developer.apple.com/videos/wwdc/2013/?id=615
它提到了JS-> Objective-C,但JSCore也可以反过来工作。
否则,正如有人建议的那样,将JS代码“翻译”应该相当容易,因为它只是数学计算。
稍加思考:
(请参见关于从UIBezierPath
中获取路径的早期错误评论的注释)
UIBezierPath
的几何形状,您可以获取它的 CGPath
并使用 CGPathApply
遍历路径元素。 - Nikolai Ruhe
UIBezierPath
不会为您完成任何此类操作。您只会使用它来渲染您构建的最终路径。但是您需要自己编写相当多的例程:您需要一个“查找两条线段之间的交点”例程,然后有了这个,您可以编写一个“从找到的交点数组中选择最近的交点”的例程。您可能还需要一个“计算三个点之间的角度”的算法。但是,有了这些工具,您就可以实现该算法。 - Rob