frankibanki frankibanki - 3 months ago 16
Swift Question

Swift - how to fill a path (opaque path)

I have a path which should have the shape of an isometric tile:

let isometricPath = CGPathCreateMutable()
CGPathMoveToPoint(isometricPath, nil, 0, -(tileSize.height / 2))
CGPathAddLineToPoint(isometricPath, nil, (tileSize.width / 2), 0)
CGPathAddLineToPoint(isometricPath, nil, 0, (tileSize.height / 2))
CGPathAddLineToPoint(isometricPath, nil, -(tileSize.width / 2), 0)
CGPathCloseSubpath(isometricPath)


and i try to make it an opaque path with this line of code:

let isometricPathRef = isometricPath as CGPathRef


but if i want to check if a CGPoint is inside that path with this:

CGPathContainsPoint(isometricPathRef, nil, locationInNode, true)


It detect the point only on the path but not inside.

How to make that possible?

Thanks

Answer

Your code is correct but you should probably look at the origins of your scene. Are your sure you can see your shape?

By default, a scene’s origin is placed in the lower-left corner of the view. So, a default scene is initialized with a height of 1024 and a width of 768, has the origin (0,0) in the lower-left corner, and the (1024,768) coordinate in the upper-right corner. The frame property holds (0,0)-(1024,768).

Suppose you have this example using your question code:

let tileSize = CGSizeMake(150.0,150.0)
// Your code:
let isometricPath = CGPathCreateMutable()
CGPathMoveToPoint(isometricPath, nil, 0, -(tileSize.height / 2))
CGPathAddLineToPoint(isometricPath, nil, (tileSize.width / 2), 0)
CGPathAddLineToPoint(isometricPath, nil, 0, (tileSize.height / 2))
CGPathAddLineToPoint(isometricPath, nil, -(tileSize.width / 2), 0)
CGPathCloseSubpath(isometricPath)

This path represent a rhombus shape.

Now if I want to draw this shape I can do:

let shape = SKShapeNode.init(path: isometricPath)
shape.strokeColor = SKColor.yellowColor()
shape.fillColor = SKColor.blueColor()
self.addChild(shape)

But nothing is showed because my scene origin start from 0.0 and your shape have negative values.

To show my rhombus I can simply change the scene anchorPoint to:

 self.anchorPoint = CGPointMake(0.5,0.5)

This centers the scene’s origin in the middle of the view (Apple docs) and you can see your tile:

enter image description here

Now suppose you want to know if a point is inside your shape:

let locationInNode = CGPointMake(tileSize.width/15,tileSize.height/15)
// this point is definitely inside the rhombus

I want to show this point simply for debug:

let circle = SKShapeNode.init(circleOfRadius: 5)
circle.strokeColor = SKColor.whiteColor()
circle.fillColor = SKColor.whiteColor()
self.addChild(circle)
circle.position = locationInNode

enter image description here

Now we can check if this point is inside the rhombus:

let isometricPathRef = isometricPath as CGPathRef
print(CGPathContainsPoint(isometricPathRef, nil, locationInNode, true))

Output:

enter image description here