Group Abstract Group Abstract

Message Boards Message Boards

Create a circular/arc spring?

Posted 8 years ago

I'm trying to create a circular spring in Mathematica. That is, a spring that oscillates back and forth but along a circular arc, not along a 1D line. Most springs are written using ParametricPlot, but I cannot find a way for the spring to move in more than 1D with ParametricPlot. I have been able to draw a a spring along an arc using PolarPlot, but the problem is, is that it doesn't look like it's oscillating using Polar Plot. Is there some kind of function that is called PolarParametricPlot? One that utilizes both functionalities of each? Or does anyone know how to draw what I'm describing using one or the other?

I'm attaching some code that demonstrates where I'm stuck. One should be able to just click Evaluate Notebook, and the Graphics will show.

Attachments:
POSTED BY: Tim Kirkpatrick
7 Replies

I have modified the spring functions to oscillate in time, instead of manually adjusting the spring. The problem is that they do not compress and contract properly. Based on the oscillation functions defined, does anyone know how to use them so that the springs compress and contract along with the movement of the masses?

\[Theta]1[t_] = 
  1/72 (40 + E^(-I Sqrt[3/10] t) + E^(I Sqrt[3/10] t) + 
     3 E^(-((I t)/Sqrt[10])) + 3 E^((I t)/Sqrt[10])) \[Pi];

\[Theta]2[t_] = 
  1/72 (88 + E^(-I Sqrt[3/10] t) + E^(I Sqrt[3/10] t) - 
     3 E^(-((I t)/Sqrt[10])) - 3 E^((I t)/Sqrt[10])) \[Pi];

\[Theta]3[t_] = 
  1/36 (68 - E^(-I Sqrt[3/10] t) - E^(I Sqrt[3/10] t)) \[Pi];

Manipulate[
 Show[
  PolarPlot[
   {
    (1 + 0.2*
       TriangleWave[(3*x)/
         2*( \[Theta]2[time] - \[Theta]1[time] - \[Theta]3[time] ) ])
    },
   {x, \[Theta]2[time], \[Theta]1[time]},
   AspectRatio -> Automatic,
   Axes -> None,
   PlotRange -> {  -1.2*1, 1.2*1  },
   PerformanceGoal -> "Quality",
   ImageSize -> Medium
   ],
  PolarPlot[
   {
    (1 + 0.2*
       TriangleWave[(3*x)/
         2*(\[Theta]2[time] - \[Theta]1[time] - \[Theta]3[time])])
    },
   {x, \[Theta]2[time], \[Theta]3[time]},
   AspectRatio -> Automatic,
   Axes -> None,
   PlotRange -> {  -1.2*1, 1.2*1  },
   PerformanceGoal -> "Quality",
   ImageSize -> Medium
   ],
  PolarPlot[
   {
    (1 + 0.2*
       TriangleWave[(3*x)/
         2*(\[Theta]2[time] - \[Theta]1[time] - \[Theta]3[time] )])
    },
   {x, \[Theta]1[time], \[Theta]3[time] - 2 \[Pi]},
   AspectRatio -> Automatic,
   Axes -> None,
   PlotRange -> {  -1.2*1, 1.2*1  },
   PerformanceGoal -> "Quality",
   ImageSize -> Medium
   ],

  Graphics[{
    {(* Mass-1 *)
     Directive[  RGBColor[0, 0, 1], Opacity[0.75]  ],
     Disk[
      {
       1*Cos[  \[Theta]1[time]  ],
       1*Sin[  \[Theta]1[time]  ]
       },
      1/15
      ]
     (* Mass-1 *)},
    {(* Mass-2 *)
     Directive[  RGBColor[0, 0, 1], Opacity[0.75]  ],
     Disk[
      {
       1*Cos[  \[Theta]2[time]  ],
       1*Sin[  \[Theta]2[time]  ]
       },
      1/15
      ]
     (* Mass-2 *)},
    {(* Mass-3 *)
     Directive[  RGBColor[0, 0, 1], Opacity[0.75]  ],
     Disk[
      {
       1*Cos[  \[Theta]3[time]  ],
       1*Sin[  \[Theta]3[time]  ]
       },
      1/15
      ]
     (* Mass-3 *)}
    }]
  ],

 {
  {time, 1 E - 20},
  1 E - 20,
  120,
  ControlType -> Trigger,
  DefaultDuration -> 120.0,
  DisplayAllSteps -> True,
  AnimationRate -> 2.0
  },
 TrackedSymbols :> {time}
 ]
POSTED BY: Tim Kirkpatrick

I have found that the key is in the argument of the wave function. I have modified the script that Henrik provided to use the TriangleWave function. I'm not even certain I understand how dividing by the "time" parameter in the argument of the wave is able to create the wave-like feature (without it, an arc is created, not a wave), but it seems to work perfectly. See below:

Manipulate[

 ParametricPlot[
  {
   (1 + 0.2*TriangleWave[(20*t)/time])*Cos[t],
   (1 + 0.2*TriangleWave[(20*t)/time])*Sin[t]
   },
  {t, 0, time},
  AspectRatio -> Automatic,
  Axes -> None,
  PlotRange -> {  -1.2*1, 1.2*1  },
  PerformanceGoal -> "Quality",
  ImageSize -> Medium
  ],

 {
  {time, 0.1},
  0.1,
  2 Pi
  },
 TrackedSymbols :> {time}
 ]
POSTED BY: Tim Kirkpatrick

I agree; that solution works. I had tunnel vision focusing on using the TriangleWave function to define the spring. I am not certain the the TriangleWave function is robust enough to handle 2D oscillation though, so defining the spring as above is a good solution. Thanks!

POSTED BY: Tim Kirkpatrick

Yes, I perfectly agree - I could not have found better words!

POSTED BY: Henrik Schachner

If you strip the 3rd dimension from Henrik's example you get:

sp[a_, t_] := {(r0 + r1 Cos[a t]) Cos[t], (r0 + r1 Cos[a t]) Sin[t]};

{r0, r1} = {1, .4};
Manipulate[
 ParametricPlot[sp[200/tt, t], {t, 0, tt}, AspectRatio -> Automatic, 
  Axes -> None, PlotRange -> {-r0 - r1, r0 + r1}, 
  PerformanceGoal -> "Quality"], {{tt, Pi}, 1, 2 Pi}]
POSTED BY: Sander Huisman

Hi Henrik,

Thanks for your post and reply. Your solution does draw a spring compressing and expanding along an arc. However, I'm looking to do this in 2D, not 3D. Is there a way to permanently set the 3D picture from the side so that it appears 2D? I'm not sure a 3D parametric plot will be compatible with the rest of the script, though. The function is a SHO with the position mapped by Cosine and Sine functions, to give the appearance that the mass is oscillating in 2D along an arc. I'm trying to get a TriangleWave (which looks like a spring) to compress and contract with the mass along the 2D arc. When I plot the TriangleWave with Polar plot, I can get the spring to bend along the 2D arc, but I cannot get it to compress and expand. When I plot the TriangleWave with ParametricPlot, I can get it to expand and contract, but not bend along the arc.

The function I'm using to do the oscillation is:

\[Theta]1[m_, k_, t_] = \[Pi]/2 + 1/6 \[Pi] Cos[(Sqrt[2] Sqrt[k] t)/Sqrt[m]];

The graphics I've tried are (just click 'Play' to see what I'm talking about):

Manipulate[

 Graphics[{

   {
    Directive[  RGBColor[0.5, 0.5, 0.5], AbsoluteThickness[3], Opacity[1]  ],
    Circle[
     {0, 0},
     1,
     {0, Pi}
     ]
    },

   {(* Mass-1 *)
    Directive[  RGBColor[0, 0, 1], Opacity[0.75]  ],
    Disk[
     {
      1*Cos[  \[Theta]1[10, 2, time]  ],
      1*Sin[  \[Theta]1[10, 2, time]  ]
      },
     1/15
     ]
    (* Mass-1 *)},
   {(* Spring-1 *)
    PolarPlot[
      {
       1 + (1/(4*\[Pi]))*TriangleWave[  2*\[Pi]*sex ]
       },
      {  sex, 0, \[Theta]1[10, 2, time]  },

      PlotStyle ->
       {
        Directive[RGBColor[0, 0, 0.35], AbsoluteThickness[2.5], 
         Opacity[0.75]]
        },
      Axes -> None
      ][[1]],
    ParametricPlot[
      {
       (1/(4*\[Pi]))*sex*\[Theta]1[10, 2, time],
       1 + (1/(4*\[Pi]))*TriangleWave[  2*\[Pi]*sex ]
       },
      {  sex, 0, \[Theta]1[10, 2, time]  },

      PlotStyle ->
       {
        Directive[RGBColor[0, 0, 0.35], AbsoluteThickness[2.5], 
         Opacity[0.75]]
        },
      Axes -> None
      ][[1]]
    (* Spring-1 *)},
   {(* Spring-2 *)
    PolarPlot[
      {
       1 + (1/(4*\[Pi]))*TriangleWave[  2*\[Pi]*sex ]
       },
      {  sex, \[Theta]1[10, 2, time], Pi  },

      PlotStyle ->
       {
        Directive[RGBColor[0, 0, 0.35], AbsoluteThickness[2.5], 
         Opacity[0.75]]
        },
      Axes -> None
      ][[1]]
    (* Spring-2 *)}

   (* Graphics *)}, ImageSize -> Medium],

 "", "",
 (* Axes *)
 "", "",

 Style["Axis Parameters", Bold, FontSize -> 14, FontFamily -> "Times"],
 {
  {time, 10^-20, Style["time", FontSize -> 16, FontFamily -> "Times"]},
  10^-20,
  120,
  ControlType -> Trigger,
  DefaultDuration -> 120.0,
  DisplayAllSteps -> True,
  AnimationRate -> 2.0
  },
 {
  {time, 10^-20, Style["", FontSize -> 16, FontFamily -> "Times"]},
  10^-20,
  120,
  ControlType -> Slider,
  ImageSize -> Medium,
  Appearance -> "Labeled"
  },

 ControlPlacement -> Left,
 SaveDefinitions -> True,
 TrackedSymbols :> {time}

 (* Manipulate *)]

I'm open to the idea of using 3D Param Plot, but I don't know how to set the viewing from the side. Any more thoughts are very welcomed! I'm at a loss as to how to fix this.

Best,

Tim

POSTED BY: Tim Kirkpatrick

Hi Tim,

is it this you are having in mind(?):

sp[a_, t_] := {(r0 + r1 Cos[a t]) Cos[t], (r0 + r1 Cos[a t]) Sin[t], r1 Sin[a t]};

{r0, r1} = {1, .4};
Manipulate[ParametricPlot3D[sp[200/tt, t], {t, 0, tt}, AspectRatio -> Automatic,
   Boxed -> False, Axes -> None, PlotRange -> {-r0 - r1, r0 + r1}, 
  PerformanceGoal -> "Quality"], {{tt, Pi}, 1, 2 Pi}]

Regards -- Henrik

POSTED BY: Henrik Schachner
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard