7
$\begingroup$

Bug introduced in v10.0, resolved in v11.0.


Introduction

Lately, I asked for a solution to inflate and unite a List of BoundaryMeshRegions: Inflate and unite a list of 0D to 2D regions

JasonB came up with a very good approach, using ContourPlot to do the hard work, instead of ImplicitRegion.

Problem

Now it happens, that the solution seems to fail for some cases of my application (I use PasteBin to save my List of regions for convenience reasons):

Quit;
ClearAll[expandedMeshRegion];
expandedMeshRegion[x_MeshRegion | x_BoundaryMeshRegion, d_: 2] := 
 Module[{xmin, xmax, ymin, ymax}, {{xmin, xmax}, {ymin, ymax}} = 
   Plus[#, {-1.1 d, 1.1 d}] & /@ 
    MinMax /@ Transpose[MeshCoordinates[x]];
  ContourPlot[
    RegionDistance[x, {xx, yy}] == d, {xx, xmin, xmax}, {yy, ymin, 
     ymax}] // BoundaryDiscretizeGraphics]

<< http://pastebin.com/raw/Yx4Jbj7F;

expandedMeshRegion[#, 10] & /@ hulls // RegionUnion

Interestingly, it works for the polygons in this case << http://pastebin.com/raw/fMBvnc6G; with double as many regions.

Side Info

  • Mathematica 10.4.0.0
$\endgroup$
  • 2
    $\begingroup$ TechSupport has kindly filed an incident report to the developers. $\endgroup$ – István Zachar Jul 26 '16 at 19:14
9
$\begingroup$

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]

Mathematica graphics

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]

Mathematica graphics

Workaround 2: Convert to Polygons

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]

Mathematica graphics

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}]

Mathematica graphics

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}

Mathematica graphics

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)
$\endgroup$
  • $\begingroup$ A good view on that issue :). Thanks for submitting it to the TechSupport. Do you have any Idea, how I could handle this issue with lists of regions, like I have in the PasteBin? Shifting polygons is kind of acceptable, if the shift is $10^{-9}$ smaller than the coordinates, but the function must not fail... $\endgroup$ – DPF Jul 21 '16 at 6:32
  • $\begingroup$ I guess, the main problem would be, to identify the pairs of regions, that fail together. $\endgroup$ – DPF Jul 22 '16 at 7:26
  • $\begingroup$ Thanks for the additional explanation! $\endgroup$ – DPF Jul 27 '16 at 7:01
  • 1
    $\begingroup$ The RegionUnion of BoundaryMeshRegion in your first example now works in 11.0. $\endgroup$ – user31159 Aug 24 '16 at 0:02
  • 1
    $\begingroup$ Thanks @Xavier, changed the boilerplate in the question accordingly. $\endgroup$ – István Zachar Aug 24 '16 at 7:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.