8
$\begingroup$

1. What I want

I would like to plot parametric curves approximately like these:

enter image description here

2. What I did

I googled parallel curves and found this resource function:

ParallelCurve

I took its definitions:

J[{x_, y_}] := {-y, x};

L[v0_] := Sqrt @ Simplify[v0 . v0]

ParallelCurve[a_, r_, t_] :=
 Module[{d}, d = D[a, t];
  a + r J[d] / L[d]]

and applied them to an eight curve:

eightc = {Sin[u], Sin[2 u]};

eightp = ParallelCurve[eightc, 0.1, u]

{(-0.2 * Cos[2 * u])/Sqrt[Cos[u]^2 + 4 * Cos[2 * u]^2] + Sin[u], (0.1 * Cos[u])/Sqrt[Cos[u]^2 + 4 * Cos[2 * u]^2] + Sin[2 * u]}

3. What I got

ParametricPlot[{eightc, eightp}, {u, 0, 2 Pi},
 ImageSize -> Large,
 AspectRatio -> 1/2,
 PlotPoints -> 60,
 PlotStyle -> Gray]

enter image description here

Very disappointing, because the two curves are not parallel at all.

4. Questions

  1. How can I get truly parallel curves?

  2. How can I put the ties (normals) between them?

$\endgroup$
5
  • $\begingroup$ At equally separated points along the curve draw a perpendicular line segment of a fixed length. $\endgroup$ Commented Oct 7, 2023 at 8:03
  • 2
    $\begingroup$ closely related Q/As: 1, 2, 3, 4, 5, 6 $\endgroup$
    – kglr
    Commented Oct 7, 2023 at 10:30
  • 2
    $\begingroup$ the issue goes away if you use AspectRatio -> 1. For AspectRatio -> ar, using a + {1, 1/aratio} r J[d]/L[d] in the definition of ParallelCurve makes curves look parallel. However, for this particular example, using this approach we get is a small bump at u = Pi/4 and at u =3Pi/4 . $\endgroup$
    – kglr
    Commented Oct 7, 2023 at 10:37
  • $\begingroup$ Please don't use JPG for non-photographic images (use PNG). $\endgroup$ Commented Oct 8, 2023 at 13:05
  • $\begingroup$ It should be recalled that in general, parallel curves can have self-intersections even when the starting curves do not have them. $\endgroup$ Commented Oct 9, 2023 at 1:08

3 Answers 3

7
$\begingroup$

A funny one :-) (based on @lericr answer)

m represents number of ties.

curve = {Sin[u], Sin[2 u]};
m = 200;
FSS = FrenetSerretSystem[curve, u];
normal = FSS[[2, 2]];
ParametricPlot[
 curve + t normal, {u, 0, 2 Pi + (2 \[Pi])/m}, {t, -.1, .1}, 
 Mesh -> {m, {-1/10 + 1/40, 1/10 - 1/40}}, PlotStyle -> Transparent, 
 BoundaryStyle -> Transparent, Frame -> None, Axes -> None, 
 PlotPoints -> 100]

enter image description here

With m=400 and curve = {Sin[2 u], Sin[3 u]}.

enter image description here

Some other examples:

enter image description here

enter image description here

With MeshStyle -> {Directive[Opacity[1], AbsoluteThickness[4]], Directive[Opacity[1], Gray, AbsoluteThickness[5]]}.

enter image description here

Update:

Here is code for equally spaced ties along the curve:

curve = {Sin[u], Sin[2 u]};
m = 200;
fu[x_?NumericQ] := NIntegrate[Sqrt[Total[D[curve, u]^2]], {u, 0, x}];

mesh = Table[
   x /. FindRoot[
     fu[x] == i, {x, 0, 10}], {i, (Most@Subdivide[fu[2 \[Pi]], m])}];
FSS = FrenetSerretSystem[curve, u];
normal = FSS[[2, 2]];
ParametricPlot[curve + t normal, {u, 0, 2 Pi}, {t, -.1, .1}, 
 Mesh -> {mesh, {-1/10 + 1/40, 1/10 - 1/40}}, 
 PlotStyle -> Transparent, BoundaryStyle -> Transparent, 
 Frame -> None, Axes -> None, PlotPoints -> 100]

enter image description here

With curve = {2 Sin[u], Sin[2 u]};m = 122;.

enter image description here

$\endgroup$
5
$\begingroup$

I would probably start with the "center" of the tracks and expand outward along the normal vectors. You can get tangents and normals for parametric curves withFrenetSerretSystem. So, for example,

curve = {Sin[u], Sin[2 u]};
FSS = FrenetSerretSystem[curve, u];
normal = FSS[[2, 2]];
ParametricPlot[curve + t normal, {u, 0, 2 Pi}, {t, -.1, .1}]

enter image description here

As for the ties, you now have a normal function, but since change in length isn't proportional to change in t, you can't just divide t into equal intervals to get equally spaced ties. So you'll need some calculus, I think. Also, in this particular example, the ties will look awkward at the places with tight curvature.

$\endgroup$
5
$\begingroup$

Although I like and recommend the accepted answer, I would like to show an alternative solution:

NormalPlot[fun_, n_, sc_, {v_, b_}] :=
 Module[{nm, no, ni},
  
  nm = # / Norm[#] * sc & [Reverse @ D[fun, t] * {-1, 1}];
  
  no = Table[{fun, fun + nm}, {t, v, b, (b - v) / n}];
  ni = Table[{fun, fun - nm}, {t, v, b, (b - v) / n}];
  
  ParametricPlot[fun, {t, v, b},
   BaseStyle -> GrayLevel[0.5],
   Epilog -> Line /@ {no, ni, no[[All, 2]], ni[[All, 2]]},
   PlotRangePadding -> 0.2,
   PlotStyle -> Opacity[0]]]

The problem with the AspectRatio of the Eight figure can be solved by multiplying the x-component with 2:

NormalPlot[{2 Sin[t], Sin[2 t]}, 140, 0.1, {-Pi, Pi}]

enter image description here

NormalPlot[{
   Cos[t] * (Sin[t]^3 * 3 + 1)/3,
  -Sin[t] * (Cos[t]^2 * 3 + 1)/3},
 140, 0.03, {-Pi, Pi}]

enter image description here

NormalPlot[{t, Sin[t]}, 16, 0.2, {-2 Pi, 2 Pi}]

enter image description here

With a slight change of the normals function we get the tangents:

TangentPlot[fun_, n_, sc_, {v_, b_}] :=
 Module[{ta, to, ti},
  
  ta = # / Norm[#] * sc & [D[fun, t]];
  
  to = Table[{fun, fun + ta}, {t, v, b, (b - v)/n}];
  ti = Table[{fun, fun - ta}, {t, v, b, (b - v)/n}];
  
  ParametricPlot[fun, {t, 0, 2 Pi},
   BaseStyle -> GrayLevel[0.5],
   Epilog -> Line /@ {to, ti, to[[All, 2]], ti[[All, 2]]},
   PlotRangePadding -> 1,
   PlotStyle -> Opacity[0]]]

TangentPlot[{t, Cos[2 t]}, 140, 1, {0, 2 Pi}]

enter image description here

I would like to thank all answerers and commenters for pointing me in the right direction.

$\endgroup$

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.