Inverse Clip Region


#1

I have a question, which I suspect has a simple answer.  I have two closed paths and I want apply a fill on path2 except where it is overlapped with path1.  I tried using reduceClipRegion, but that gives me a fill ONLY where path2 overlaps  with path1.  I basically want the inverse of that.  There is an excludeClipRegion, but that only operates on rectangles, not paths.  

Any suggestions?

This code does the "opposite" of what I want, but hopefully will help illustrate what I'm asking for.  


void MyView::paint (Graphics& g)
{

Path path1, path2;

path1 = <some closed path>

path2 = <some other closed path>

g.reduceClipRegion(path1);
g.fillPath (path2);

}

 

Thanks,

Chris


#2

It's actually not quite as easy as it sounds.. What you need to do is to subtract one of these paths from the parent rectangle, and clip to the result, but the Path class doesn't have a proper intersection operator (because that's a surprisingly complex and scary thing to write!).

But.. there's an easy trick you can use to punch a hole in a rectangle if the shape is non-reentrant and contained entirely inside the rectangle - just add a rectangle which is drawn in the opposite direction (i.e. clockwise vs anti-clockwise) to the shape inside it.


#3

Thanks for the help.  I solved the problem by adding code that modifies the path to give an "inverse" shape.  It's not at all general, but gets the job done.

-Chris


#4

sorry to ressurect this old thread Jules. I'm trying to knock a simple shape out of another, and was trying to use your suggestion above, but couldn't make it work. 

So I've got path1 which is a rounded rectangle, and path2 which is a smaller rounded rectangle. I want to knock path2 out of path1 (fill path1 except for the area where path2 overlaps). Do I need to draw the inner shape backwards? Or add a backwards shape to it? I can't quite follow your explanation. 


#5

Yeah, you'd need to draw either the inner or outer shape backwards. Doesn't matter which one.

Or you can use setUsingNonZeroWinding (false) to use alternate-winding, which would probably also work.


#6

Ok, got it working with non zero winding turned off.

- Create 2 paths, Outer and Inner (Inner is the shape to punch out from Outer)

- For outer path use setUsingNonZeroWinding (false)

- add the Inner path to the Outer path

done (no drawing shapes backwards, the winding setting seems to take care of this case)

 

 


#7

Bumping this as it helped me solve the problem of a transparency that allowed certain (circular) components to pop through.

For future reference and clarity the code is something like this:

        Path path;

        path.addRectangle (transparencyBounds);
        path.setUsingNonZeroWinding (false);  
        path.addEllipse (circleBounds);

        g.setColour (Colours::white);
        g.setOpacity (0.5f);
        g.fillPath (path);