0

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.

jmdecombe
  • 782
  • 6
  • 16
  • in the physics world, 150 points = 1 meter, the path is displayed In meters – Knight0fDragon Dec 21 '18 at 16:01
  • try creating B at 200,100 instead of 150,150. It may just compare the points, so if 0 points intersect, it is going to return the original region, not an empty region – Knight0fDragon Dec 21 '18 at 16:11
  • Not sure what you mean. If regions A and B are different in any way, it should never return A or B as the result of the intersection. In the example I gave, it clearly does, which is a bug. – jmdecombe Dec 21 '18 at 19:08

0 Answers0