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:
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!!
Answer
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.
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}
]
Comments
Post a Comment