2
$\begingroup$

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.

$\endgroup$

1 Answer 1

3
$\begingroup$

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]
$\endgroup$
6
  • $\begingroup$ 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. $\endgroup$ Dec 2, 2014 at 12:13
  • $\begingroup$ 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. $\endgroup$ Dec 2, 2014 at 12:16
  • $\begingroup$ 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. $\endgroup$
    – Aisamu
    Dec 2, 2014 at 12:31
  • $\begingroup$ 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! $\endgroup$ Dec 2, 2014 at 12:47
  • 1
    $\begingroup$ 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. $\endgroup$
    – Aisamu
    Dec 2, 2014 at 17:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.