ClearAll[rPClearAll[bdR, combinePolygonsByColorHolesAllowed]
rPbdR = RegionPlot[RegionUnionBoundaryDiscretizeRegion[RegionUnion @@ #, PlotPoints -> 90,
MaxRecursionMeshCellStyle -> 5, PlotStyle{2 -> #2, BoundaryStyle1 -> Thick]Directive[Thick, Gray]}] &;
combinePolygonsByColorHolesAllowed = Show[Values[
GroupBy[Cases[#[[1]], {_RGBColor, _Polygon}, All], First,
Module[{color = #[[1, 1]], polys = #[[All, 2]]},
rP[polysbdR[polys, color]] &]], PlotRange -> All, Frame -> False,
AspectRatio -> Automatic] &;
Grid[{Style[#, 24] & /@ {"gr1", "gr2", "gr3", "gr4"},
Show[#, ImageSize -> 250] & /@ #,
Show[#, ImageSize -> 250] & /@ combinePolygonsByColorHolesAllowed /@ #},
Dividers -> All] &@{gr1, gr2, gr3, gr4}
If holes are not allowed, we need to identify the holes in the region formed by the group of polygons. For this purpose, we BoundaryDiscretizeRegion
the RegionUnion
of the polygon group and use the (undocumented) function Region`Mesh`FindMeshRegionHoles
which returns None
if the mesh region does not have any holes and, if it does, a point for each of the holes. For each hole h
, we find the polygons that lie on the line from a point in h
to nearest point on the outer boundary (obtained using ConnectedMeshComponents
) and RegionPlotBoundaryDiscretizeRegion
the RegionUnion
of resulting partition of the polygon group.
ClearAll[findHoles, combinePolygonsByColorNoHoles]
findHoles = Region`Mesh`FindMeshRegionHoles[
BoundaryDiscretizeRegion[RegionUnion @@ #]] &;
combinePolygonsByColorNoHoles = Show[Values[
GroupBy[Cases[#[[1]], {_RGBColor, _Polygon}, All], First,
Module[{color = #[[1, 1]], polys = #[[All, 2]],
bdr = BoundaryDiscretizeRegion[RegionUnion @@ #[[All, 2]]],
outerboundary, lines, partition},
If[findHoles[polys] === None, rP[polysbdR[polys, color],
outerboundary = First@ConnectedMeshComponents[
DiscretizeGraphics[MeshPrimitives[bdr, {1, "Boundary"}]]];
lines = Rationalize[Line[{#, RegionNearest[outerboundary, #]}] & /@
findHoles[polys], 10^-4];
partition = {Complement[polys, ##], ##} & @@
Table[Select[Rationalize[polys, 10^-4],
Head[RegionIntersection[#, ln]] === Line &], {ln , lines}];
Show[rP[FirstShow[bdR[First @ partition, color],
rP[#bdR[#, Lighter@color]Lighter @ Lighter @ color] & /@ Rest[partition],
PlotRange -> All]]] &]],
PlotRange -> All, Frame -> False, AspectRatio -> Automatic] &;
Grid[{Style[#, 24] & /@ {"gr1", "gr2", "gr3", "gr4"},
Show[#, ImageSize -> 250] & /@ #,
Show[#, ImageSize -> 250] & /@ combinePolygonsByColorHolesAllowed /@ #,
Show[#, ImageSize -> 250] & /@ combinePolygonsByColorNoHoles /@ #},
Dividers -> All] & @ {gr1, gr2, gr3, gr4}
Showing input graphics (first row), outputs from combinePolygonsByColorHolesAllowed
(second row) and outputs from combinePolygonsByColorNoHoles
(third row):
Grid[{Style[#, 24] & /@ {"gr1", "gr2", "gr3", "gr4"},
Show[#, ImageSize -> 250] & /@ #,
Show[#, ImageSize -> 250] & /@ combinePolygonsByColorHolesAllowed /@ #,
Show[#, ImageSize -> 250] & /@ combinePolygonsByColorNoHoles /@ #},
Dividers -> All] & @ {gr1, gr2, gr3, gr4}
gr4a = Graphics[{EdgeForm[Gray], Cases[gr4[[1]], {Red, _}, All]},
ImageSize -> Medium];
gr4b = Replace[combinePolygonsByColorHolesAllowed[gr4],
{_Directive[{___, Directive[__Blue, Blue]___}], _GraphicsGroup_} -> {}, All];
gr4c = Replace[combinePolygonsByColorNoHoles[gr4],
{_, Directive[__Directive[{___, Blue | Lighter[Blue]]Lighter[Lighter@Blue], _GraphicsGroup___}], _} -> {}, All];
Row[Show[#, ImageSize -> 250] & /@ {gr4, gr4a, gr4b, gr4c}]
Note: We can also use RegionPlot
instead of BoundaryDiscretizeRegion
above; that is, we can replace the function rdF
above with rP
:
rP = RegionPlot[RegionUnion @@ #, PlotPoints -> 90,
MaxRecursion -> 5, PlotStyle -> #2, BoundaryStyle -> Thick] &;
The 2D primitives produced by the functions above are FilledCurve
s if we use rdF
; they are Polygon
s if we use rP
.