Симулятор физики в водном питоне

У меня проблемы с пониманием того, как смоделировать такую ​​ситуацию: http://phet.colorado.edu/sims/dedensity-and-buoyancy/buoyancy_en.html

Суть программы в том, чтобы сделать симулятор - как тот, что по ссылке. Я хочу сохранить реалистичность и использовать Python. Я хочу нарисовать симуляцию в Pygame.

В моей программе я прошу пару переменных; масса и радиус. Радиус будет использоваться для расчета объема сферы, а масса будет использоваться для расчета плавучести, силы тяжести и ускорения.

Но дело в том, что для того, чтобы все было в единицах СИ, я прошу радиус в метрах. Делая это с радиусом менее 10 см, получается действительно небольшое число. И когда я использую модуль Pygame для рисования сферы размером 0,1 м, это терпит неудачу. Поэтому вместо этого мне нужно было использовать более крупный масштаб.

Итак, вот моя основная проблема. Насколько точно масштабировать сферу? Скажем, я хотел определить 100 пикселей как 1 метр. Тогда мне пришлось бы умножить свой радиус на 100, так как это будет масштаб, но теперь, когда сфера больше, следует ли скорость также умножить на 100?

Я очень запутался в этом! Спасибо за ваше время.

В любом случае не знаю, нужно ли вам это видеть.
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

person Simon Larsen    schedule 12.09.2012    source источник
comment
Вы должны иметь возможность определять все в единицах отображения, заменяя 1 м = 100 пикселей везде, где вам нужно что-то отображать. Вы уже отслеживаете единицы всего, так что это не должно быть сложно.   -  person Benjamin Bannier    schedule 13.09.2012
comment
Итак, когда я разворачиваю свою сферу, все, что мне нужно сделать, это сделать ее в 100 раз больше? Мне соответственно не нужно увеличивать скорость?   -  person Simon Larsen    schedule 13.09.2012
comment
@SimonBob Вам нужно будет масштабировать все по коэффициенту масштабирования.   -  person Andy Hayden    schedule 13.09.2012
comment
@hayden Значит, это так же просто, как умножение на коэффициент масштабирования в каждом операторе возврата?   -  person Simon Larsen    schedule 13.09.2012
comment
@SimonBob все, что вы показываете ... То есть, если вы собирались отображать объект как 100 на 100 пикселей, вы масштабируете его до 200 на 200 пикселей и т. Д., И его местоположение также масштабируется ... (вы не меняете математика выше, как это отображается)   -  person Andy Hayden    schedule 13.09.2012
comment
@hayden Я показываю только сферу и синий фон. Но что меня беспокоит; когда я использую свою формулу для скорости, я получаю результаты в [м / с], но я сделал масштабный коэффициент 100: 1. Разве тогда не следует умножать скорость еще и на масштабный коэффициент?   -  person Simon Larsen    schedule 13.09.2012
comment
@SimonBob в некотором смысле, если бы он двигался со скоростью 1 пикс / с, теперь он будет со скоростью 2 пикселя / с. Но это в части display ... Выполните все вычисления в m, затем преобразуйте m в пиксели при рисовании.   -  person Andy Hayden    schedule 13.09.2012
comment
@SimonBob, Хайден совершенно прав, просто измените что-то в части дисплея, сохраняйте свои вычисления в физических единицах. Затем, когда вы показываете, конвертируйте метры в пиксели с некоторым выбранным вами коэффициентом. Вероятно, вам даже не нужно преобразовывать скорости (поскольку вы можете иметь дело только с координатами), но 1 м / с станет 100 пикселей / с при таком же преобразовании единиц.   -  person Benjamin Bannier    schedule 13.09.2012
comment
Это может помочь думать об этом как о преобразовании мира в экранные координаты / масштабирование. Ваш объект может находиться в (200,100) мире, но на экране он может отображаться в (0,0). Подобно тому, как мозаичные карты с прокруткой преобразуют координаты на дисплее.   -  person ninMonkey    schedule 13.09.2012


Ответы (1)


Как и многие другие проблемы в физике, эту можно решить с помощью размерного анализа.

Давайте посмотрим на те константы, которые вы определили:

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

Чтобы быть последовательными и масштабировать все ваши расстояния так, чтобы 1 m = 100 px, нам нужно масштабировать ваши константы:

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

Единственное, что вам нужно сделать, это увеличить вашу переменную radius в 100 раз. После этого остальные ваши вычисления будут согласованы:

  1. Ваш расчет объема будет правильным, поэтому
  2. Ваши расчеты массы и площади поверхности изменятся, поэтому
  3. Ваша гравитация и буйность изменятся, так что
  4. Ваше ускорение изменится, поэтому
  5. Наконец, ваша скорость будет правильной.

В ваших уравнениях / методах я не вижу, где установлен ваш medium_density, поэтому мне тоже нужно изменить. Но, в конце концов, все, что вам нужно сделать, это масштабировать все ваши входные данные, которые имеют единицу «расстояния», и ваша выходная переменная будет масштабирована правильно.

person theJollySin    schedule 04.10.2012