7

I have a (vaguely) complex curve with some self-intersections, and I would like to add a filling to the interior. However, the recommended method (of turning Lines into FilledCurves), i.e. by doing something like

ParametricPlot[
  {Cos[t] + 2 Cos[2 t], Sin[t] - 2 Sin[2 t]}
  , {t, 0, 2 π}
  , Frame -> True
  ] /. {Line[pts_] :> {FilledCurve[{Line[pts]}]}}

is unsatisfactory, since, as the documentation puts it,

Filled curves can be non-convex and intersect themselves. Self-intersecting curves are filled according to an even-odd rule that alternates between filling and not at each crossing.

This puts a big hole in the middle of my figure that I would also like to fill:

Mathematica graphics

How can I control the filling in that hole?

Emilio Pisanty
  • 10,255
  • 1
  • 36
  • 69

3 Answers3

4
pp = ParametricPlot[{Cos[t] + 2 Cos[2 t], Sin[t] - 2 Sin[2 t]}, {t, 0, 2 π} , 
        Frame -> True ] /. {Line[pts_] :> {FilledCurve[Line@pts]}};

bdg = BoundaryDiscretizeGraphics[pp[[1]], Frame->True]

Mathematica graphics

 BoundaryDiscretizeGraphics[pp[[1]], Frame->True, 
   MeshCellStyle -> {{1, All} -> Directive[Thick, Blue], {2} -> Yellow}]

Mathematica graphics

Or, use bdg in RegionPlot (thanks: @Mr.Wizard):

 RegionPlot @ bdg

Mathematica graphics

Note: In version 11, bdg = BoundaryDiscretizeGraphics @@ pp also works.

kglr
  • 394,356
  • 18
  • 477
  • 896
4

Now we can use WindingPolygon since v12.

plot = ParametricPlot[{Cos[t] + 2 Cos[2 t], Sin[t] - 2 Sin[2 t]}, {t, 
    0, 2 π}, Frame -> True];
plot /. Line[pts_] :> 
   WindingPolygon[pts, "NonzeroRule"] // BoundaryDiscretizeGraphics

enter image description here

Or

Clear["Global`*"];
Needs["NDSolve`FEM`"]
plot = ParametricPlot[{Cos[t] + 2  Cos[2  t], 
   Sin[t] - 2  Sin[2  t]}, {t, 0, 2  π}, Frame -> True];
m = 
 ToElementMesh@
  DiscretizeGraphics[plot]@"MakeRepresentation"@"ElementMesh"
m // MeshRegion // BoundaryMesh
cvgmt
  • 72,231
  • 4
  • 75
  • 133
  • plot = ParametricPlot[{Cos[t] + 2 Cos[2 t], Sin[t] - 2 Sin[2 t]}, {t, 0, 2 π}, Frame -> True]; NDSolve\FEM`ToElementMesh[ DiscretizeGraphics[plot]["MakeRepresentation"["ElementMesh"]]] // MeshRegion // BoundaryMesh` – cvgmt Jul 07 '23 at 12:39
0

In:

xss = Table[{Cos[t] + 2 Cos[2 t] + 2, Sin[t] - 2 Sin[2 t]}, {t, 0, 
    2 \[Pi], 1/100}];
regionPlot[xss_] := ListLinePlot[
  xss, 
  Filling -> {Axis}, 
  FillingStyle -> LightBlue, 
  AspectRatio -> 1,
   Frame -> True, 
  Axes -> False,
   PlotStyle -> Transparent]
regionPlot@xss   

Out:

Mathematica graphics

webcpu
  • 3,182
  • 12
  • 17