2

I have a few questions. Here is the code so far:

Needs["VariationalMethods`"]
ClearAll[Global]

Framed[Manipulate[
  (

    variables = {Subscript[θ, 1][t], Subscript[θ, 2][t],
       Subscript[θ, 3][t], Subscript[θ, 4][t]};
    Subscript[r, 1] = 
     Subscript[l, 
      1] {Sin[Subscript[θ, 1][t]], -Cos[
         Subscript[θ, 1][t]]};
    Subscript[r, 2] = 
     Subscript[r, 1] + 
      Subscript[l, 
       2] {Sin[Subscript[θ, 2][t]], -Cos[
          Subscript[θ, 2][t]]};
    Subscript[r, 3] = 
     Subscript[r, 2] + 
      Subscript[l, 
       3] {Sin[Subscript[θ, 3][t]], -Cos[
          Subscript[θ, 3][t]]};
    Subscript[r, 4] = 
     Subscript[r, 3] + 
      Subscript[l, 
       3] {Sin[Subscript[θ, 4][t]], -Cos[
          Subscript[θ, 4][t]]};

    tMax = 20;
    initial = {Subscript[θ, 1][0] == angle1, 
      Subscript[θ, 2][0] == angle2, 
      Subscript[θ, 3][0] == angle3, 
      Subscript[θ, 4][0] == angle4, 
      Subscript[θ, 1]'[0] == speed1, 
      Subscript[θ, 2]'[0] == speed2, 
      Subscript[θ, 3]'[0] == speed3, 
      Subscript[θ, 4]'[0] == speed4};

    lagrangian = (Subscript[m, 1]/2) D[Subscript[r, 1], t].D[
         Subscript[r, 1], t] + (Subscript[m, 2]/2) D[Subscript[r, 2], 
         t].D[Subscript[r, 2], t] + (Subscript[m, 3]/2) D[Subscript[r,
          3], t].D[Subscript[r, 3], t] + (Subscript[m, 4]/2) D[
         Subscript[r, 4], t].D[Subscript[r, 4], t] - 
      g {0, 1}.(Subscript[m, 1]*Subscript[r, 1] + 
          Subscript[m, 2]*Subscript[r, 2] + 
          Subscript[m, 3]*Subscript[r, 3] + 
          Subscript[m, 4]*Subscript[r, 4]);
    eqs = EulerEquations[lagrangian, variables, t];

    sol = 
     First[NDSolve[Join[eqs, initial], 
       Head /@ variables, {t, 0, tMax}]];

    nFrames = 200;
    frames = 
     Table[Graphics[{lineColour, Thick, 
         Line[{{0, 0}, Subscript[r, 1], Subscript[r, 2], Subscript[r, 
           3], Subscript[r, 4]}], pivotColour, Disk[{0, 0}, .1], 
         massColour, Disk[Subscript[r, 1], Subscript[m, 1]/10], 
         Disk[Subscript[r, 2], Subscript[m, 2]/10], 
         Disk[Subscript[r, 3], Subscript[m, 3]/10], 
         Disk[Subscript[r, 4], Subscript[m, 4]/10]} /. sol, 
       PlotRange -> {{-(Subscript[l, 1] + Subscript[l, 2] + Subscript[
             l, 3] + Subscript[l, 4] + Subscript[m, 4]/10), 
          Subscript[l, 1] + Subscript[l, 2] + Subscript[l, 3] + 
           Subscript[l, 4] + 
           Subscript[m, 4]/
            10}, {-(Subscript[l, 1] + Subscript[l, 2] + Subscript[l, 
             3] + Subscript[l, 4] + Subscript[m, 4]/10), 
          Subscript[l, 1] + Subscript[l, 2] + Subscript[l, 3] + 
           Subscript[l, 4] + Subscript[m, 4]/10}}, 
       Background -> White], {t, tMax/nFrames, tMax, tMax/nFrames}];
    ListAnimate[frames, 20]
    )
   "",
  Delimiter,
  "",

  Grid[{
    {
     {Style["Masses (kg)", 16, Bold],
      {{Subscript[m, 1], 1, "Mass 1"}, {1, 2, 3, 4, 5}},
      {{Subscript[m, 2], 1, "Mass 2"}, {1, 2, 3, 4, 5}},
      {{Subscript[m, 3], 1, "Mass 3"}, {1, 2, 3, 4, 5}},
      {{Subscript[m, 4], 1, "Mass 4"}, {1, 2, 3, 4, 5}}} ,


     {Style["Rod lengths (m)", 16, Bold],
      {{Subscript[l, 1], 1, "Rod 1"}, {1, 2, 3, 4, 5}},
      {{Subscript[l, 2], 1, "Rod 2"}, {1, 2, 3, 4, 5}},
      {{Subscript[l, 3], 1, "Rod 3"}, {1, 2, 3, 4, 5}},
      {{Subscript[l, 4], 1, "Rod 4"}, {1, 2, 3, 4, 5}}}},

    {{Style["Initial angles (radians)", 16, Bold],
      {{angle1, 0, "Mass 1"}, {1, 2, 3, 4, 5}},
      {{angle2, 0, "Mass 2"}, {1, 2, 3, 4, 5}},
      {{angle3, 0, "Mass 3"}, {1, 2, 3, 4, 5}},
      {{angle4, 0, "Mass 4"}, {1, 2, 3, 4, 5}}}, 

     {{Style["Initial angles (radians)", 16, Bold],
       {{speed1, 0, "Mass 1"}, {1, 2, 3, 4, 5}},
       {{speed2, 0, "Mass 2"}, {1, 2, 3, 4, 5}},
       {{speed3, 0, "Mass 3"}, {1, 2, 3, 4, 5}},
       {{speed4, 0, "Mass 4"}, {1, 2, 3, 4, 5}}}}}
    }
   ],
  "",
  Delimiter,
  "",

  Style["Display and style", 16, Bold],
  {{lineColour, Darker[Gray], "Rod colour"}, ColorSetter},
  {{massColour, Darker[Red], "Mass colour"}, ColorSetter},
  {{pivotColour, Darker[Red], "Pivot colour"}, ColorSetter},
  Paneled -> False
  ],
 FrameMargins -> 50,
 Background -> LightBlue,
 BaseStyle -> {FontColor -> GrayLevel[0]}
 ]

Don't worry, the animation works fine (without Manipulate). So I'm trying to use Grid in the body of Manipulate so the controls look better. I simply took the buttons, menus, etc. and put them inside Grid so it would put similar things together. It does that, but it instead of buttons showing up, the actual code shows up in grid. Moreover, it's way too wide...I just want the controls to take up a small part of the screen.

I'm also looking to change all the input fields to textboxes with certain limitations, like a mass greater than 0 but less than 5, for example.

And how do I get the animation not to run automatically? I've tried searching for any kind of autorun setting but can't find anything.

Yves Klett
  • 15,383
  • 5
  • 57
  • 124
Sultan of Swing
  • 913
  • 1
  • 6
  • 19

1 Answers1

3

Grid

According to the documentation, you have to explicitly define the Controls inside Grids, Columns and the like, since Manipulate has no way of figuring it out.

Using a simpler example:

Manipulate[code, 
    "", Delimiter, "", 
    {x, 0, 1}, 
    {y, 0, 1}, 
    "", Delimiter, "", 
    Grid[Map[Control, {{{x, 0, 1}, {y, 0, 1}}, {{x, 0, 1}, {y, 0, 1}}}, {-2}]]
]

Manipulate result

Since Control works anywhere, you can even prototype your Grid outside of Manipulate. Here's an example, using some of OP's code, with connected pairs of Controls

Grid[Map[Control, {{{{speed1, 0, "Mass 1"}, {1, 2, 3, 4, 
  5}}, {{speed2, 0, "Mass 2"}, {1, 2, 3, 4, 5}}}, {{{speed1, 0, 
  "Mass 3"}, {1, 2, 3, 4, 5}}, {{speed2, 0, "Mass 4"}, {1, 2, 3, 
  4, 5}}}}, {-3}]]

Grid of controls

Input validation

To add limitations to your input fields, just use dynamic as described here

InputField[Dynamic[val, If[0 < val < 5, val = #] &], Number]

Autoplay

From ListAnimate help:

By setting AnimationRunning->False, ListAnimate starts in a paused state:

ListAnimate[{1, 2, 3}, AnimationRunning -> False]
Aisamu
  • 2,618
  • 14
  • 17
  • I sincerely appreciate your effort and help. It seems simple but whenever I try to put together a grid of some labeled input fields, it keeps showing me my code in the frame. It's getting really frustrating. – Sultan of Swing Dec 02 '14 at 12:13
  • It's to a point where I'm tempted not to use any grids and just use the buttons on their own, however it wants to show up, no matter how ugly. – Sultan of Swing Dec 02 '14 at 12:16
  • It is definitely possible. It helps if you start with a small example and grow it in small steps. You can also prototype your Grid, with Controls before injecting them on the Manipulate. I'll throw in another example. – Aisamu Dec 02 '14 at 12:31
  • The biggest prblem is that I have to change a substantial amount of code based on the type of control object I want to use. Like putting four sliders like you did doesn't work when I change Control to InputField. Well it works but it has my code INSIDE the text field! – Sultan of Swing Dec 02 '14 at 12:47
  • Making this animation look nice is too difficult. The text fields are HUGE, the grids are HUGE, limiting certain values doesn't work half the time. You are right, starting small helps, but I guess my problem is that I did the animation and then later decided I wanted to manipulate it. – Sultan of Swing Dec 02 '14 at 12:49
  • 1
    I've just finished a moderately-sized GUI using only MMA, and I there is no denying that doing layout with grids, panels and the like (esp. "fluid") is dull and painful. The tutorials (not just help files) were a great help, though. You might want to give them a slow, thorough read! I've done it more than once, actually. – Aisamu Dec 02 '14 at 17:53