问题
I am currently trying to make a simulation in which multiple particle agents (blue dots) try to follow the enemy particle (red dot). I have managed to get my simulation to have one blue dot follow the red dot, but I am having trouble producing multiple version of the blue dots (also trying ot get it to appear at random initial locations) in the simulation and animating all of them to follow the red dot.
Any ideas on how to fix this?
Attempt to animate clones of blue particles:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from matplotlib.collections import PatchCollection
from matplotlib import cm
import random
fig = plt.figure()
fig.set_dpi(100)
fig.set_size_inches(5, 4.5)
ax = plt.axes(xlim=(0, 100), ylim=(0, 100))
enemy = plt.Circle((10, -10), 0.75, fc='r')
agent = plt.Circle((10, -10), 0.75, fc='b')
p = None
def init():
enemy.center = (5, 5)
agent.center = (random.randint(1, 100), random.randint(1, 100))
ax.add_patch(agent)
for x in range(0,5):
agent_clone = plt.Circle((10, -10), 0.75, fc='b')
agent_clone.center = (random.randint(1, 100), random.randint(1, 100))
patches_ac.append(agent_clone)
p = PatchCollection(patches_ac, cmap=cm.prism, alpha=0.4)
ax.add_collection(p)
ax.add_patch(enemy)
return []
def initalizePosition(agent,enemy):
x_a, y_a = agent.center
x_e, y_e = enemy.center
x_a += 50
y_a += 50
agent.center = (x_a, y_a)
enemy.center = (x_e, y_e)
return agent
def animationManage(i,agent,enemy):
animateCos(i,enemy)
#animateCirc(i,enemy)
#animateLine(i,agent)
followTarget(i,agent,enemy)
return []
def followTarget(i, patch, enemy_patch):
x, y = patch.center
# Calculating velocity
# v(t+1) = wv(t) + rand_1()c_1(p(t) - x(t)) + rand_2()c_2(g(t) - x(t))
v_x, v_y = velocity_calc(patch, enemy_patch)
# Implementing:
# x(t+1) = x(t) + v(t + 1)
# x position
x += v_x
# y position
y += v_y
patch.center = (x, y)
return patch,
def inertia_calc():
return 0
def top_speed_regulate(curr_speed):
top_speed = 0.5
if curr_speed > top_speed:
return top_speed
elif curr_speed < -top_speed:
return -top_speed
else:
return curr_speed
def velocity_calc(agent_patch, enemy_patch):
x, y = agent_patch.center
x_e, y_e = enemy_patch.center
pos_vect = np.array([x,y], dtype='f')
velo_vect = np.array([0.0,0.0], dtype='f')
velo_vect[0] = top_speed_regulate( (x_e - x)* 0.05 )
velo_vect[1] = top_speed_regulate( (y_e - y)* 0.05 )
return velo_vect[0], velo_vect[1]
def animateLine(i, patch):
x, y = patch.center
x += 0.25
y += 0.25
patch.center = (x, y)
return patch,
def animateCos(i, patch):
x, y = patch.center
x += 0.1
#x += 0.4
y = 50 + 30 * np.cos(np.radians(i))
#y = 50 + 10 * np.cos(np.radians(i))
patch.center = (x, y)
return patch,
def animateCirc(i, patch):
# It seems that i represents time step
x, y = patch.center
# 1st constant = position and 2nd constant = trajectory
x = 50 + 30 * np.sin(np.radians(i))
y = 50 + 30 * np.cos(np.radians(i))
patch.center = (x, y)
return patch,
anim = animation.FuncAnimation(fig, animationManage,
init_func=init,
frames=1000,
fargs=(agent,enemy,),
interval=1,
blit=True,
repeat=True)
plt.show()
Working version of the code with just one blue particle:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import random
fig = plt.figure()
fig.set_dpi(100)
fig.set_size_inches(5, 4.5)
ax = plt.axes(xlim=(0, 100), ylim=(0, 100))
enemy = plt.Circle((10, -10), 0.75, fc='r')
agent = plt.Circle((10, -10), 0.75, fc='b')
def init():
enemy.center = (5, 5)
agent.center = (random.randint(1, 100), random.randint(1, 100))
ax.add_patch(agent)
ax.add_patch(enemy)
return []
def initalizePosition(agent,enemy):
x_a, y_a = agent.center
x_e, y_e = enemy.center
x_a += 50
y_a += 50
agent.center = (x_a, y_a)
enemy.center = (x_e, y_e)
return agent
def animationManage(i,agent,enemy):
animateCos(i,enemy)
#animateCirc(i,enemy)
#animateLine(i,agent)
followTarget(i,agent,enemy)
return []
def followTarget(i, patch, enemy_patch):
x, y = patch.center
# Calculating velocity
# v(t+1) = wv(t) + rand_1()c_1(p(t) - x(t)) + rand_2()c_2(g(t) - x(t))
v_x, v_y = velocity_calc(patch, enemy_patch)
# Implementing:
# x(t+1) = x(t) + v(t + 1)
# x position
x += v_x
# y position
y += v_y
patch.center = (x, y)
return patch,
def inertia_calc():
return 0
def top_speed_regulate(curr_speed):
top_speed = 0.5
if curr_speed > top_speed:
return top_speed
elif curr_speed < -top_speed:
return -top_speed
else:
return curr_speed
def velocity_calc(agent_patch, enemy_patch):
x, y = agent_patch.center
x_e, y_e = enemy_patch.center
pos_vect = np.array([x,y], dtype='f')
velo_vect = np.array([0.0,0.0], dtype='f')
'''
velo_vect[0] = top_speed_regulate( (x_e - x)* 0.05 )* random.random()
velo_vect[1] = top_speed_regulate( (y_e - y)* 0.05 )* random.random()
'''
velo_vect[0] = top_speed_regulate( (x_e - x)* 0.05 )
velo_vect[1] = top_speed_regulate( (y_e - y)* 0.05 )
return velo_vect[0], velo_vect[1]
def animateLine(i, patch):
x, y = patch.center
x += 0.25
y += 0.25
patch.center = (x, y)
return patch,
def animateCos(i, patch):
x, y = patch.center
x += 0.1
#x += 0.4
y = 50 + 30 * np.cos(np.radians(i))
#y = 50 + 10 * np.cos(np.radians(i))
patch.center = (x, y)
return patch,
def animateCirc(i, patch):
# It seems that i represents time step
x, y = patch.center
# 1st constant = position and 2nd constant = trajectory
x = 50 + 30 * np.sin(np.radians(i))
y = 50 + 30 * np.cos(np.radians(i))
patch.center = (x, y)
return patch,
anim = animation.FuncAnimation(fig, animationManage,
init_func=init,
frames=1000,
fargs=(agent,enemy,),
interval=1,
blit=True,
repeat=True)
plt.show()
回答1:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import random
fig = plt.figure()
fig.set_dpi(100)
fig.set_size_inches(5, 4.5)
ax = plt.axes(xlim=(0, 100), ylim=(0, 100))
enemy = plt.Circle((10, -10), 0.75, fc='r')
agent = plt.Circle((10, -10), 0.75, fc='b')
patches_ac = []
ax.add_patch(agent)
for x in range(0, 5):
agent_clone = plt.Circle((10, -10), 0.75, fc='b')
agent_clone.center = (random.randint(1, 100), random.randint(1, 100))
patches_ac.append(agent_clone)
ax.add_patch(agent_clone)
ax.add_patch(enemy)
def init():
enemy.center = (5, 5)
agent.center = (random.randint(1, 100), random.randint(1, 100))
for ac in patches_ac:
ac.center = (random.randint(1, 100), random.randint(1, 100))
return []
def animationManage(i):
animateCos(i, enemy)
followTarget(i, agent, enemy)
for ac in patches_ac:
followTarget(i, ac, enemy)
return []
def followTarget(i, patch, enemy_patch):
x, y = patch.center
v_x, v_y = velocity_calc(patch, enemy_patch)
# x position
x += v_x
# y position
y += v_y
patch.center = (x, y)
return patches_ac
def top_speed_regulate(curr_speed):
top_speed = 0.5
if curr_speed > top_speed:
return top_speed
elif curr_speed < -top_speed:
return -top_speed
else:
return curr_speed
def velocity_calc(agent_patch, enemy_patch):
x, y = agent_patch.center
x_e, y_e = enemy_patch.center
velo_vect = np.array([0.0, 0.0], dtype='f')
velo_vect[0] = top_speed_regulate( (x_e - x)* 0.05 )
velo_vect[1] = top_speed_regulate( (y_e - y)* 0.05 )
return velo_vect[0], velo_vect[1]
def animateCos(i, patch):
x, y = patch.center
x += 0.1
y = 50 + 30 * np.cos(np.radians(i))
patch.center = (x, y)
return patch,
anim = animation.FuncAnimation(fig, animationManage,
init_func=init,
frames=1000,
interval=1,
blit=True,
repeat=True)
plt.show()
来源:https://stackoverflow.com/questions/38446295/cannot-animate-clones-of-the-same-patch-in-python-matplotlib