• Create Account

# Calculate objects position in water affected by buoyancy

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

26 replies to this topic

### #1Hairies  Members   -  Reputation: 103

Like
0Likes
Like

Posted 13 May 2012 - 10:30 AM

Hello there,

im currently working on a framework to create my own games and wanted to add buoyancy physics to it.
I understand the fundamentals, but still have problems to implement it the right way into my framework.
I calculated the resulting force on the object by subtracing the gravity force from the buoyancy and worked out the resultgin acceleration.
I know that the density of the water gets bigger as the object rises in the water, but i dont know when it gets lower...but these are only some problems...anyways ill post my code here(written in C#) and hope somebody will be able to help me creating realistic buoyancy physics. In the moment the object just accelerates up and never returns down -,-...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DextroEngine;
using DextroEngine.Physics;
using Tao.OpenGl;
namespace Shooter
{
class buoyancy_test:IGameObject
{
Renderer _renderer = new Renderer();
Sprite s = new Sprite();
Gravitation g = new Gravitation(9.81f);
double pK = 0.75f;//object density
double pFl = 1;//water density
double watervolume = 0;//amount of object in water
double YIncrement = 0;//amount to increase/decrease objects posítion
double buoyancy = 0;
double bodyforce = 0;
double _totaltimePassed;
float PercentInWater = 9f;
bool moveup = false;
bool movedown = false;
public buoyancy_test()
{
s.SetWidth(10);
s.SetHeight(10);
s.rigidbody.Density = pFl;
s.rigidbody.SetVolume(s.GetWidth(), s.GetHeight(),10);
CalculateMass();
Get_pFl();
}
public double CalculateMass()
{
bodyforce = pK* g.gravitation * s.rigidbody.GetVolume();
s.rigidbody.Mass = bodyforce / g.gravitation;
return s.rigidbody.Mass;
}
public double InWaterVolume()
{
watervolume = s.GetWidth() * s.GetHeight() * PercentInWater;
return watervolume;
}
public  double  Get_pFl()
{
double v_inWater = InWaterVolume();
pFl = (s.rigidbody.Volume * pK)/v_inWater;
return pFl;
}
public void UpdateMovement(double time)
{
_totaltimePassed += time;
buoyancy = pFl * g.gravitation * s.rigidbody.GetVolume();
double result_force = buoyancy - bodyforce;
double a = result_force / s.rigidbody.Mass;
if ((pFl > pK)&&(pFl < 1))
{
moveup = true;
movedown = false;
}
if ((pFl >1))
{
moveup = false;
movedown = true;
}
if (moveup)
{
YIncrement += (a * 0.5 * (_totaltimePassed * _totaltimePassed));
PercentInWater -= 0.1f;
if (PercentInWater > 7.5f)
{
Get_pFl();
}
}
if (movedown)
{
YIncrement -= (a * 0.5 * (_totaltimePassed * _totaltimePassed));
PercentInWater += 0.1f;
if (PercentInWater < 9.0f)
{
Get_pFl();
}
}
}

public void Update(double elapsedTime)
{
UpdateMovement(elapsedTime);
s.SetPosition(0, 0+YIncrement);
}
public void Render()
{
Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
_renderer.DrawSprite(s);
}

}
}


Edited by Hairies, 13 May 2012 - 10:44 AM.

### #2Madhed  Crossbones+   -  Reputation: 1548

Like
0Likes
Like

Posted 13 May 2012 - 11:57 AM

I know that the density of the water gets bigger as the object rises in the water, but i dont know when it gets lower

Density of water does not change (or rather it is not neccessary to include that in a simple calculation). Maybe you just worded that wrong?
Bouyancy force is volume of displaced liquid times liquid density times gravitational force.
So the hard part is to find the amount of displaced liquid. In my buoyancy script I simply use the bounding box and check against the water surface to find the relative amount of displaced water.

Edited by Madhed, 13 May 2012 - 11:59 AM.

### #3Hairies  Members   -  Reputation: 103

Like
0Likes
Like

Posted 13 May 2012 - 12:26 PM

But isnt it so, that the object in water floats if its density is equal to the water's density and it sinks if it is bigger and it rises if it is lower? so the density of the water somehow must change...actually finding the amount of displaced liquid shouldnt be too hard, because it is exactly the same as the amount of volume of the object submerged in water isnt it, so i just needed to calculate that volume?

Edited by Hairies, 13 May 2012 - 12:33 PM.

### #4Madhed  Crossbones+   -  Reputation: 1548

Like
0Likes
Like

Posted 13 May 2012 - 12:40 PM

But isnt it so, that the object in water floats if its density is equal to the water's density and it sinks if it is bigger and it rises if it is lower?

Yes, if the densities are equal the gravitation pulling down and the buoyancy pushing up cancel each other so the object floats.

so the density of the water somehow must change

I still don't understand what you mean by that? Why must the density change? To move the object around?

Edited by Madhed, 13 May 2012 - 12:40 PM.

### #5Hairies  Members   -  Reputation: 103

Like
0Likes
Like

Posted 13 May 2012 - 12:46 PM

you said that the density of water doesnt change, but how can the object sink or rise, if the waters density stays the same?
From wikipedia i got this:
"A body often rises till it breaks through the waters surface. In this case : V_submerged * p_fluid = V_body * p_body.

Edited by Hairies, 13 May 2012 - 12:58 PM.

### #6Madhed  Crossbones+   -  Reputation: 1548

Like
0Likes
Like

Posted 13 May 2012 - 12:53 PM

Because if the density of the object is different from the density of water it will receive a force that will cause an acceleration.
This force will be constant as long as all the parameters stay the same (density, volume, gravity). Actually density of water is bigger if you go deeper.
But according to wikipedia it increases by only 5% at 10km depth which is negligible for any simple game physics simulation that I can imagine.

### #7Hairies  Members   -  Reputation: 103

Like
0Likes
Like

Posted 13 May 2012 - 01:02 PM

So, actually the denities of both water and object don't change? im confused...why am i then reading that

1) if p_fluid < p_body : Object sinks
2) if p_fluid = p_body: Object floats
3) if p_fluid > p_body: Object rises...?

Apart from that, can you help me calculating the correct motion of the object in water influenced by bouyency?

Edited by Hairies, 13 May 2012 - 01:06 PM.

### #8Madhed  Crossbones+   -  Reputation: 1548

Like
0Likes
Like

Posted 13 May 2012 - 01:26 PM

Could you rephrase your problem? Actually, I'm afraid I don't quite get what it is that you want to know.

### #9Hairies  Members   -  Reputation: 103

Like
0Likes
Like

Posted 13 May 2012 - 01:34 PM

first i want to know that how is it that

1) if p_fluid < p_body : Object sinks
2) if p_fluid = p_body: Object floats
3) if p_fluid > p_body: Object rises,

if both water and object density dont change?

Edited by Hairies, 13 May 2012 - 01:37 PM.

### #10Madhed  Crossbones+   -  Reputation: 1548

Like
0Likes
Like

Posted 13 May 2012 - 01:47 PM

I'm sorry I still don't know what you mean...

If you want to learn the fundamental principles of how buoyancy works you should check out wikipedia or a physics book.
If you just want to implement it in your simulation everything that needs to be done has already been said.

### #11Hairies  Members   -  Reputation: 103

Like
0Likes
Like

Posted 13 May 2012 - 02:11 PM

ok, forget the density problem issue, its not that important...could you send me your buyouncy script so i could look at it ?

### #12Madhed  Crossbones+   -  Reputation: 1548

Like
0Likes
Like

Posted 13 May 2012 - 02:44 PM

I can't give you the source code because of contract issues but actually it is quite simple:

void updatePhysics() {
if (inWater) {
float submerged = (waterSurface.y-myBounds.bottom)/myBounds.height;
if (submerged > 1) submerged = 1;
Vector3 buoyancy = -gravity*(submerged*myVolume)*waterDensity;
}
}


### #13jefferytitan  Members   -  Reputation: 1039

Like
0Likes
Like

Posted 13 May 2012 - 04:02 PM

Is p_fluid the density of the fluid? Basically the density of both the fluid and the body stay the same. You're having to push the fluid aside to sink in it. When you get in a bathtub your body forces the water to rise, so you're making the water resist gravity, which takes force.

If the body is denser than the water, it would completely sink. This is because the force of gravity on the body is stronger than the force of gravity on the water, so the water cannot fully resist it sinking (only slow it down).

If the body is lighter than the water, it will float, e.g. sink a little bit then stop (and probably bob around a bit due to momentum). It obviously can't be entirely on top of the water, as this goes against gravity. But it will sink until the forces equalise, e.g. until the force on the displaced water equalises with the force of gravity on the body. The denser it is, the lower it will sit in the water.

If the body has the same density as water, you can effectively treat it like a lump of water. It will go up or down or stay where it is purely based upon which way the water is flowing and other normal forces on water such as turbulence and convection currents.

Hope that helps!

### #14Bacterius  Crossbones+   -  Reputation: 5598

Like
0Likes
Like

Posted 13 May 2012 - 04:14 PM

What makes an object "bob" up and down on the water's surface if it happens to float? It is pushed upwards by a net force of buoyancy and gravity, which reduces the immersed volume of the object. This reduces the buoyancy force, which causes gravity to take over, pulling the object back down. This in turn causes more of the object's volume to be immersed, causing the buoyancy force to become greater than gravity once again, pushing the object upwards again, ad infinitum until friction forces stabilize the object.

Also another little thing which may also help you understand, if the gravitational strength suddenly decreased then the object would not suddenly sink or start hovering above the water, in fact it would remain floating at exactly the same height. This is because in an incompressible static fluid (like water in a tank), the only forces acting on the object are gravity and the buoyancy force, and both forces take into account the gravitational strength, which means any change in the latter will be cancelled out - at least in theory.

So pretty much, the net force on an object in a static fluid is just (p_fluid * immersedVolume - objectMass) * gravitationalFieldStrength. Note this means that if the object isn't actually in the water, immersedVolume is zero, which results in gravity -mg only, as expected.

It gets more complicated if the fluid is in laminar flow and even more complicated if the fluid is experiencing turbulence (you'll need some heavy duty algorithms in that case).

"The best comment is a deleted comment."

### #15Hairie  Members   -  Reputation: 109

Like
0Likes
Like

Posted 14 May 2012 - 12:04 PM

Okay, thanks for all these useful responses.... now i have the following situation:

An object(a quad in this case) should fall vertically from a specific position into the water with a density lower than that of water...how would I calculate its correct motion within the water, till it stands still? What formulas would i need to calculate its upward and downward motion?

### #16Bacterius  Crossbones+   -  Reputation: 5598

Like
0Likes
Like

Posted 14 May 2012 - 02:09 PM

It depends how the water is moving. The water will be putting pressure on every immersed surface of the quad, which will result in angular rotation if not all the fluid is immersed (since the force of the water on the sides will only affect the immersed part of the quad), so it will start to bob back and forth trying to restabilize itself. If the water pushes it so that one corner that was previously out of the water tips into the water, the quad may rotate by 90 degrees before floating back up.

Basically calculate the force of the water on every immersed surface (pressure * area) perpendicular to the surface according to the water's velocity field, add gravity and buoyancy, deduce linear/rotational acceleration and you're good to go.

If the water is not moving, it's simpler, since a static fluid won't apply torques so you don't need to worry about angular momentum, but you can't really use a nice and simple formula like kinematics, the motion of the quad is still somewhat chaotic. Its downward motion would just be gravity (buoyancy is always up), and upwards motion is buoyancy. The net force divided by the quad's mass will yield its acceleration which you can then use to displace the quad accordingly. Note I'm assuming infinitely deep water here, if the quad happens to hit the bottom of the "pool" before going back up you'll need to handle the collision of course.

I suspect there could be a formula derived to model this behaviour, with a trigonometric function in it to simulate the bobbing, but it would make more sense to do it using timesteps (and it's easier to improve later on too).

"The best comment is a deleted comment."

### #17Hairie  Members   -  Reputation: 109

Like
0Likes
Like

Posted 14 May 2012 - 02:43 PM

My first ideas were to calculate the difference between gravity force and bouyancy and to get the resulting acceleration by dividing hte resulting force by the mass of the object. Then i could use the formular y = 0.5 * a * t² for each timestep, resulting in y+=0.5*a*t². Depending on if the resulting force is below or over 0, the object would move either up or down. Each timestep i could recalculate the immersed volume, which would be something like

v_inWater = s.GetWidth() * s.GetHeight() * (watervolume-y);


where watervolume is current immersed volume and y is the amount added/subtracted each timestep, depending on if it is sinking or rising, after that i could recalculate the bouyancy force, then the resulting force and finally the acceleration....is this a right approach or are there some mistakes in it?

### #18Bacterius  Crossbones+   -  Reputation: 5598

Like
0Likes
Like

Posted 14 May 2012 - 02:52 PM

You need to keep track of the acceleration and modify it each time step, not replace it completely. Then you also keep track of the velocity and update it as well each step. For instance if the quad is going down at -9.8 m/s, when it goes under water after a while the difference between the buoyancy force and gravity will become positive, say 2 m/s. At that point the new acceleration is -9.8 + 2 = -7.8 m/s, -5.8 m/s, -3.8 m/s etc.. and so on, so that the quad slows down in water before rising back up with increasing speed (when the acceleration becomes positive).

Does it make sense? Kinematics assume acceleration is constant, so it's good for textbooks but not very useful when it comes to problems with accelerating masses like these, you want something more effective.

Also something you overlooked but which can probably be ignored for the sake of simplicity, if your quad hits the water with enough speed full-on, it will *not* sink but bounce back up a little bit before falling back down and sinking, because the fluid's normal force on the quad will be at its maximum. But really, that's quite complicated to handle.

"The best comment is a deleted comment."

### #19Hairie  Members   -  Reputation: 109

Like
0Likes
Like

Posted 14 May 2012 - 03:51 PM

Thanks again, I completely forgot to subtract the positive accelerations from g xD, so I would need to apply the new value for g int both the formulas: pK * V_max * g for the bodyforce and: p_fl * V_immersed *g for the buoyancy...isn't it? By the way, the object already slows down when it first enters the water isnt it? So g already then must decrease isn' it ? Or am i being wrong?

Edited by Hairie, 14 May 2012 - 04:01 PM.

### #20Bacterius  Crossbones+   -  Reputation: 5598

Like
0Likes
Like

Posted 14 May 2012 - 04:17 PM

g doesn't decrease, it's constant. What makes the object slow down is that the water opposes the object via the buoyancy force which makes its net force go upwards. But in reality you want to keep track of velocity and apply acceleration to it because otherwise your objects will be changing directions instantly which will look unrealistic. Basically keep variables for position (X and Y) and velocity (X and Y) and every frame, figure out the forces, update the accelerations, then go velocity = velocity + acceleration * timestep and then position = position + velocity * timestep or something like that (I forgot what the exact form is with timesteps).

"The best comment is a deleted comment."

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS