Scene from the Buoyancy Demo
Gravity and Buoyancy
A stationary body submerged in a liquid is effected by two forces, gravity and buoyancy. Gravity acts at the center of mass and it is always directed straight down. On a rigid body, the center of gravity can be considered stationary in reference to the body. Buoyancy, on the other hand, acts at the center of buoyancy, and the center of buoyancy moves as the body tilts and rolls. The size of the gravity force is;
Fg = Mass * Gravity
The size of the buoyancy force is proportional to the volume of liquid that it displaces, the force of gravity and the density of the liquid.
Fb = (Volume * LiquidDensity) * gravity
When an object is stable in the liquid, the gravity force and the buoyancy force cancel each other out. This means that the boat is displacing an amount of liquid that weight as much as the boat does itself.
Fg = FbMass * Gravity = Volume * Gravity * LiquidDensityMass = Volume * LiquidDensity
As the boat tilts, the center of buoyancy will move and it will no longer act along an axis that go through the center of gravity. This means that the force will produce a torque. If the boat is well designed, this torque will tend to right the boat up. It does so if the center of buoyancy is located above the center of gravity.
Buoyancy force on tilted hull
But calculating how much liquid is displaced by an arbitrary shape is far from trivial. Even harder is calculating the center of said displacement volume. In a real time simulation, this must be done every simulation step, because the volume of buoyancy keeps changing. When the liquid isn’t a simple plane, but a wavy mesh, the calculations become very hard.
I’ve taken a particle based approach to the buoyancy calculations, the shape is approximated by buoyancy particles. I call the buoyancy particles Bobby or Bobbies, because that’s what they do.
My Bobbies don’t have mass or inertia, I use an open source physics package for that, which is called ODE. ODE takes care of all the the physical aspects of the bodies, like inertia, velocity, center of mass, inertia tensors, collision detection and response and so on. Bobbies create buoyancy forces and drag when they’re submerged in liquid. When they’re not, they’re dormant. A Bobby then applies it’s forces to the ODE body that the bobby is attached to.
Bobbies are uniformly distributed in the volume of the shape that’s being approximated. Simply approximating the hull will not do, because the volume of displacement is also inside the hull. Typically, for a cube, 8 bobbies are required to balance it, and to approximate it convincingly. For more complex bodies, a car or a boat, the number of bobbies required must be empirically determined.
Many Bobbies approximating a hull
The bobbies don’t have to be of the same size, they can be any size that fits a certain space. Bobbies can overlap or not, you’ll have to empirically determine what works for your model. If Bobbies overlap, some areas of your model will have double buoyancy, and if you have holes in your mode, some parts will lack buoyancy. In my experience, the simulations seem convincing either way. What is important is that the volume of the bobbies are equal to that which you would expect for any given volume, otherwise your bodies may sink.
The Bobbies are spheres, and this is very advantageous, because it’s very easy to calculate the center of buoyancy of a partially submerged sphere, and the volume submerged.
Bobby on even liquid
If the liquid above the Bobby can be considered flat, the force of buoyancy will always act straight up, and through the center of gravity. This means that there’s no point in even calculating the center of Buoyancy for flat liquid, the force can act on the center of gravity instead.
Bobby in a wave
If the liquid above the Bobby isn’t flat, due to wave action, things get a bit hairier. This does not include bodies that are submerged in a container with a sloping roof, as the following image shows;
Force at A = Force at B
Here’s an example of a bobby in a wave;
Bobby on sloping / wavy liquid
To explain why the the sphere will react we will examine a simpler case, a cube suspended in liquid;
Buoyancy explained (?)
Buoyancy appears because there is a pressure differential between the bottom of an object and the top of an object. Pressure over an area equals force. Pressure increases as depth increases, and since the bottom of the cube is deeper than the top of the cube, the force on the bottom of the cube will be higher.
Vertical lift (buoyancy)
First I’ll derive the force acting to lift/lower a body. Note that the area of each side of the cube is h2, which means that the force on that side is pressure * h2
g = gravity a = height on the left side b = height on the right side h = side of cube p = liquid densityFy = Fu - Ft Fu = p * g * h2 * (a + h) / 2 + p * g * h2 * (b + h) / 2 Ft = p * g * h2 * a / 2 + p * g * h2 * b / 2Fy = p * g * h2 * (a + h + b + h - (a + b)) / 2 Fy = p * g * h2 * 2 * h / 2 Fy = p * g * h3
This means that the formula for buoyancy lift is identical to what we stated at the start of the page; Volume * Gravity * LiquidDensity. Also, the sloping liquid plane doesn’t effect the buoyancy, the upward lift is always the same!
Let’s investigate side forces next. Note that these functions don’t take the viscosity of the liquid into account, more on that later.
g = gravity a = height on the left side b = height on the right side h = side of cube p = liquid densityFx = Fb - Fa Fb = p * g * h2 * b / 2 + p * g * h2 * (b + h) / 2 = p * g * h2 * (2 * b + h) / 2 Fa = p * g * h2 * a / 2 + p * g * h2 * (a + h) / 2 = p * g * h2 * (2 * a + h) / 2Fx = p * g * h2 * (2 * b + h - 2 * a - h) / 2 Fx = p * g * h2 * (b - a)
For level level water (b=a), the force is zero, which is what we’d expect. Then the force increases linearly with the difference between a and b. What is surprising is that the force on a body submerged in liquid is larger when the the liquid is sloping, the lifting force remains the same, but an additional moving force is added.
To make it easier to use, we’ll restate the formula with a liquid “slope”;
g = gravity dydx = change in liquid elevation per length unit (liquid slope) h = side of cube p = liquid densitydydx = (b - a) / h b - a = dydx * h Fx = p * g * h2 * (b - a) Fx = p * g * h2 * dydx * h Fx = p * g * h3 * dydx
The above equations consider water to be a grid of unconnected water columns, where pressure only propagate straight downwards. This isn’t accurate, the viscosity of the liquid will make neighbouring “water columns” share the load. The further from the pressure gradient the body is located, the less it will feel the pressure gradient. I haven’t been able to find any formulas, but it stands to reason that the effect would diminish exponentially. Please let me know if you find a formula that describes this, email me at email@example.com.
In correspondence these damping formulas has been suggested;
Damping = ScaleConstant * exp(-FalloffConstant * Depth2) or Damping = ScaleConstant / (OffsetConstant + Depth2)
With OffsetConstant somewhere around the value of your wave amplitude squared. The constants would have to be empirically (trial and error) determined.
This gives us a revised formula for horizontal forces, something along the lines of this;
g = gravity
dydx = change in liquid elevation per length unit (liquid slope)
h = side of cube
p = liquid densityFx = p * g * h3 * dydx * (ScaleConstant / (OffsetConstant + Depth2))
In shallow conditions, the formula does fairly well without damping, because it emulates the water movement that the wave would induce. But in deeper water, the Fx can be totally ignored, especially if the waves are small.
As explained earlier, the magnitude of the buoyancy force will depend on the volume displaced, gravity and the density of the liquid being displaced.
Fb = Volume * gravity * LiquidDensity
If the sphere is totally out of the liquid, the submerged volume is of course 0, if it’s totally submerged, we use the usual sphere volume formula;
r = radius of sphereVolume = (4 / 3) * pi * r3
To calculate the volume of a partially submerged sphere, we can use this formula
h = height from liquid level to bottom of sphere r = radius of sphereVolume = pi * h * (3 * r * h - h2) / 3
Center of buoyancy
We also need the center of the buoyancy volume. If the sphere is fully submerged, then the center will be at the center of gravity. That is, in the middle of the sphere. If the sphere isn’t submerged at all, there is no center of buoyancy, because there is no buoyancy. For a partially submerged Bobby, this function gives the location of the center of buoyancy;
r = radius of sphere h = height from liquid level to bottom of spherez = 3 * (2 * r - h)2 / (4 * (3 * r - h))
The height is measured from the bottom of the sphere, to find it’s actual 3d position, you need to move it acording to the normal of the water surface above it.
Center of buoyancy
If the Bobby isn’t stationary in relation to the liquid, it will be exposed to drag. Drag is fairly simple to compute;
Fd = DragCoefficient * LiquidDensity * Velocity2 * Area / 2
The DragCoefficient must be empirically determined, so try different values and see what happens.
Bobby in drag
In my simulations, the location that the drag acts upon is the same as the buoyancy, though this isn’t accurate. The drag occurs in the leading edge of the sphere as it moves through the liquid, so that’s where it should act. Fd is always parallel with V, but since it doesn’t act on the center of gravity, it may incur spin through a torque.
Where Area is the cross-sectional area of the object that is being subjected to the drag. That means that flow/velocity head on will induce more drag than flow/velocity that only hits the body at an angle. For a single fully submerged sphere, the area will always be the area of a circle with the same radius as the sphere;
Area = pi * r2
If the sphere is only partially submerged, the equation is more complicated.
r = radius of circle (sphere radius in this case) h = distance from spheres bottom to liquid levelArea = r2 * ArcCos( (r-h) / r) - (r-h) * sqrt(2 * r * h - h2)
Only exterior Bobbies should have drag, internal ones would typically be shielded by the exterior ones, though this isn’t currently simulated. Bobbies should also have a normal that determines in what movement directions they have drag, this isn’t simulated either. Both are trivial to code.
Basically, three drag modes should be supported;
- No drag, internal nodes, like the interior volume of a ship.
- Always drag, if the object simulated is a sphere or a set of spheres.
- Direction dependant drag, where a normal determines how much of the spheres “area” is obstructing the flow. The back end of a boat has no drag when modelled this way, for instance.
Lift is calculated with the same formula as drag, but it’s a force that acts perpendicular to the speed vector, instead of parallel to it. Lift doesn’t have to work upwards, it can just as well work downwards. My bobbies don’t currently simulate lift, but with an up vector and a LiftCoefficient, that could be taken care of. That way, speed boats could be modelled; the bottom bobbies would tend to lift the ship out of the water.
Bobby getting a lift
Other forces that effect should/could effect the bobbies
The water is assumed to be stationary, and that isn’t always the case. For instance, in a wave the water moves around a bit, and that water movement should be taken into account in the drag calculations. Currently Bobbies aren’t effected by air drag, but they could be.
I’ve shown an extremely easy way to simulate fairly complex buoyancy behaviour, something can typically be implemented with very little work. However, there are disadvantages to this method. One is that very complex bodies may need too many bobbies. For instance, a ship approximated by 8 x 8 x 8 = 512 bobbies may be fairly accurate, but that’s a large amount of bobbies! Clever use of sized bobbies could reduce this problem. Another disadvantage is that it’s not the most accurate method. I wouldn’t want to go sailing on a ship that’s only been modelled with this method.
I’d like to thank Eric Grange for helping and inspiring me during the development of the bobbies, and for developing GLScene. He also reviewed this paper. I’d also like to thank Johan Franson for reviewing the paper. Thanks to Niclas Kling, the only navy engineer I know, for explaining stuff to me, and sending me a huge PDF book on maritime design. Thanks to Jonathan Langridge for improving my formulas for horizontal “lift”.
All mistakes in this paper are mine alone.