How could I get the volume of water on a region as it is filled up with water from below? Assume gravity points in some appropriate downward axis like -y (or -z in 3D) so the water fills upward from the base of the object.
In addition, I not only consider closed objects but also open ones, so the water should stop filling when it's about to spill out of the opening.
For some objects this is quite easy as demonstrated below, but I'd like a way to calculate these volumes for a wider class of 2D and even 3D objects:
(* Mathematica messes up the padding on the rhs *)
GraphicsRow[
{Graphics[{
LightBlue,
DiskSegment[{0, 0}, 1, {-\[Pi]/2 - 0.6, -\[Pi]/2 + 0.6}],
Black, AbsoluteThickness[2],
Circle[{0, 0}, 1, {-4 \[Pi]/3, \[Pi]/6}],
AbsoluteThickness[1], Arrow[{{0, 0}, {0, 0.5}}]
}],
Graphics[{
LightBlue, DiskSegment[{0, 0}, 1, {-\[Pi] - \[Pi]/6, \[Pi]/6}],
Black, AbsoluteThickness[2],
Circle[{0, 0}, 1, {-4 \[Pi]/3, \[Pi]/6}],
AbsoluteThickness[1], Arrow[{{0, 0}, {0, 0.5}}]
}]
}
]
I thought of a way to do this for simple closed 3D objects using RegionIntersection
with a large cuboid that grows in height. The volume can be calculated using RegionMeasure
. In the case of objects with holes / openings however, the interior to intersect is missing and the appropriate point to stop increasing z
needs to be figured out.
Manipulate[
Block[{c = Cylinder[{{0, 0, 0}, {1, 3, 5}}, 1/2],
r = Cuboid[{-10, -10, -10}, {10, 10, z}]},
Show[RegionIntersection[DiscretizeGraphics@c, DiscretizeGraphics@r],
Graphics3D[{Opacity[.1],
Cylinder[{{0, 0, 0}, {1, 3, 5}}, 1/2]
}]]], {z, 0, 7}]
Here's a potential bowl-like 3D mesh I'm interested in filling - but note I want a general solution that works on non-convex objects too and arbitrary .obj meshes I can load from disk.
SeedRandom[1234];
(*Generate a random polyhedron with an opening near the top *)
r = RegionUnion[
If[Mean[#[[1]]][[3]] < 0.85, #, Nothing] & /@
MeshPrimitives[RandomPolyhedron[100], 2]];
Graphics3D[{
Red, Arrow[{{0, 0, 0}, {0, 0, 1}}],
Green, r}]
And here's an example random polygon with an opening for the 2D case:
SeedRandom[1234];
(*Generate a random polygon with an opening near the top *)
r = RegionUnion[
If[Max[#[[1]][[All, 2]]] < 0.85, #, Nothing] & /@
MeshPrimitives[RandomPolygon[20], 1]];
Graphics[{Red, Arrow[{{0, 0}, {0, 1}}], Green, r}]
Manipulate
) generates a bunch of messages but still works. Your final code block does not work at all for me (except theArrow
does display). $\endgroup$Manipulate
is a bit slow. $\endgroup$