Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Physics simulator in water python

I'm having issues understanding how to simulate a situation like this: http://phet.colorado.edu/sims/density-and-buoyancy/buoyancy_en.html

The point of the program is to make a simulator - like the one in the link. I want to keep it realistic and use Python. I want to draw the simulation in Pygame.

In my program I ask for a couple of variables; the mass and the radius. The radius will be used to calculate the volume of a sphere and the mass will be used to calculate the buoyancy, gravity force and acceleration.

But the thing is, to keep everything in SI-units I ask for the radius in metre. Doing this while keeping my radius under 10cm, makes for a really small number. And when I use the Pygame module to draw a sphere at the size of 0.1m, it fails. So instead of doing that, I needed to use a bigger scale.

So here comes my main problem. How exacly should I scale the sphere? Say I wanted to define 100 pixels to be 1 metre. I would then have to multiply my radius by 100, since that would be the scale, but now that the sphere is bigger should the velocity also be multiplied by 100?

I've gotten really confused over this! Thanks for your time.

Don't know if you need to see this, anyhow.
Calculations.py

import math

class Formulas():
    def __init__(self):
        self.pi = 3.1415926535
        self.gravity = 9.82 #m/s^2
        self.density_water = 1000.0 #kg/m^3
        self.density_air   = 1.29 #kg/m^3
        self.drag_sphere   = 0.47

    def object_buoyancy(self, volume, medium_density):
        buoyancy = volume * medium_density * self.gravity #N
        return buoyancy

    def object_gravity(self, mass):
        gravity_force = mass * self.gravity #N
        return gravity_force

    def object_volume_sphere(self, radius):
        volume  = 1.3333333 * self.pi * math.pow(radius, 3) #m^3
        return volume

    def object_mass(self, density, volume):
        mass = volume * density #kg
        return mass

    def object_acceleration(self, gravity_force, buoyancy, mass):
        total_force = gravity_force - buoyancy #N
        acceleration = total_force / mass #m/s^2
        return acceleration

    def object_speed(self, acceleration, time, scale):
        speed  = acceleration * (float(time)/1000.0) #m/s
        return speed

    def surface_area(self, radius):
        area = 4 * self.pi * math.pow(radius, 2)
        return area
like image 776
Simon Larsen Avatar asked Sep 12 '12 21:09

Simon Larsen


1 Answers

Like so many problems in physics, this one can be solved using dimensional analysis.

Let us take a look at those constants you defined:

self.pi = 3.1415926535
self.gravity = 9.82 #m/s^2
self.density_water = 1000.0 #kg/m^3
self.density_air   = 1.29 #kg/m^3
self.drag_sphere   = 0.47

In order to be consistent and scale all of your distances so that 1 m = 100 px, we need to scale your constants:

self.pi = 3.1415926535
self.gravity = 982.0 #px/s^2
self.density_water = 0.001 #kg/px^3
self.density_air   = 0.00000129 #kg/px^3
self.drag_sphere   = 0.47

The only other thing you have to do is increase your radius variable by a factor of 100. After that, the rest of your calculations will fall in line:

  1. Your volume calculation will be correct, so
  2. Your mass and surface area calculations will change, so
  3. Your gravity and bouyancy will change, so
  4. Your acceleration will change, so
  5. Finally, your velocity will be correct.

In your equations/methods, I do not see where your medium_density is set, so that my have to change as well. But, in the end, all you have to do is scale all of your inputs that have a unit of "distance" and your output variable will be scaled correctly.

like image 83
john_science Avatar answered Oct 30 '22 06:10

john_science