# Colouring in a FilledCurve, self-intersections and all

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:

How can I control the filling in that hole?

• ParametricPlot[ r {Cos[t] + 2 Cos[2 t], Sin[t] - 2 Sin[2 t]}, {t, 0, 2 Pi}, {r, 0, 1}, Frame -> True] Commented Jun 5, 2017 at 0:43
• @Bob That's nowhere near sufficient - try e.g. changing the weight between the two components. Commented Jun 5, 2017 at 0:49
• Related: (9406), (11517) Commented Jun 5, 2017 at 0:52
• That Mathematica does not have an option to disable this behavior is a pretty significant limitation compared to, say, SVG.
– user484
Commented Jun 5, 2017 at 1:22

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]


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


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

 RegionPlot @ bdg


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

• In v10.1 I need bdg = BoundaryDiscretizeGraphics @@ pp[[1]]; -- if that doesn't break code in other versions you might make that change. Commented Jun 5, 2017 at 0:48
• That's some pretty interesting tooling. Commented Jun 5, 2017 at 0:49
• @Mr.Wizard, i made the change,
– kglr
Commented Jun 5, 2017 at 0:54
• Thanks. Depending on the OP's needs RegionPlot[bdg] may be sufficient and significantly cleaner. Commented Jun 5, 2017 at 1:00
• @Mr.Wizard, thank you again. Added the RegionPlot alternative.
– kglr
Commented Jun 5, 2017 at 1:05

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


Or

Clear["Global*"];
Needs["NDSolveFEM"]
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

• plot = ParametricPlot[{Cos[t] + 2 Cos[2 t], Sin[t] - 2 Sin[2 t]}, {t, 0, 2 π}, Frame -> True]; NDSolveFEMToElementMesh[ DiscretizeGraphics[plot]["MakeRepresentation"["ElementMesh"]]] // MeshRegion // BoundaryMesh Commented Jul 7, 2023 at 12:39

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:

• Some notes: my region need not be centered at the origin, and I would like to explicitly avoid double-filling. Commented Jun 4, 2017 at 20:09