【问题标题】:How to plot animated dots moving inside a circle?如何绘制在圆圈内移动的动画点?
【发布时间】:2016-04-23 16:31:03
【问题描述】:

我正在尝试编写一个函数来生成在圆圈内移动的点。我已经有一个用 matpltolib 动画绘制动画点的函数(感谢 Tony Babarino),但是我在编写迫使点留在圆圈中的部分时遇到了麻烦

这就是产生运动的部分的工作原理

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

# Initializing number of dots
N = 25


# Creating dot class
class dot(object):
    def __init__(self):
        self.x = 10 * np.random.random_sample()
        self.y = 10 * np.random.random_sample()
        self.velx = self.generate_new_vel()
        self.vely = self.generate_new_vel()

    def generate_new_vel(self):
        return (np.random.random_sample() - 0.5) / 5

    def move(self) :
            if np.random.random_sample() < 0.95:
                self.x = self.x + self.velx
                self.y = self.y + self.vely
            else:
                self.velx = self.generate_new_vel()
                self.vely = self.generate_new_vel()
                self.x = self.x + self.velx
                self.y = self.y + self.vely

# Initializing dots
dots = [dot() for i in range(N)]

# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax = plt.axes(xlim=(0, 10), ylim=(0, 10))
d, = ax.plot([dot.x for dot in dots],
             [dot.y for dot in dots], 'ro', markersize=3)
circle = plt.Circle((5, 5), 1, color='b', fill=False)
ax.add_artist(circle)


# animation function.  This is called sequentially
def animate(i):
    for dot in dots:
        dot.move()
    d.set_data([dot.x for dot in dots],
               [dot.y for dot in dots])
    return d,

# call the animator. 
anim = animation.FuncAnimation(fig, animate, frames=200, interval=20)

plt.show()

我想通过添加一个强制圆点饱和的部分来改进功能移动 我希望圆的边界像栅栏一样,点不能越过

我知道如何检测点何时越线,但我不知道在那之后该怎么做。

非常感谢您的帮助

【问题讨论】:

  • 你需要明确当一个点碰到圆的边界时你想要发生什么:它会反弹回来吗?留在这?再次出现在另一边?无论如何,中心思想是您需要强制执行圆约束:x**2 + y**2 &lt; R**2
  • 点应该会反弹
  • 然后你可以简单地反转速度的符号(两个分量)。由于您的圆的中心不在原点,因此在这种情况下,方程式略有不同:(x - xc)**2 + (y - yc)**2 &lt; R**2,当此条件为真时,该点位于圆心在 xc、yc 和半径 R 的圆内。
  • 感谢您的帮助。我试过了,但效果不太好,有时圆点会卡在圆圈的边缘并开始振动,这很奇怪。
  • 而且如果我让代码运行很长时间,有几个点设法逃脱我不明白为什么

标签: python python-3.x animation matplotlib geometry


【解决方案1】:

我更改了代码,这样您就不会遇到振动和逃脱圈子的问题。进入圆圈的每个点都不会逃逸(这些点在开始时可以在圆圈之外),也不会在圆圈的边缘振动。 将 numpy 导入为 np 从 matplotlib 导入 pyplot 作为 plt 从 matplotlib 导入动画

# Initializing number of dots
N = 25
XC = 5
YC = 5
R = 1
R_SQR = R **2

# Creating dot class
class dot(object):
    def __init__(self, ind):
        self.x = 10 * np.random.random_sample()
        self.y = 10 * np.random.random_sample()
        self.velx = self.generate_new_vel()
        self.vely = self.generate_new_vel()
        self.in_circle = not self.calc_out_of_circle()

    def generate_new_vel(self):
        return (np.random.random_sample() - 0.5) / 5

    def move(self) :
        if np.random.random_sample() < 0.95:
            self.check_out_of_circle()
            self.x += self.velx
            self.y += self.vely
        else:
            self.velx = self.generate_new_vel()
            self.vely = self.generate_new_vel()
            self.check_out_of_circle()
            self.x += self.velx
            self.y += self.vely
        self.check_inside_circle()

    def calc_out_of_circle_with_params(self, x, y):
        return (x - XC) ** 2 + (y - YC) ** 2 >= R_SQR ** 2

    def calc_out_of_circle(self):
        return self.calc_out_of_circle_with_params(self.x, self.y)

    def check_out_of_circle(self):
        if self.in_circle and self.calc_out_of_circle_with_params(self.x + self.velx, self.y + self.vely):
            self.velx = -self.velx
            self.vely = -self.vely

    def check_inside_circle(self):
        if not self.calc_out_of_circle():
            self.in_circle = True


# Initializing dots
dots = [dot(i) for i in range(N)]

# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax = plt.axes(xlim=(0, 10), ylim=(0, 10))
d, = ax.plot([dot.x for dot in dots],
             [dot.y for dot in dots], 'ro', markersize=3)
circle = plt.Circle((XC, YC), R, color='b', fill=False)
ax.add_artist(circle)


# animation function.  This is called sequentially
def animate(i):
    for dot in dots:
        dot.move()
    d.set_data([dot.x for dot in dots],
               [dot.y for dot in dots])
    return d,

# call the animator.
anim = animation.FuncAnimation(fig, animate, frames=200, interval=20)
# plt.axis('equal')
plt.show()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    相关资源
    最近更新 更多