IOS 16中有针对CGPath(核心图形)的新功能,更准确地说,有一个用于确定两个CGPath(参见https://developer.apple.com/documentation/coregraphics/cgpath/3994964-intersection)的交集的函数交集(_:Using:),以及用于联合、归一化、将路径分割为其组件等的几个相关函数.

我测试了其中的几个,但似乎都不起作用.事实上,任何随机组合的非平凡的例子都会给我错误的结果.例如,下面的代码给出了下面的第一张图片:紫色区域是正确的交叉点.

   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. 我是不是做错了什么?(文档没有对我相交的两条路径提出任何要求,所以我认为我的路径不会太复杂……)
  2. 有没有人经历过类似的漏洞?

非常感谢您的帮助!

Blend of red and blue

Wrong intersection

编辑: 我已经对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()

给出了结果:

enter image description here

绿色的线条应该环绕紫色,但却没有.

这首先是一个例子的一部分,在这个例子中,红色和蓝色路径都有很多自交叉,我认为路径的自交叉是问题所在(因为我还有其他一些非常复杂的例子,没有自交叉,但有洞,一切似乎都很顺利).但当我剥离到最低限度时,结果发现还有其他东西不一致,因为在这两条道路上都没有更多的self 交叉点…… 当舍入蓝色路径的数字时,误差消失了,所以可能就是这种关于根的退化角点情况…我的蓝色曲线也是二次曲线(然后有一条线来闭合路径),而它证明了用绿色绘制的交叉点是三次贝塞尔曲线.我不确定我是否还在做错事.

推荐答案

几种可能性...

  1. 新的路径交叉点功能(可能还有其他功能)有点"错误"

  2. 它工作正常,但我们对路径是如何构建的理解有点模糊

  3. 1&;2的组合

经过一些实验后,我在iOS上得到了这一点(不确定它为什么垂直翻转--你在MacOS应用程序上运行这个程序吗?):

enter image description here

现在,根据我的理解,这句话:

    var pathRedFill = CGMutablePath(rect: CGRect(origin: CGPoint(x: 10, y: 10),
                                                 size: CGSize(width: 400, height: 700)),
                                    transform: nil)
    

相当于:

    var pathRedFill = CGMutablePath()
    pathRedFill.move(to: CGPoint(x: 10, y: 10))
    pathRedFill.addLine(to: CGPoint(x: 410, y: 10))
    pathRedFill.addLine(to: CGPoint(x: 410, y: 710))
    pathRedFill.addLine(to: CGPoint(x: 10, y: 710))
    pathRedFill.closeSubpath()

接下来我们要做的是:

    pathRedFill.addQuadCurve(to: CGPoint(x: 267, y: 121), control: CGPoint(x: 395, y: 735))
    pathRedFill.closeSubpath()

我们得到了我们预期的yields .但是,当我们完成其余的代码时,我们得到了一个错误的交叉点(似乎是).

我的猜测是,在第一个子路径关闭后呼叫.addQuadCurve时,会出现某种形式的"断开".

如果我们做出这样的改变:

    var pathRedFill = CGMutablePath(rect: CGRect(origin: CGPoint(x: 10, y: 10),
                                                 size: CGSize(width: 400, height: 700)),
                                    transform: nil)
    
    // add this line:
    pathRedFill.move(to: pathRedFill.currentPoint)
    
    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)

    // add this line:
    pathBlueFill.move(to: pathBlueFill.currentPoint)

    pathBlueFill.addQuadCurve(to: CGPoint(x: 637, y: 176), control: CGPoint(x: 343, y: 451))
    pathBlueFill.closeSubpath()

以下是输出:

enter image description here

所以似乎拨打.moveTo或者"explicitly starts a new subpath."

然后,在内部,路径/子路径更...完成了吗?

Ios相关问答推荐

避免从CoreData加载图像列表时出现SwiftUI挂起

如何将Safari调试器附加到Turbo-iOS原生应用中的模拟器

SwiftUI Divider过大了其父视图

如何在 SwiftUI 中将选项卡放在滚动视图中?

SwiftUI:通过Sheet将数据添加到Realm DB时视图不更新

.onAppear() 函数不适用于 NavigationLink

在 iPad 上删除列表的顶部和底部行

在 Swift 中按下返回键时在文本字段之间切换

是否可以在没有 Mac 的情况下为 iOS 制作 PhoneGap 应用程序?

通过touch 传递到下面的 UIViews

有没有办法在 xib 文件中的视图和顶部布局指南之间添加约束?

iOS 7 圆形框架按钮

如何在 Objective-C (iOS) 中的图像上写文本?

iOS在应用程序中下载并保存图像

由于 GoogleSignIn、AdMob 提交应用程序时 iOS 10 GM 发布错误应用程序try 在没有使用说明的情况下访问隐私敏感数据

Parse for iOS:try 运行应用程序时出错

Flutter:如何创建一个新项目

在 NSUserDefaults 中存储值是否有任何限制?

请在您的 Podfile 中为此目标指定一个平台?

iPhone UITableView.如何开启音乐 App 之类的单字母字母列表?