What is the best way to clip a graphic to a region?
I'm pretty sure this can't be done. As evidence of this I put forward Import[]
of .EPS and .PDF with such clipping in it: mathematica imports the shapes unclipped. If there would be some undocumented function to do this clipping, I would assume that Import[]
would make use of it.
You can use region functionality (RegionIntersection
) to clip primitives, although it will be a bit slow. There are two issues, though.
The output if not always a graphics primitive. Sometimes the output of
RegionIntersection
is aBooleanRegion
object, and these objects don't render inside ofGraphics
. This can be fixed by usingBoundaryDiscretizeRegion
to convert to aBoundaryMeshRegion
that does render inside ofGraphics
(in M12). If you are using earlier versions of Mathematica, you can use my answer to Make MeshRegion/BoundaryMeshRegion work as a graphics primitive in M11 to enable them to be rendered in earlier versions of Mathematica as well.2 dimensional multi-primitives (e.g.,
Polygon
) lose the edges where the polygons overlap. This can be fixed by converting multi-primitives to lists of single-primitives.
Here is some code that does this:
ClippedPrimitives[prims_, clip_] := prims /. r_?RegionQ :> clipPrimitives[r, clip]
clipPrimitives[p:Polygon[{__?MatrixQ}], clip_] := ClippedPrimitives[Thread[p], clip]
clipPrimitives[prim_, clip_] := Which[
RegionDisjoint[clip, prim],
Nothing,
RegionWithin[clip, prim],
prim,
True,
Replace[
RegionIntersection[prim, clip],
b_BooleanRegion :> BoundaryDiscretizeRegion[b]
]
]
For your example (which will be slow because the world multi-polygon consists of 5809 polygons):
Graphics[{
Green, Rectangle[{-18, 35}, {18, 82}],
Red, Line[{
{-10.181224213835492,65.15571149065886},
{-4.290845998237188,79.14535975270482},
{14.116585925507536,63.683116936759234},
{16.32547775635689,43.80309045911497},
{-0.6093596134882375,35.70382041266731},
{-16.071602429433796,40.85790135131583},
{-13.126413321634658,57.79273872116096},
{-10.181224213835492,65.15571149065886}
}],
ClippedPrimitives[
First @ CountryData["World", "Shape"],
Polygon[{
{-10.181224213835492,65.15571149065886},
{-4.290845998237188,79.14535975270482},
{14.116585925507536,63.683116936759234},
{16.32547775635689,43.80309045911497},
{-0.6093596134882375,35.70382041266731},
{-16.071602429433796,40.85790135131583},
{-13.126413321634658,57.79273872116096}
}]
]
}]