Message Boards Message Boards

Avoid error in the time-dependent angles defined within the PolarPlot?

Posted 7 years ago

I am back with another problem on the circular spring. With the help of Wolfram Community, I was able to get a spring to oscillate along an arc using trig functions and PolarPlot[]. The issue at hand now is that the oscillations of the springs do not match the oscillations of the masses along the arcs. For some of the springs, they compress when they should be expanding and vice versa. However, one of the springs does compress and expand properly. I cannot see the error in the time-dependent angles defined within the PolarPlot. Can anyone else spot the error(s)?

Here is code for circular springs:

\[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[{
    {
     Circle[{0, 0}, 1]
     },
    {(* Mass-1 *)
     Directive[  RGBColor[0, 0, 1], Opacity[0.85]  ],
     Disk[
      {
       1*Cos[  \[Theta]1[time]  ],
       1*Sin[  \[Theta]1[time]  ]
       },
      1/15
      ]
     (* Mass-1 *)},
    {(* Mass-2 *)
     Directive[  RGBColor[0, 0, 1], Opacity[0.85]  ],
     Disk[
      {
       1*Cos[  \[Theta]2[time]  ],
       1*Sin[  \[Theta]2[time]  ]
       },
      1/15
      ]
     (* Mass-2 *)},
    {(* Mass-3 *)
     Directive[  RGBColor[0, 0, 1], Opacity[0.85]  ],
     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 -> 3.0
  },
 TrackedSymbols :> {time}
 ]
POSTED BY: Tim Kirkpatrick
3 Replies

Hi Tim,

For physical modeling, have you ever considered using Wolfram SystemModeler? The system you describe can be modeled using drag-and-drop with prebuilt components:

model of components

Then you can quite easily change parameters such as the spring constants, the masses or the number of masses. It can still be analyzed in Mathematica. Simulating the above model from Mathematica allows you to use the result right away.

sim = WSMSimulate["RotationalSprings"]
\[Theta]1[t_] := sim["I1.phi", t];
\[Theta]2[t_] := sim["I2.phi", t];
\[Theta]3[t_] := sim["I3.phi", t];

This can now work with the excellent code from Henrik above.

sim = WSMSimulate["RotationalSprings"]
\[Theta]1[t_] := sim["I1.phi", t];
\[Theta]2[t_] := sim["I2.phi", t];
\[Theta]3[t_] := sim["I3.phi", t];

angleSpring[\[Phi]1_, \[Phi]2_, n_Integer] := Module[{absDiff},
  absDiff = Abs[\[Phi]2 - \[Phi]1];
  If[absDiff < Pi,
   ParametricPlot[(1 + .2 TriangleWave[n (\[Gamma] - \[Phi]1)/absDiff]) {Cos[\[Gamma]], Sin[\[Gamma]]}, {\[Gamma], \[Phi]1, \[Phi]2}, PlotRange -> {-1.3, 1.3}, PerformanceGoal -> "Quality"],
   ParametricPlot[(1 + .2 TriangleWave[n (\[Gamma] - \[Phi]1)/(2 Pi + \[Phi]1 - \[Phi]2)]) {Cos[\[Gamma]], Sin[\[Gamma]]}, {\[Gamma], \[Phi]2 - 2 Pi, \[Phi]1}, 
    PlotRange -> {-1.3, 1.3}, PerformanceGoal -> "Quality"]]
  ]

Animate[Show[angleSpring[\[Theta]1[time], \[Theta]2[time], 20], 
  angleSpring[\[Theta]2[time], \[Theta]3[time], 20], 
  angleSpring[\[Theta]1[time], \[Theta]3[time], 20], 
  Graphics[{Blue, Opacity[.85], 
    Disk[{Cos[\[Theta]1[time]], Sin[\[Theta]1[time]]}, 1/15], 
    Disk[{Cos[\[Theta]2[time]], Sin[\[Theta]2[time]]}, 1/15], 
    Disk[{Cos[\[Theta]3[time]], Sin[\[Theta]3[time]]}, 
     1/15]}]], {time, 0, 120}, DisplayAllSteps -> True, 
 AnimationRate -> 3]

Using that, you could for example have a manipulate that gives you sliders to change different parts of the model. For example, here the initial angles of the masses are changed:

Manipulate[
 Column[{
   Button["Simulate", sim = WSMSimulate["RotationalSprings",
      WSMInitialValues -> {"I1.phi" -> \[Phi]1, "I2.phi" -> \[Phi]2, 
        "I3.phi" -> \[Phi]3}]],
   Animate[
    Show[angleSpring[\[Theta]1[time], \[Theta]2[time], 20], 
     angleSpring[\[Theta]2[time], \[Theta]3[time], 20], 
     angleSpring[\[Theta]1[time], \[Theta]3[time], 20], 
     Graphics[{Blue, Opacity[.85], 
       Disk[{Cos[\[Theta]1[time]], Sin[\[Theta]1[time]]}, 1/15], 
       Disk[{Cos[\[Theta]2[time]], Sin[\[Theta]2[time]]}, 1/15], 
       Disk[{Cos[\[Theta]3[time]], Sin[\[Theta]3[time]]}, 
        1/15]}]], {time, 0, 120}, DisplayAllSteps -> True, 
    AnimationRate -> 3]}], {{\[Phi]1, 0, 
   "I1 Initial Angle [\[Degree]]"}, 0, 360 Degree},
 {{\[Phi]2, 120 Degree, "I2 Initial Angle [\[Degree]]"}, 0, 
  360 Degree},
 {{\[Phi]3, 240 Degree, "I3 Initial Angle [\[Degree]]"}, 0, 360 Degree}
 ]

enter image description here

Attachments:
POSTED BY: Patrik Ekenberg

enter image description here

Hi Tim,

I guess this is what you are trying to achive:

ClearAll["Global`*"]

\[Theta]1[t_] := (5*Pi)/9 + (1/36)*Pi*Cos[Sqrt[3/10]*t] + (1/12)*Pi*Cos[t/Sqrt[10]]; 
\[Theta]2[t_] := (11*Pi)/9 + (1/36)*Pi*Cos[Sqrt[3/10]*t] - (1/12)*Pi*Cos[t/Sqrt[10]]; 
\[Theta]3[t_] := (17*Pi)/9 - (1/18)*Pi*Cos[Sqrt[3/10]*t]; 

angleSpring[\[Phi]1_, \[Phi]2_, n_Integer] := Module[{absDiff},
  absDiff = Abs[\[Phi]2 - \[Phi]1];
  If[absDiff < Pi,
   ParametricPlot[(1 + .2 TriangleWave[n (\[Gamma] - \[Phi]1)/absDiff]) {Cos[\[Gamma]], Sin[\[Gamma]]}, {\[Gamma], \[Phi]1, \[Phi]2}, PlotRange -> {-1.3, 1.3}, PerformanceGoal -> "Quality"],
   ParametricPlot[(1 + .2 TriangleWave[n (\[Gamma] - \[Phi]1)/(2 Pi + \[Phi]1 - \[Phi]2)]) {Cos[\[Gamma]], Sin[\[Gamma]]}, {\[Gamma], \[Phi]2 - 2 Pi, \[Phi]1}, 
    PlotRange -> {-1.3, 1.3}, PerformanceGoal -> "Quality"]]
  ]

Animate[Show[angleSpring[\[Theta]1[time], \[Theta]2[time], 20], 
  angleSpring[\[Theta]2[time], \[Theta]3[time], 20], 
  angleSpring[\[Theta]1[time], \[Theta]3[time], 20], 
  Graphics[{Blue, Opacity[.85], 
    Disk[{Cos[\[Theta]1[time]], Sin[\[Theta]1[time]]}, 1/15], 
    Disk[{Cos[\[Theta]2[time]], Sin[\[Theta]2[time]]}, 1/15], 
    Disk[{Cos[\[Theta]3[time]], Sin[\[Theta]3[time]]}, 
     1/15]}]], {time, 0, 120}, DisplayAllSteps -> True, 
 AnimationRate -> 3]

Consider the If-condition inside the angleSpring function; probably this was the point you were missing in your code.

Does this motion represent a realistic dynamics? It looks nice anyway!

Regards -- Henrik

POSTED BY: Henrik Schachner

Henrik,

Thank you very much. The solution you gave for the springs helped a great deal. I was able to use it to complete the demonstration I was working on for coupled harmonic oscillations. I've added you as a contributor to it. Please keep a look out for it in the coming months.

Best,

Tim

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

Group Abstract Group Abstract