2
$\begingroup$

I am trying to write a simple cylindrical tank design notebook. Once the user inputs the desired capacity in gallons, it will compute the required volume (in cubic feet) and then offer sliders for height and diameter. However, since the volume (and capacity) must stay constant, if the user changes the height, the diameter will have to change accordingly, and vice versa.

Here is an image of what I'm trying to go for. The little thing on the right is an approximately six foot person for scaling purposes:

example

My issue is getting the sliders to change dynamically as the user changes the other variable. How can I write a relation to make sure that the calculated volume of the cylinder using height and diameter ALWAYS equals the user-defined volume?

I've looked into a couple similar solutions with dynamic updating of variables, but I was still confused and I wasn't sure if it applied in this case. These are a couple of the ones I tried to use: Alternative updating of a dynamic expression How to anchor a Pane's scroll position to the bottom?

Code included below:

Manipulate[
 Graphics3D[{
   Cylinder[{{0, 0, 0}, {0, 0, h}}, d/2],
   Cuboid[{15.25, 0.75, 0}, {16.75, -0.75, 4.5}],
   Sphere[{16, 0, 5}, 1.5]
   },
  ImageSize -> 500,
  PlotRange -> {{-15, 25}, {-15, 15}, {0, 30}}],

 {{cap, 8000, "gallons:"}, ImageSize -> Tiny},
 Spacer[10],
 Dynamic@Row[{Style["      volume:   ", 12], 
    NumberForm[cap/7.4813, 4], 
    Style["  \!\(\*SuperscriptBox[\(ft\), \(3\)]\)", 12]}],
 Spacer[10],
 {{h, 5, "height (ft):"}, 5, 25, Appearance -> "Labeled"},
 {{d, 5, "diameter (ft):"}, 2, 20, Appearance -> "Labeled"},
 Spacer[10]

 ]

Thank you very much!!

$\endgroup$
1
  • 1
    $\begingroup$ humm... this is all not clear. What if I change the gallon amount, now what will happen to the diameter and the height? You can't have 3 variables change all the time. Infinite possibilities. If the volume is fixed, ok, easy to do. But not if all change at same time. Is volume fixed? If it is fixed, why are you making cap dynamic? Once the user inputs the desired capacity in gallons This tells me volume is changing as well. Once the volume changes, current h and d are invalid and there are infinite possibilities for them. $\endgroup$
    – Nasser
    Commented Jun 21, 2014 at 5:55

1 Answer 1

5
$\begingroup$

This solution is valid only after the user enters a new volume, and touches a slider for d or h to adjust them. i.e. once a new volume is entered, the h and the d are no longer valid, until a user changes one of them, so they can sync with the new volume. You might want to adjust the range of sliders as needed. The idea is to use the second argument of Dynamic and update the other slider at that moment. This is the simplest way to do these things.

enter image description here

Manipulate[
 Module[{},
  Graphics3D[{
    Cylinder[{{0, 0, 0}, {0, 0, h}}, d/2],
    Cuboid[{15.25, 0.75, 0}, {16.75, -0.75, 4.5}],
    Sphere[{16, 0, 5}, 1.5]
    }, ImageSize -> 500, PlotRange -> {{-15, 25}, {-15, 15}, {0, 30}}]
  ],
 Grid[{
   {"Gallons",
    Manipulator[Dynamic[cap, {cap = #} &], {100, 100000, 100}, ImageSize -> Tiny],
    Row[{Style["      volume:   ", 12], Dynamic@NumberForm[cap/7.4813, 4], 
    Style["ft^3", 12]}]
    },
   {"height",
    Manipulator[Dynamic[h, {h = #; d = 2 Sqrt[(cap/7.4813)/(Pi h)]} &], 
    {5, 20, 1}, ImageSize -> Tiny], Row[{Dynamic@NumberForm[h, 4], "ft"}]
    },
   {"d",
    Manipulator[Dynamic[d, {d = #; h = (cap/7.4813)/(Pi (d/2)^2)} &], {2, 30, 1}, 
     ImageSize -> Tiny], Row[{Dynamic@NumberForm[d, 4], "ft"}]
    }}],
 {{cap, 8000}, None},
 {{h, 13.615}, None},
 {{d, 10}, None}
 ]
$\endgroup$
1
  • $\begingroup$ Nasser, your solution is perfect! Thank you very much, this is exactly what I was going for. $\endgroup$
    – madacho
    Commented Jun 21, 2014 at 15:19

Your Answer

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

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