Skip to main content
Commonmark migration
Source Link

###Update

Update

###Update

Update

Added discussion of the cause of error message and how it might be eliminated
Source Link
m_goldberg
  • 108.1k
  • 16
  • 104
  • 259
Clear[k, n, t]
r[x_] := {x, Sin[x]};
{{k[x_]k}, {t[x_], n[x_]}} = FrenetSerretSystem[r[x], x];

Manipulate[
  ParametricPlot[r[x], {x, 0, 2 Pi},
    Epilog -> {
      Orange, Thick, 
      Arrow[{r[tt], r[tt] + n[tt]}],
      Arrow[{r[tt], r[tt] + t[tt]}],
      Red, PointSize[Large], Point[r[tt]]}, 
      PlotRange -> {{-Pi/4, 2 Pi}, {-2, 2}}],
  {tt, 0., 2 Pi}]

demodemo

###Update

The reason your code produces the error message is because you have a scoping problem

If you were to insert a debugging code into your Manipulate expression like so

Manipulate[
  Module[{r, unitT, unitN, sys},
    ...
    unitN[x_] = sys[[2, 2]];
    Print[Definition[unitN]];
    ParametricPlot[...],
  {tt, 0.01, 2 Pi - 0.01}]

you would see

debug

Note that on the lhs the independent variable is x$_ and the rhs it is x, so your function definitions for the tangent and normal don't work. There several ways you can fix this. Here are three.

  1. Define the functions for r, t and n at top-level as I did in the code given above. This is not a bad solution. It's only real drawback is that the Manipulate expression is not self-contained.

  2. Define the functions in an Initialization clause of the Manipulate expression. The functions are still defined globally but, at least, they are only defined once and the Manipulate expression is self-contained. This is my recommendation.

  3. Fix the scoping problem with a variable injection trick I learned form Mr.Wizard (I am not sure he invented it). Although this will fix the scoping, I do not recommend it because it still leaves the problem that the expressions defining r, t and n are re-evaluated each time the front-end updates the Manipulate's content pane -- a big performance hit.

My recommendation is to use the following code.

Manipulate[
  ParametricPlot[r[x], {x, 0, 2 Pi},
    Epilog -> {
      Orange, Thick,
      Arrow[{r[tt], r[tt] + n[tt]}],
      Arrow[{r[tt], r[tt] + t[tt]}],
      Red, PointSize[Large], Point[r[tt]]}, 
    PlotRange -> {{-Pi/4, 2 Pi}, {-2, 2}}],
  {tt, 0., 2. Pi},
  Initialization :> (
    Clear[k, n, t];
    r[x_] := {x, Sin[x]}; 
    {{k}, {t[x_], n[x_]}} = FrenetSerretSystem[r[x], x];)]

The code that only addresses the scoping problem is:

Manipulate[
  Module[{r, unitT, unitN, sys},
    r[x_] = {x, Sin[x]};
    sys = FrenetSerretSystem[r[x], x];
    Function[unitT[x_] = #][sys[[2, 1]]];
    Function[unitN[x_] = #][sys[[2, 2]]];
    ParametricPlot[r[x], {x, 0, 2 Pi},
      Epilog -> {
        Orange, Thick,
        Arrow[{r[tt], r[tt] + unitN[tt]}],
        Arrow[{r[tt], r[tt] + unitT[tt]}],
        Red, PointSize[Large], Point[r[tt]]}, 
      PlotRange -> {{-Pi/4, 2 Pi}, {-2, 2}}]],
  {tt, 0., 2. Pi}]
Clear[k, n, t]
r[x_] = {x, Sin[x]};
{{k[x_]}, {t[x_], n[x_]}} = FrenetSerretSystem[r[x], x];

Manipulate[
  ParametricPlot[r[x], {x, 0, 2 Pi},
    Epilog -> {
      Orange, Thick, Arrow[{r[tt], r[tt] + n[tt]}],
      Red, PointSize[Large], Point[r[tt]]}, 
      PlotRange -> {{-Pi/4, 2 Pi}, {-2, 2}}],
  {tt, 0., 2 Pi}]

demo

Clear[k, n, t]
r[x_] := {x, Sin[x]};
{{k}, {t[x_], n[x_]}} = FrenetSerretSystem[r[x], x];

Manipulate[
  ParametricPlot[r[x], {x, 0, 2 Pi},
    Epilog -> {
      Orange, Thick, 
      Arrow[{r[tt], r[tt] + n[tt]}],
      Arrow[{r[tt], r[tt] + t[tt]}],
      Red, PointSize[Large], Point[r[tt]]}, 
      PlotRange -> {{-Pi/4, 2 Pi}, {-2, 2}}],
  {tt, 0., 2 Pi}]

demo

###Update

The reason your code produces the error message is because you have a scoping problem

If you were to insert a debugging code into your Manipulate expression like so

Manipulate[
  Module[{r, unitT, unitN, sys},
    ...
    unitN[x_] = sys[[2, 2]];
    Print[Definition[unitN]];
    ParametricPlot[...],
  {tt, 0.01, 2 Pi - 0.01}]

you would see

debug

Note that on the lhs the independent variable is x$_ and the rhs it is x, so your function definitions for the tangent and normal don't work. There several ways you can fix this. Here are three.

  1. Define the functions for r, t and n at top-level as I did in the code given above. This is not a bad solution. It's only real drawback is that the Manipulate expression is not self-contained.

  2. Define the functions in an Initialization clause of the Manipulate expression. The functions are still defined globally but, at least, they are only defined once and the Manipulate expression is self-contained. This is my recommendation.

  3. Fix the scoping problem with a variable injection trick I learned form Mr.Wizard (I am not sure he invented it). Although this will fix the scoping, I do not recommend it because it still leaves the problem that the expressions defining r, t and n are re-evaluated each time the front-end updates the Manipulate's content pane -- a big performance hit.

My recommendation is to use the following code.

Manipulate[
  ParametricPlot[r[x], {x, 0, 2 Pi},
    Epilog -> {
      Orange, Thick,
      Arrow[{r[tt], r[tt] + n[tt]}],
      Arrow[{r[tt], r[tt] + t[tt]}],
      Red, PointSize[Large], Point[r[tt]]}, 
    PlotRange -> {{-Pi/4, 2 Pi}, {-2, 2}}],
  {tt, 0., 2. Pi},
  Initialization :> (
    Clear[k, n, t];
    r[x_] := {x, Sin[x]}; 
    {{k}, {t[x_], n[x_]}} = FrenetSerretSystem[r[x], x];)]

The code that only addresses the scoping problem is:

Manipulate[
  Module[{r, unitT, unitN, sys},
    r[x_] = {x, Sin[x]};
    sys = FrenetSerretSystem[r[x], x];
    Function[unitT[x_] = #][sys[[2, 1]]];
    Function[unitN[x_] = #][sys[[2, 2]]];
    ParametricPlot[r[x], {x, 0, 2 Pi},
      Epilog -> {
        Orange, Thick,
        Arrow[{r[tt], r[tt] + unitN[tt]}],
        Arrow[{r[tt], r[tt] + unitT[tt]}],
        Red, PointSize[Large], Point[r[tt]]}, 
      PlotRange -> {{-Pi/4, 2 Pi}, {-2, 2}}]],
  {tt, 0., 2. Pi}]
Source Link
m_goldberg
  • 108.1k
  • 16
  • 104
  • 259

This much simpler implementation seems to work just fine.

Clear[k, n, t]
r[x_] = {x, Sin[x]};
{{k[x_]}, {t[x_], n[x_]}} = FrenetSerretSystem[r[x], x];

Manipulate[
  ParametricPlot[r[x], {x, 0, 2 Pi},
    Epilog -> {
      Orange, Thick, Arrow[{r[tt], r[tt] + n[tt]}],
      Red, PointSize[Large], Point[r[tt]]}, 
      PlotRange -> {{-Pi/4, 2 Pi}, {-2, 2}}],
  {tt, 0., 2 Pi}]

demo