Edit
f[s_] := 8 {Cos[s], Sin[s]} - 2.5 {Cos[10 s], Sin[8 s]};
plot = ParametricPlot[f[s], {s, 0, .95*2 π}, PlotPoints -> 20,
MaxRecursion -> 2];
line = Cases[plot, _Line, -1] // First;
lines = Partition[line[[1]], 2, 1];
reg = DiscretizeGraphics /@ Line /@ lines // RegionUnion;
g = Graph[MeshPrimitives[reg, 1] /. Line -> Apply@UndirectedEdge,
VertexCoordinates -> MeshCoordinates[reg]];
faces = PlanarFaceList[g];
faces = Select[faces, WindingCount[Line@#, Mean@#] == 1 &];
GraphicsRow[{Graphics[Line /@ lines],
Graphics[{{RandomColor[], Polygon@#} & /@ faces}]}]

Region`Mesh`FindSegmentIntersections
with "ReturnSegmentIndex" -> True do the job!
- To illustrate the principle, we deliberately set
PlotPoints -> 20, MaxRecursion -> 2 in the plot.
Clear["Global`*"];
f[s_] := 8 {Cos[s], Sin[s]} - 2.5 {Cos[10 s], Sin[8 s]};
plot = ParametricPlot[f[s], {s, 0, .95*2 π}, PlotPoints -> 20,
MaxRecursion -> 2];
line = Cases[plot, _Line, -1] // First;
data = Region`Mesh`FindSegmentIntersections[line,
"ReturnSegmentIndex" -> True];
indexs =
Cases[data, {"SegmentsIntersect", indexs_} :> indexs, -1] // First;
indexs = (Sort@First@# -> Last@#) & /@ indexs//Sort;
intersections =
Graphics[{line, {Cyan, Thick,
Line@line[[1, #[[1, 1]] ;; #[[1, 1]] + 1]],
Line[line[[1, #[[1, 2]] ;; #[[1, 2]] + 1]]], Red,
AbsolutePointSize[6], Point@data[[1, #[[2]]]]} & /@ indexs}];
polys = Polygon /@ (Join[{data[[1, #[[2]]]]},
line[[1, #[[1, 1]] + 1 ;; #[[1, 2]]]]] & /@ indexs);
g = Graphics[{line, polys, White,
MapIndexed[Text[Style[First@#2, 14, Bold], RegionCentroid@#1] &,
polys]}];
GraphicsRow[{intersections, g}]

Original
Clear["Global`*"];
f[s_] = {Cos[s] + Sin[4 s]/12, Sin[3 s] - Cos[7 s]/4};
thickness = 10^-5;
s[t_] :=
f[t] + c*
Normalize[RotationMatrix[π/2] . f'[t], # . #/Sqrt[# . #] &];
l = 4.5;
pts = Join[Table[s[t] /. c -> thickness, {t, 0, l, .01}],
Reverse@Table[s[t] /. c -> -thickness, {t, 0, l, .01}]];
Graphics[{WindingPolygon[pts, "NonzeroRule"],
First@ParametricPlot[f[s], {s, 0, l}, PlotStyle -> Cyan]}]
Clear["Global`*"];
f[s_] = {Cos[s] + Sin[4 s]/12, Sin[3 s] - Cos[7 s]/4};
thickness = 10^-5;
s[t_] :=
f[t] + c*
Normalize[RotationMatrix[π/2] . f'[t], # . #/Sqrt[# . #] &];
draw[l_] := Module[{pts},
pts = Join[Table[s[t] /. c -> thickness, {t, 0, l, .01}],
Reverse@Table[s[t] /. c -> -thickness, {t, 0, l, .01}]];
Graphics[{WindingPolygon[pts, "NonzeroRule"],
First@ParametricPlot[f[s], {s, 0, l}, PlotStyle -> Cyan]}]]
ani = Manipulate[Show[draw[l], PlotRange -> 2], {l, .1, 8}]
- But still does not work for another curve if we replace
{l, .1, 5.9} to {l, .1, 6.3}
Clear["Global`*"];
f[s_] = 8 {Cos[s], Sin[s]} - 3 {Cos[10 s], Sin[8 s]};
thickness = 10^-5;
s[t_] :=
f[t] + c*
Normalize[RotationMatrix[π/2] . f'[t], # . #/Sqrt[# . #] &];
draw[l_] :=
Module[{pts},
pts = Join[Table[s[t] /. c -> thickness, {t, 0, l, .01}],
Reverse@Table[s[t] /. c -> -thickness, {t, 0, l, .01}]];
Graphics[{WindingPolygon[pts, "NonzeroRule"],
First@ParametricPlot[f[s], {s, 0, l}, PlotStyle -> Cyan]}]]
ani = Animate[Show[draw[l], PlotRange -> 15], {l, .1, 5.9},
SaveDefinitions -> True]
- Another method does not depend on
WindingPolygon.
Clear["Global`*"];
f[s_] = 8 {Cos[s], Sin[s]} - 3 {Cos[10 s], Sin[8 s]};
pts = Table[f[s], {s, Subdivide[0., 5.9, 300]}];
n = Length@pts;
data = Do[
If[(pt =
RegionIntersection[Line[pts[[i ;; i + 1]]],
Line[pts[[k + 1 ;; k + 2]]]]) =!= EmptyRegion[2],
Sow[{i, k, pt}]], {k, 1, n - 2}, {i, 1, k - 1}] // Reap //
Last // First;
ani1 = Manipulate[
Graphics[{Line[pts], Red,
Polygon@Join[{Flatten@First@data[[j, 3]]},
Take[pts, {1 + data[[j, 1]], 1 + data[[j, 2]]}]]}], {j, 1,
Length@data, 1}]
ani2 = Animate[
Graphics[{Line[Take[pts, s]],
Table[If[
s >= data[[;; , 2]][[j]], {ColorData[97]@j,
poly = Polygon@
Join[{Flatten@First@data[[j, 3]]},
Take[pts, {1 + data[[j, 1]], 1 + data[[j, 2]]}]], White,
Text[Style[j, 14], RegionCentroid@poly]}], {j, 1,
Length@data}]}, PlotRange -> 12], {s, 1, Length@pts, 1}]