13
$\begingroup$

There are three arbitrary curves that defined by three implicit functions. How to separate the 12 regions(one of them is the outside infinite region)

Although we can use image methods to distinguish it, the effect seem not so good. Here we want to get the vector graphics. Thanks!

curves = ContourPlot[{x^2 + y^2 - 16 == 0, 
   x^2/36 + y^2 == 1, (x - 2)^2 + (y + 1)^2 - 9 == 0}, {x, -7, 
   7}, {y, -7, 7}, 
  ContourStyle -> Directive[AbsoluteThickness[2], Black],PlotRangePadding -> None]
Colorize[MorphologicalComponents[curves]]

enter image description here

Test another way.(I don't know how to extract data from BoundaryMeshRegion directly.)

Clear["Global`*"];
curves = ContourPlot[{x^2 + y^2 - 16 == 0, 
    x^2/36 + y^2 == 1, (x - 2)^2 + (y + 1)^2 - 9 == 0}, {x, -7, 
    7}, {y, -7, 7}, 
   ContourStyle -> Directive[AbsoluteThickness[2], Black], 
   Frame -> False,PlotRangePadding -> None];
Colorize[MorphologicalComponents[curves]];
domains = ImageMesh[curves, Method -> "DualMarchingSquares"];
pts = MeshCoordinates[domains];
lines = MeshCells[domains, "Multicells" -> True][[2]];
regs = BoundaryMeshRegion[pts, #] & /@ lines;
outside = BoundaryMeshRegion[pts, lines[[1]], lines[[2]]];
insides = 
  BoundaryMeshRegion[pts, lines[[#]]] & /@ Range[3, Length[regs]];
Graphics[{Gray, outside, 
  Thread[{ColorData[96] /@ Range[Length[regs] - 2], insides}]}]

enter image description here

$\endgroup$
3
  • 1
    $\begingroup$ This link should help, although this is not a typical Venn Diagram scenario. For instance, the light blue region on the left and the deep blue region on the right are in the same set but are supposed to be colored differently. Instead of A, B, C use ImplicitRegion for each of your equations. $\endgroup$
    – Syed
    Dec 22, 2021 at 7:57
  • $\begingroup$ curves = ContourPlot[{x^2 + y^2 - 16 == 0, x^2/36 + y^2 == 1, (x - 2)^2 + (y + 1)^2 - 9 == 0}, {x, -7, 7}, {y, -7, 7}, PlotRangePadding -> None, Frame -> False]; ArrayPlot[MorphologicalComponents[curves, .9], ColorRules -> {0 -> White, 1 -> Green, 2 -> Red, 3 -> Blue, 4 -> Yellow, 5 -> Cyan, 6 -> Orange, 7 -> Brown, 8 -> Pink, 9 -> Purple, 10 -> Magenta, 11 -> Gray, 12 -> LightYellow}] $\endgroup$
    – cvgmt
    Dec 30, 2021 at 23:49
  • $\begingroup$ curves = ContourPlot[{x^2 + y^2 - 16 == 0, x^2/36 + y^2 == 1, (x - 2)^2 + (y + 1)^2 - 9 == 0}, {x, -7, 7}, {y, -7, 7}, PlotRangePadding -> None, Frame -> False]; regs = ConnectedMeshComponents[ ImageMesh[curves, Method -> "DualMarchingSquares"]]; Graphics[Thread[{ColorData[97] /@ Range[Length[regs]], regs}]] $\endgroup$
    – cvgmt
    Dec 31, 2021 at 8:28

2 Answers 2

10
$\begingroup$
eqns = {x^2 + y^2 - 16 == 0, x^2/36 + y^2 == 1, (x - 2)^2 + (y + 1)^2 - 9 == 0};

regions = eqns /. Equal -> LessEqual;

rp = RegionPlot[Evaluate@regions, {x, -7, 7}, {y, -7, 7}, 
    PlotPoints -> 100, PlotStyle -> Opacity[1], 
    BoundaryStyle -> Directive[AbsoluteThickness[1], White]]

enter image description here

Use a slightly modified version of separatePolygons from this answer:

ClearAll[separatePolygons]
separatePolygons = Module[
         {imgmesh = 
            ImageMesh @
              ColorNegate @
                Rasterize[Graphics[#[[1]]], ImageResolution -> 200], 
          cb = CoordinateBounds @ #[[1, 1, 1]], cbm}, 
        cbm = CoordinateBounds @ imgmesh;
        MeshPrimitives[imgmesh, 2] /. 
          p_Polygon :> RescalingTransform[cbm, cb] /@ p] &;

Graphics[MapIndexed[{ColorData[97] @ #2[[1]], #} &, 
    separatePolygons[rp]], ImageSize -> Large] 

enter image description here

Note: In versions prior to version 12.0, replace cb = CoordinateBounds @ #[[1, 1, 1]] with cb = CoordinateBounds @ #[[1, 1]].

$\endgroup$
6
$\begingroup$

Using the method in OP's update:

curves = ContourPlot[{x^2 + y^2 - 16 == 0, x^2/36 + y^2 == 1, 
    (x - 2)^2 + (y + 1)^2 - 9 == 0}, {x, -7, 7}, {y, -7, 7}, 
   ContourStyle -> Directive[AbsoluteThickness[2], Black], 
   Frame -> False];

imesh = ImageMesh[curves, Method -> "DualMarchingSquares"];

polygons13 = ReverseSortBy[RegionMeasure] @
  (MeshPrimitives[imesh, 1, Multicells -> True] /. Line -> Polygon @* Apply[Join]);

polygons = Join[{Polygon[# -> #2]& @@ (List @@@ #[[;;2]])}, #[[3;;]]]& @ polygons13;

Graphics[{RandomColor[], #}] & /@ polygons// Multicolumn[#, 3]&

enter image description here

Graphics[{RandomColor[], #} & /@ polygons, ImageSize -> Large]

enter image description here

Note: The first two polygons in polygon13 are the enclosing rectangle and the union of inside polygons:

Graphics[{RandomColor[], #}] & /@ polygons13[[;;2]]

enter image description here

Hence to the need to use the Polygon[# -> #2]& @@ (...) trick to get a polygon with a hole.

$\endgroup$

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.