iOS 16中有CGPath(核心图形)的新功能,更准确地说,有一个函数交集(_:using:)用于确定两个CGPath的交集(请参见https://developer.apple.com/documentation/coregraphics/cgpath/3994964-intersection),以及几个相关函数用于联合、归一化、将路径分离为其组件等。
我测试了其中的几个,但似乎都不起作用。事实上,任何随机组合的非平凡示例都会给我错误的结果。例如,下面的代码给了我下面的第一张图片:紫色区域是正确的交叉点。
var pathRedFill = CGMutablePath(rect: CGRect(origin: CGPoint(x: 10, y: 10),
size: CGSize(width: 400, height: 700)),
transform: nil)
pathRedFill.addQuadCurve(to: CGPoint(x: 267, y: 121), control: CGPoint(x: 395, y: 735))
pathRedFill.closeSubpath()
var pathBlueFill = CGMutablePath(rect: CGRect(origin: CGPoint(x: 120, y: 120),
size: CGSize(width: 200, height: 200)), transform: nil)
pathBlueFill.addQuadCurve(to: CGPoint(x: 637, y: 176), control: CGPoint(x: 343, y: 451))
pathBlueFill.closeSubpath()
context.setBlendMode(.normal)
context.setFillColor(red: 1, green: 0, blue: 0, alpha: 0.5)
context.addPath(pathRedFill)
context.drawPath(using: .eoFill)
context.setFillColor(red: 0, green: 0, blue: 1, alpha: 0.5)
context.addPath(pathBlueFill)
context.drawPath(using: .eoFill)
如果我添加下面的代码来计算相交路径,我得到了第二张图片。绿色线应该精确地环绕紫色区域。但它没有。
context.setLineWidth(4)
context.setStrokeColor(red: 0, green: 1, blue: 0, alpha: 1)
let intersectionPath = pathRedFill.intersection(pathBlueFill, using: .evenOdd)
context.addPath(intersectionPath)
context.drawPath(using: .stroke)
我的问题:
1.是不是我做错了什么?(文档没有对我相交的两个路径提出任何要求,所以我的路径不是太复杂,我应该认为...)
1.有人遇到过类似的错误吗?
非常感谢您的帮助!
编辑:我对iOS16中添加的所有10个函数做了更多的测试(根据DonMag纠正了我的路径公式中的错误),并试图找到我认为出错的最简单的情况。所以这(所有其他代码保持不变,只有路径发生了变化)
let pathRedFill = CGPath(rect: CGRect(origin: CGPoint(x: 200, y: 300),
size: CGSize(width: 200, height: 200)),
transform: nil)
var pathBlueFill = CGMutablePath()
pathBlueFill.move(to: CGPoint(x: 302.854156, y: 369.438843))
pathBlueFill.addQuadCurve(to: CGPoint(x: 296.932526, y: 386.031342), control: CGPoint(x: 218.5, y: 376.0))
pathBlueFill.closeSubpath()
给出了结果:
绿线应该环绕紫色,但没有。
这第一个是一个例子的一部分,其中红色和蓝色路径都有很多自相交,我认为路径的自相交是问题所在(因为我有一些非常复杂的例子没有自相交,但是有洞,看起来一切都很好)但是当我完成了最小化的剥离,结果发现还有一些不一致的地方,因为在两条路径中没有更多的自相交...当四舍五入蓝色路径的数字时,误差消失,所以这可能是关于根的这种退化角情况...而且我的蓝色曲线是二次曲线(然后是闭合路径的线),而结果是交叉点,用绿色描边,是三次贝塞尔曲线我不确定我是不是还做错了什么。
1条答案
按热度按时间8zzbczxx1#
几种可能性...
1.新的路径交叉函数(也许还有其他的)有点"bug"
1.它工作正常,但我们对路径如何构建的理解有点模糊
经过一些实验,我得到了这个与您的原始代码在iOS上(不知道为什么它是垂直翻转-您运行这个在MacOS应用程序?):
现在,据我所知,这句台词:
等价于:
接下来我们要做的是:
我们得到了预期的输出...但是,当我们完成其余的代码时,我们得到了(似乎是)一个不正确的交集。
我的猜测是,在关闭第一个子路径之后调用
.addQuadCurve
时,会出现某种"断开连接"。如果我们进行此更改:
下面是输出:
因此,调用
.moveTo
可能 *"显式地启动一个新的子路径"。然后,在内部,路径/子路径更...完整?
你问题的第二部分...
我认为路径可能比表面上看起来要复杂得多。
对于您的具体示例:
pathRedFill
是顺时针路径,而pathBlueFill
是逆时针路径。要查看差异,请尝试更改此代码中的
clockwise
变量...当设置为true
时,我们会得到正确的intersectionPath
: