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$
1
  • 2
    $\begingroup$ TechSupport has kindly filed an incident report to the developers. $\endgroup$ Jul 26, 2016 at 19:14

1 Answer 1

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$
5
  • $\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, 2016 at 6:32
  • $\begingroup$ I guess, the main problem would be, to identify the pairs of regions, that fail together. $\endgroup$
    – DPF
    Jul 22, 2016 at 7:26
  • $\begingroup$ Thanks for the additional explanation! $\endgroup$
    – DPF
    Jul 27, 2016 at 7:01
  • 1
    $\begingroup$ The RegionUnion of BoundaryMeshRegion in your first example now works in 11.0. $\endgroup$
    – user31159
    Aug 24, 2016 at 0:02
  • 1
    $\begingroup$ Thanks @Xavier, changed the boilerplate in the question accordingly. $\endgroup$ Aug 24, 2016 at 7:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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