Joshua
Joshua

Reputation: 197

Inverse CGPath in Rect

I'm looking to inverse a CGPath (relative to a Rect). By this, I mean I have defined a CGPath and I want to get a CGPath that outlines all other areas in the rect.

I've been experimenting different ways and been googling for a couple days now with no luck. I simply just cannot work it out!

Consider the following rect with defined CGPath (where green is the defined CGPath filled):

enter image description here

Now, with what I want (the inversed CGPath) would produce the following:

enter image description here

Specifically, this is for usage with an SKCropNode and SKPhysicsBody in the SpriteKit framework, however i'm producing the polygon for the mask node using CGPaths (and storing the path in an ivar).

Is inversing a CGPath possible, or some other way? If so, how?

Thanks in advance.

Upvotes: 6

Views: 2957

Answers (2)

Kirow
Kirow

Reputation: 1210

Code sample, using UIBezierPath.reversing():

let cgPath: CGPath = ...
let size = cgPath.boundingBox.size

let inverted = UIBezierPath(rect: CGRect(origin: .zero, size: size))
inverted.append(UIBezierPath(cgPath: cgPath).reversing())

//draw result
let image = UIGraphicsImageRenderer(size: size).image { context in
    context.cgContext.setFillColor(UIColor.red.cgColor)
    context.cgContext.addPath(inverted.cgPath)
    context.cgContext.fillPath()
}

Upvotes: 0

pasawaya
pasawaya

Reputation: 11595

I copied the code from the answer @DavidRonnqvist linked to, but changed it to retrieve the UIBezierPath from a CGPath, which is what you need:

CGPath        filledPath = ...; //This is the inner filled shape
CAShapeLayer *invertedLayer = [CAShapeLayer layer];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithCGPath:filledPath];

[invertedLayer setPath:[maskPath CGPath]];
[invertedLayer setFillRule:kCAFillRuleEvenOdd];
[invertedLayer setFillColor:[[UIColor colorOfYourChoice] CGColor]];

I didn't test this but in theory it should work.

Upvotes: 5

Related Questions