Here's a solution using Inset
:
clipRange = {{0, 5}, {0, 5}};
Manipulate[
Graphics[
{
Red, Rectangle[{0, 0}, {5, 5}],
Inset[
Graphics[
{Blue, Translate[Disk[{1, 1}, 1], {8 cross, 1}]},
PlotRange -> clipRange
],
First /@ clipRange,
ImageScaled@{0, 0},
-Subtract @@@ clipRange
],
[email protected], Green, Rectangle[{5, 5}, {10, 0}]
},
PlotRange -> All
],
{cross, 0, 1}
]
Essentially, we are creating a second Graphics
with the stuff to be clipped (here the disk), and then we carefully position the Inset
to occupy the correct region in the outer Graphics
:
- The plot range of the inner
Graphics
is set to clipRange
- The position is set to the lower left corner of the
clipRange
- The reference position in the inner coordinate system is set to the lower left corner with
ImageScaled@{0,0}
(in theory, First/@clipRange
would also work, but that solution doesn't quite work with PlotRange->All
and ImagePadding->Automatic
)
- The size of the inset is set to the size of the
clipRange
Compared to the other solutions, this has the advantage that the placement of the "clipping region" can be anywhere inside the plot range (as opposed to the GraphicsRow
solution), and that there is no need to call the potentially expensive and fragile function RegionIntersection
. The code can also easily be extracted into a wrapper function that can be put around arbitrary graphics primitives:
ClipObjects[prim_, clipRange_] :=
Inset[
Graphics[
prim,
PlotRange -> clipRange
],
First /@ clipRange,
ImageScaled@{0, 0},
-Subtract @@@ clipRange
]
Manipulate[
Graphics[
{
Red, Rectangle[{0, 0}, {5, 5}],
ClipObjects[
{Blue, Translate[Disk[{1, 1}, 1], {8 cross, 1}]},
{{0, 5}, {0, 5}}
],
[email protected], Green, Rectangle[{5, 5}, {10, 0}]
},
PlotRange -> All
],
{cross, 0, 1}
]
(* same output *)
This does exactly the same as the code above, but the code is nicely separated from the graphics expression.