Как сделать анимацию, которая включает в себя много частиц (N) с их позицией ([x, y]) и углом ([rad]), перемещающимися в разное время в питоне - PullRequest
0 голосов
/ 05 марта 2019

У меня есть работа по реализации модели Vicsek Бумага модели Vicsek .Я написал коды для модели Vicsek , которые могут генерировать положение и направление частиц с помощью numpy.Self.particles.shape = (N, 2) ( N: количество частиц. 2: положение [x, y]) представляет положение N частиц и self.thetas.shape = (N, 1) обозначает направление каждой частицы.Я получаю 50 групп данных с 50-кратным обновлением положения и направления.И сделайте N = 100, и 50 групп данных, затем pointX.shape = (50,100), pointY.shape = (50,100) и thetas.shape = (50,100).В моем вопросе я хочу отобразить их с анимацией (matplotlib.animation) в python с pyqt5. На мой взгляд, я надеюсь, что частицы могут быть представлены точкой (позицией) и стрелкой или линией (направлением), чтобы было ясно видеть .Я также ищу несколько примеров.Эта сеть Примеры анимации имеет Частицы в коробке , но она не добавляет направление.Когда я ищу решения, the solution position.они предлагают, чтобы я мог добавить эти коды:

points,= ax.plot([],[],'b.',ms=6)
line, = ax.plot([],[],ms=6)

, где точки представляют положение N частиц каждый раз, а линия представляет направление, которое вычисляется по формуле:

dx = np.cos(self.theta)*v
dy = np.sin(self.theta)*v

и затем с использованием анимация функция animate function заменить переменные частицы на точки:

points.set_data(pointX[i,:],pointY[i,:])
line.set_data()?????

Затем line.set_data () что я не знаю, как сделать, я пытаюсь каким-то способом, но они делают все соединения линии.

Затем я пытаюсь matplotlib.quiver колчан , яобнаружить, что он не может двигаться в анимационной функции.

Затем я нахожу простой метод в github 2d plot .Это так просто, но я не могу использовать в своем pyqt5.

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

Буду признателен, если вы поможете мне!

Примеры анимации

import numpy as np
from scipy.spatial.distance import pdist, squareform

import matplotlib.pyplot as plt
import scipy.integrate as integrate
import matplotlib.animation as animation

class ParticleBox:
"""Orbits class

init_state is an [N x 4] array, where N is the number of particles:
   [[x1, y1, vx1, vy1],
    [x2, y2, vx2, vy2],
    ...               ]

bounds is the size of the box: [xmin, xmax, ymin, ymax]
"""
def __init__(self,
             init_state = [[1, 0, 0, -1],
                           [-0.5, 0.5, 0.5, 0.5],
                           [-0.5, -0.5, -0.5, 0.5]],
             bounds = [-2, 2, -2, 2],
             size = 0.04,
             M = 0.05,
             G = 9.8):
    self.init_state = np.asarray(init_state, dtype=float)
    self.M = M * np.ones(self.init_state.shape[0])
    self.size = size
    self.state = self.init_state.copy()
    self.time_elapsed = 0
    self.bounds = bounds
    self.G = G

def step(self, dt):
    """step once by dt seconds"""
    self.time_elapsed += dt

    # update positions
    self.state[:, :2] += dt * self.state[:, 2:]

    # find pairs of particles undergoing a collision
    D = squareform(pdist(self.state[:, :2]))
    ind1, ind2 = np.where(D < 2 * self.size)
    unique = (ind1 < ind2)
    ind1 = ind1[unique]
    ind2 = ind2[unique]

    # update velocities of colliding pairs
    for i1, i2 in zip(ind1, ind2):
        # mass
        m1 = self.M[i1]
        m2 = self.M[i2]

        # location vector
        r1 = self.state[i1, :2]
        r2 = self.state[i2, :2]

        # velocity vector
        v1 = self.state[i1, 2:]
        v2 = self.state[i2, 2:]

        # relative location & velocity vectors
        r_rel = r1 - r2
        v_rel = v1 - v2

        # momentum vector of the center of mass
        v_cm = (m1 * v1 + m2 * v2) / (m1 + m2)

        # collisions of spheres reflect v_rel over r_rel
        rr_rel = np.dot(r_rel, r_rel)
        vr_rel = np.dot(v_rel, r_rel)
        v_rel = 2 * r_rel * vr_rel / rr_rel - v_rel

        # assign new velocities
        self.state[i1, 2:] = v_cm + v_rel * m2 / (m1 + m2)
        self.state[i2, 2:] = v_cm - v_rel * m1 / (m1 + m2) 

    # check for crossing boundary
    crossed_x1 = (self.state[:, 0] < self.bounds[0] + self.size)
    crossed_x2 = (self.state[:, 0] > self.bounds[1] - self.size)
    crossed_y1 = (self.state[:, 1] < self.bounds[2] + self.size)
    crossed_y2 = (self.state[:, 1] > self.bounds[3] - self.size)

    self.state[crossed_x1, 0] = self.bounds[0] + self.size
    self.state[crossed_x2, 0] = self.bounds[1] - self.size

    self.state[crossed_y1, 1] = self.bounds[2] + self.size
    self.state[crossed_y2, 1] = self.bounds[3] - self.size

    self.state[crossed_x1 | crossed_x2, 2] *= -1
    self.state[crossed_y1 | crossed_y2, 3] *= -1

    # add gravity
    self.state[:, 3] -= self.M * self.G * dt


#------------------------------------------------------------
# set up initial state
np.random.seed(0)
init_state = -0.5 + np.random.random((50, 4))
init_state[:, :2] *= 3.9

box = ParticleBox(init_state, size=0.04)
dt = 1. / 30 # 30fps


#------------------------------------------------------------
# set up figure and animation
fig = plt.figure()
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111, aspect='equal', autoscale_on=False,
                 xlim=(-3.2, 3.2), ylim=(-2.4, 2.4))

# particles holds the locations of the particles
particles, = ax.plot([], [], 'bo', ms=6)

# rect is the box edge
rect = plt.Rectangle(box.bounds[::2],
                 box.bounds[1] - box.bounds[0],
                 box.bounds[3] - box.bounds[2],
                 ec='none', lw=2, fc='none')
ax.add_patch(rect)

def init():
    """initialize animation"""
    global box, rect
    particles.set_data([], [])
    rect.set_edgecolor('none')
    return particles, rect

def animate(i):
    """perform animation step"""
    global box, rect, dt, ax, fig
    box.step(dt)

    ms = int(fig.dpi * 2 * box.size * fig.get_figwidth()
            / np.diff(ax.get_xbound())[0])

    # update pieces of the animation
    rect.set_edgecolor('k')
    particles.set_data(box.state[:, 0], box.state[:, 1])
    particles.set_markersize(ms)
    return particles, rect

ani = animation.FuncAnimation(fig, animate, frames=600,
                          interval=10, blit=True, init_func=init)


# save the animation as an mp4.  This requires ffmpeg or mencoder to be
# installed.  The extra_args ensure that the x264 codec is used, so that
# the video can be embedded in html5.  You may need to adjust this for
# your system: for more information, see
# http://matplotlib.sourceforge.net/api/animation_api.html
#ani.save('particle_box.mp4', fps=30, extra_args=['-vcodec', 'libx264'])

plt.show()

Большое спасибо за напоминание о вставке кодов.

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