Имитация простого сценария, связанного с физикой - PullRequest
0 голосов
/ 19 апреля 2011

Я абсолютный новичок в обеих симуляциях, поэтому этот вопрос может быть глупым. Если это так, пожалуйста, не стесняйтесь редактировать его. Я пытаюсь смоделировать следующий сценарий в Python. Я случайно помещаю несколько мелких частиц в двухмерное поле с фиксированными размерами. Каждая частица имеет радиус действия r. Если первая частица имеет вторую в пределах своего радиуса действия, то на обе частицы должна быть приложена сила (эффект, который первая оказывает на вторую и наоборот), и моя силовая функция определяется как:

f(i,j)_n = (r - |pi_n - pj_n|)((pj_n - pi_n)/|pi_n - pj_n|)

, где n - шаг по времени в данный момент, pi_n представляет положение i на шаге по времени n, || - вычисление величины, а (pj_n - pi_n) - вычитание вектора.

Мне было интересно, есть ли какие-нибудь библиотеки, которые бы упростили этот материал для меня. Все, что мне нужно, это в основном следующее:

time-step particle position(x,y)

У кого-нибудь есть предложения для меня, пожалуйста?

Ответы [ 2 ]

2 голосов
/ 19 апреля 2011

Googling для python library vector 2d возвращает http://www.supereffective.org/pages/Vector-2d-Vector-Library в качестве верхнего попадания, которое выглядит как компетентная библиотека (содержащая проекцию и перпендикулярность, нормализацию, вращение, масштабирование и т. Д.)

Asпока число частиц не слишком велико, это должно работать просто отлично в сочетании со схемой интеграции.например, вы отслеживаете каждую частицу (pos, vel) и, возможно, также ускоряющиеся векторы, и используете:

F = m a

-> F = m dv/dt

-> dv/dt = F/m

и, следовательно,

dv ~= dt*F/m

-> v' - v ~= dt*F/m

-> ball.vel += timeStep*sum(ball.force(n) for n in ball.neighbors())/ball.mass

Это Эйлеринтеграция, которая имеет довольно плохие свойства, но подходит для игры.

1 голос
/ 10 мая 2011

Мне действительно нравится физическая библиотека pymunk , оболочка для библиотеки физики бурундуков.

Прежде всего, библиотеку нужно инициализировать:

import pymunk
pymunk.init_pymunk()
space = pymunk.Space()
space.gravity = (0.0, -100.0)

Чтобы достичь того, чего вы просили, вам нужно создать форму Body и Circle для каждой частицы, которую вы хотите создать.

mass = 1
radius = 14
inertia = pymunk.moment_for_circle(mass, 0, radius, (0,0))
body = pymunk.Body(mass, inertia)
x, y = random.randint(0, 200), random.randint(0, 200)
body.position = x, 550
shape = pymunk.Circle(body, radius, (0,0))
shape.sensor = True
space.add(body, shape)

Частицы не будут сталкиваться друг с другом, поскольку флаг sensor установлен на True. Радиус теперь является областью влияния.

Теперь мы создаем функцию обратного вызова для частиц, которые имеют перекрывающуюся область влияния:

def near_callback(space, arbiter, *args, **kwargs):
    body_i = arbiter.shapes[0].body
    body_j = arbiter.shapes[1].body

    # calculate the forces force_i and force_j with your formula
    ...

    body_i.apply_force(force_i)
    body_j.apply_force(force_j)

Обратный вызов устанавливается в space:

space.set_default_collision_handler(near_callback, near_callback, None, None, None)

Конечно, space нужно «ступить» для каждого таймфрейма:

space.step(dt)

Надеюсь, это было несколько понятно и полезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...