I am trying to leverage the byIntersection(with:) method of SKRegion in SpriteKit, since it is part of the standard iOS distribution and I would rather not include yet another library if I can avoid it or, God forbid, write my own, since arbitrary path intersection can be very tricky with all the edge cases. Note that my application does not use SpriteKit per se. I just want to leverage that functionality for free.
This method supposedly returns the intersecting region though I do not even need that, as all I really need is to know whether the regions intersect. My goal is to simply test if the intersection region is based on an empty path.
I have two NSBezierPath objects that I convert to CGPath objects while converting the points on the paths from a source NSView to a target NSView, before initializing new SKRegion objects with each CGPath, using SKRegion(path:). I know that everything works before SpriteKit is involved, as I have fully tested everything.
Once I have my two SKRegion objects, the first weird thing is that the coordinates of all the points in the paths have been scaled down by 150, just by virtue of passing those paths to the SKRegion initializer. This is not a problem, as both regions are scaled similarly so determining whether they intersect should still be as accurate, at least from a mathematical standpoint.
The second weird thing, and really the crux of the problem, is that regionA.byIntersection(with: regionB) seems to always return regionA, regardless of whether they intersect fully, partially, or not at all. I have of course verified that both regions are valid and different, and I reasonably assume that a third distinct region should be returned.
My question is as follow: Is this API actually working and, if it is, what am I doing wrong? If it is not working or production quality, has it ever worked and why is it still listed in the official online documentation? Based on the description, it seems that it should be usable without setting up a SKView or any other SpriteKit setup, as it is supposedly based strictly on mathematical algorithms.
Here is some bare-bones sample code to demonstrate the problem in a playground:
import SpriteKit
let pathA = CGPath(rect: CGRect(x: 100, y: 100, width: 200, height: 200), transform: nil)
let pathB = CGPath(rect: CGRect(x: 150, y: 150, width: 200, height: 200), transform: nil)
let regionA = SKRegion(path: pathA)
let regionB = SKRegion(path: pathB)
let regionC = regionA.byIntersection(with: regionB)
print(regionC.path ?? "There is no path.")
The output is:
Path 0x7fb46b67d500:
moveto (0.666667, 0.666667)
lineto (2, 0.666667)
lineto (2, 2)
lineto (0.666667, 2)
closepath
As explained earlier, all coordinates are mysteriously scaled down by 150, so undoing the scaling gives (x: 100, y: 100, width: 200, height: 200), which is indeed pathA, instead of (x: 150, y: 150, width: 150, height: 150), which would be the correct answer.