A simplified minimal example from {hulls[[6]], hulls[[12]]}
(similarly failes if you replace BoundaryMeshRegion
with MeshRegion
):
SeedRandom@1;
b1 = BoundaryMeshRegion[
{{142., -82.}, {187., -56.}, {142., -133.8}, {187., -108.}},
{Line[{{3, 4}, {4, 2}, {2, 1}, {1, 3}}]},
Properties -> {}, Method -> {}];
b2 = BoundaryMeshRegion[
{{187., -56.}, {231., -82.2}, {97.7, -108.}, {142., -133.}},
{Line[{{3, 4}, {4, 2}, {2, 1}, {1, 3}}]},
Properties -> {}, Method -> {}];
RegionUnion[b1, b2]

These two are not joined. The alarming thing is, that if you evaluate it a couple more times, the order with which the unevaluated RegionUnion
returns is not the same, regardless of SeedRandom
. I would consider it a bug, and a twofold at that: internal numerical imprecisions (?) inhibit joining and the internal method of RegionUnion
is immune to SeedRandom
.
RegionBounds
indicates that the bounds are almost identical along the y dimension.
RegionBounds /@ test
{{{142.375, 187.061}, {-133.8, -56.4}}, {{97.6877, 231.748}, {-133.8, -56.4}}}
Workaround 1: Coordinate offset
A possible workaround is to slightly offset all or one appropriate coordinate and transform the region a bit. Note, that the visible lip is due to me rounding the original hulls
coordinates but is not the effect of the slight coordinate shift.
b2 = BoundaryMeshRegion[
{{187., -56.}, {231., -82.2}, {97.7, -108.}, {142., -133.}} +
10^-6,
{Line[{{3, 4}, {4, 2}, {2, 1}, {1, 3}}]},
Properties -> {}, Method -> {}];
RegionUnion[b1, b2]

Workaround 2: Convert to Polygon
s
TechSupport kindly suggested the following workaround:
b1 = Polygon[{{142., -82.}, {187., -56.}, {187., -108.}, {142., -133.8}}]
b2 = Polygon[{{187., -56.}, {231., -82.2}, {142., -133.}, {97.7, -108.}}]
b = RegionUnion[b1, b2] (* Note, that this does not really join the polygons *)
RegionPlot[b, AspectRatio -> Automatic]

You can easily extract the Polygon
represenations by using MeshPrimitives
. Then you can then simply plot the result as a list of graphics primitives:
exp = expandedMeshRegion[#, 10] &/@ hulls;
poly = Chop@Flatten[MeshPrimitives[#, 2] &/@ exp];
Graphics[{{RandomColor[], #} &/@ poly}]

Or ypu can join individual primitives into one big Polygon
- this of course only works so simply if the individual polygons are all convex.
comb = Polygon @ (Join @@ List @@@ poly); (* would have been nice without the parenthesis *)
Graphics@{Blue, comb}

Don't try to discretize the resulting combined Polygon
:
BoundaryDiscretizeGraphics@comb
BoundaryMeshRegion::bcinsect: -- Message text not found -- ...
Joining the polygons as regions and plotting the result with RegionPlot
also fails and on my machine it crashes the kernel.
(* Be advased, this might crash your kernel *)
RegionPlot @ (RegionUnion @@ poly)