10
$\begingroup$

I have several (four) parametric curves defining a closed loop in the plane, and I wish to fill it with some color. Now, I have seen several nice answers for the case of two curves, where the simplest solution is to shift between them as $t \:\gamma_1+(1-t)\gamma_2$, but this is easy only for two curves.

parametric plot of four curves

xs[u_, v_, λ_] := (-(1/4)+I/4) Sqrt[π]  λ(Erf[(1/2+I/2) u]-Erf[(1/2+I/2) (u-I v)]+Erfi[(1/2+I/2) u]-Erfi[(1/2+I/2) (u+I v)])+1/λ Sqrt[π]  FresnelC[u/Sqrt[π]]
ys[u_, v_, λ_] := (-(1/4)-I/4) Sqrt[π] λ(Erf[(1/2+I/2) u]-Erf[(1/2+I/2) (u-I v)]-Erfi[(1/2+I/2) u]+Erfi[(1/2+I/2) (u+I v)])+1/λ Sqrt[π]  FresnelS[u/Sqrt[π]]
    
loop[λ_] := {{xs[-1, t, λ], ys[-1, t, λ]}, {xs[2.2, t, λ], ys[2.2, t, λ]}, {xs[t, -1, λ], ys[t, -1, λ]}, {xs[t, 2.2, λ], ys[t, 2.2, λ]}}
      
ParametricPlot[{loop[0.6]}, {t, -1, 2.2} ]
$\endgroup$

2 Answers 2

12
$\begingroup$
  • We can mapping the rectangle -1<=s<=2.2, -1<=t<=2.2 to such region.
xs[u_, v_, λ_] := (-(1/4) + 
     I/4) Sqrt[π] λ (Erf[(1/2 + I/2) u] - 
     Erf[(1/2 + I/2) (u - I v)] + Erfi[(1/2 + I/2) u] - 
     Erfi[(1/2 + I/2) (u + I v)]) + 
  1/λ Sqrt[π] FresnelC[u/Sqrt[π]]
ys[u_, v_, λ_] := (-(1/4) - 
     I/4) Sqrt[π] λ (Erf[(1/2 + I/2) u] - 
     Erf[(1/2 + I/2) (u - I v)] - Erfi[(1/2 + I/2) u] + 
     Erfi[(1/2 + I/2) (u + I v)]) + 
  1/λ Sqrt[π] FresnelS[u/Sqrt[π]]
ParametricPlot[{xs[s, t, .6], ys[s, t, .6]}, {s, -1, 2.2}, {t, -1, 
  2.2}, PlotStyle -> Cyan]

enter image description here

  • We can compare with the mapping domain and the mapping range as below.
{ParametricPlot[{s, t}, {s, -1, 2.2}, {t, -1, 2.2}, PlotStyle -> Cyan,
    Axes -> None, Mesh -> {10, 10}, 
   MeshShading -> {{Red, Blue}, {Yellow, Green}}], 
  ParametricPlot[{xs[s, t, .6], ys[s, t, .6]}, {s, -1, 2.2}, {t, -1, 
    2.2}, PlotStyle -> Cyan, Axes -> None, Mesh -> {10, 10}, 
   MeshShading -> {{Red, Blue}, {Yellow, Green}}]} // GraphicsRow

enter image description here

  • Another way is take care of the orientation of paths.
xs[u_, v_, λ_] = (-(1/4) + 
      I/4) Sqrt[π] λ (Erf[(1/2 + I/2) u] - 
      Erf[(1/2 + I/2) (u - I v)] + Erfi[(1/2 + I/2) u] - 
      Erfi[(1/2 + I/2) (u + I v)]) + 
   1/λ Sqrt[π] FresnelC[u/Sqrt[π]];
ys[u_, v_, λ_] = (-(1/4) - 
      I/4) Sqrt[π] λ (Erf[(1/2 + I/2) u] - 
      Erf[(1/2 + I/2) (u - I v)] - Erfi[(1/2 + I/2) u] + 
      Erfi[(1/2 + I/2) (u + I v)]) + 
   1/λ Sqrt[π] FresnelS[u/Sqrt[π]];
loop[λ_] = {{xs[-1, t, λ], 
    ys[-1, t, λ]}, {xs[2.2, t, λ], 
    ys[2.2, t, λ]}, {xs[t, -1, λ], 
    ys[t, -1, λ]}, {xs[t, 2.2, λ], 
    ys[t, 2.2, λ]}};
{l1, l2, l3, l4} = ParametricPlot[#, {t, -1, 2.2}] & /@ loop[.6];
{pts1, pts2, pts3, pts4} = 
  Cases[#, Line[a_] :> a, Infinity] & /@ {l1, l2, l3, l4};
pts = Join[pts3[[1]], pts2[[1]], Reverse@pts4[[1]], Reverse@pts1[[1]]];
Graphics[{Green, FilledCurve[Line[pts]]}, Axes -> True]
(* Graphics[{Green, WindingPolygon[pts]}, Axes -> True] *) 

enter image description here

  • BoundaryDiscretizeGraphics also work if we use JoinedCurve.
Clear[xs, ys, l1, l2, l3, l4]; 
xs[u_, v_, λ_] = (-(1/4) + 
      I/4) Sqrt[π] λ (Erf[(1/2 + I/2) u] - 
      Erf[(1/2 + I/2) (u - I v)] + Erfi[(1/2 + I/2) u] - 
      Erfi[(1/2 + I/2) (u + I v)]) + 
   1/λ Sqrt[π] FresnelC[u/Sqrt[π]] // Re;
ys[u_, v_, λ_] = (-(1/4) - 
       I/4) Sqrt[π] λ (Erf[(1/2 + I/2) u] - 
       Erf[(1/2 + I/2) (u - I v)] - Erfi[(1/2 + I/2) u] + 
       Erfi[(1/2 + I/2) (u + I v)]) + 
    1/λ Sqrt[π] FresnelS[u/Sqrt[π]] // Re;
l1 = Cases[
    ParametricPlot[{xs[s, -1, .6], ys[s, -1, .6]}, {s, -1, 2.2}], 
    Line[a_] :> a, Infinity][[1]];
l2 = Cases[
    ParametricPlot[{xs[2.2, t, .6], ys[2.2, t, .6]}, {t, -1, 2.2}], 
    Line[a_] :> a, Infinity][[1]];
l3 = Cases[
     ParametricPlot[{xs[s, 2.2, .6], ys[s, 2.2, .6]}, {s, 2.2, -1}], 
     Line[a_] :> a, Infinity][[1]] // Reverse;
l4 = Cases[
     ParametricPlot[{xs[-1, t, .6], ys[-1, t, .6]}, {t, 2.2, -1}], 
     Line[a_] :> a, Infinity][[1]] // Reverse;
Graphics[JoinedCurve[
   Line[Join[l1, l2, l3, l4]]]] // BoundaryDiscretizeGraphics

enter image description here

  • Some related.

https://mathematica.stackexchange.com/a/252935/72111

https://mathematica.stackexchange.com/a/262992/72111

$\endgroup$
1
  • $\begingroup$ Excellent ! Thank you so much. $\endgroup$ Mar 2, 2022 at 22:56
3
$\begingroup$

An alternative approach: post-process one-parameter ParametricPlot output to order line coordinates and add a polygon.

ClearAll[addFilling]
addFilling[style_ : ColorData[97]@1] := Graphics[{Opacity[.3], style, 
         Polygon @ #[[Last@FindShortestTour[#]]] & @
           MeshCoordinates @ DiscretizeGraphics @ #}] &;

Use addFilling[] with the option DisplayFunction:

ppA1 = ParametricPlot[loop[0.6], {t, -1, 2.2}, 
  ImageSize -> 700, PlotStyle -> AbsoluteThickness[.5], Axes -> False, Frame -> True,
  DisplayFunction -> (Show[#, addFilling[] @ #] &)]

enter image description here

Compare with the two-parameter ParametricPlot method from cvgmt's answer:

ppA2 = ParametricPlot[{xs[s, t, .6], ys[s, t, .6]}, {s, -1, 2.2}, {t, -1, 2.2}, 
  Axes -> False, ImageSize -> 700]

enter image description here

Zoom in to see the artifacts in the second picture:

GraphicsColumn[{Show[ppA1, PlotRange -> {{.5, 2}, {.5, 1}}],
   Show[ppA2, PlotRange -> {{.5, 2}, {.5, 1}}]}]

enter image description here

Using λ = .3:

ppB1 = ParametricPlot[loop[0.3], {t, -1, 2.2}, 
   Axes -> False, PlotStyle -> AbsoluteThickness[.5], Frame -> True, ImageSize -> 700, 
   DisplayFunction -> (Show[#, addFilling[] @ #] &)]

enter image description here

ppB2 = ParametricPlot[{xs[s, t, .3], ys[s, t, .3]}, {s, -1, 2.2}, {t, -1,  2.2}, 
   Axes -> False, ImageSize -> 700]

enter image description here

GraphicsColumn[{Show[ppB1, PlotRange -> {{-2, 2}, {-1, 1}}],
  Show[ppB2, PlotRange -> {{-2, 2}, {-1, 1}}]}]

enter image description here

$\endgroup$
2
  • 2
    $\begingroup$ (+1) The extra part come from other mesh line. ParametricPlot[{xs[s, t, .6], ys[s, t, .6]}, {s, -1, 2.2}, {t, -1, 2.2}, PlotStyle -> Yellow, Axes -> False, Frame -> False, Method -> {"BoundaryOffset" -> False}, MeshFunctions -> {#4 &}, Mesh -> {{{2.2, Red}, {2.1, Green}, {2.0, Blue}}}, MeshStyle -> Red, BoundaryStyle -> None] $\endgroup$
    – cvgmt
    Mar 2, 2022 at 2:09
  • $\begingroup$ Thank you so much. I hesitated about which answer to accept since both yours and cvgmt's are excellent. In the end I accepted the latter because I found it just slightly easier to implement. $\endgroup$ Mar 2, 2022 at 22:59

Your Answer

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

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