【发布时间】:2019-11-20 00:27:08
【问题描述】:
目标是动画/模拟洒水器。基本思想是在一个实例中创建多个液滴,每个液滴以不同的角度离开喷头。 然而,我得到的是一条直线,而不是一个移动的点。我尝试了相同的代码,只有一到两滴/点,但我仍然得到相同的直线。起初我以为是因为我在动画中加入了拖动(在之前的试验中,当我加入拖动时,我得到了奇怪/意外的结果,所以我希望这是同样的问题)
下面是我写的代码。
编辑:dragx 和 dragy 不再设置为相同的值。初始速度在更新函数之外计算。
每次指数增加时都会重新计算阻力,因为阻力取决于速度。
现在还包括导入。
我现在还尝试使用散点图而不是线,这在原点处给了我一个点。从那以后我又回到了这条线上
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
from math import sin, cos
import matplotlib.axes as axess
#pressure in system
def pressure(pump):
return 10.197*pump*10**5/998.2
#Initial velocity based on the pressure of the system
def vinit(init_head):
return (2*9.81*init_head)**0.5
# Number of droplets per iteration
n = 2
v0 = vinit(pressure(5.8))
cd = 0.5 #drag coefficient of a sphere;
rho = 1.225 #density of air; kg/m^3
fps = 20
runtime = 1*20
numframes = fps*runtime
time = np.linspace(0,runtime,numframes)
#Initialize droplets
droplets = np.zeros(numframes, dtype = [('position', float, 2),
('velocity', float, 2),
('force', float, 2),
('angle',float, 1),
('radius', float, 1)])
droplets['radius'] = np.random.normal(0.0045, 0.001, numframes)
A = 4*np.pi*droplets['radius']**2
mass = ((4*np.pi*droplets['radius']**3)/3)*1000 #mass of waterdroplet
drag = np.zeros(numframes,dtype = [('dragx', float, 1),('dragy', float, 1)])
rads = np.radians(np.random.normal(37,1,numframes))
droplets['angle'] = rads
droplets['force'][:,1] = -9.8*mass
#Initialize velocity
for i in range(0, numframes):
droplets['velocity'][i,0] = v0*cos(droplets['angle'][i])
droplets['velocity'][i,1] = v0*sin(droplets['angle'][i])
#Initialize the drag
drag['dragx'] = -0.5*rho*cd*A*droplets['velocity'][:,0]
drag['dragy'] = -0.5*rho*cd*A*droplets['velocity'][:,1]
droplets['position'][:,0] = 0
#Initialize the figure
fig,ax = plt.subplots()
axess.Axes.set_frame_on(ax,True)
ax.autoscale(True)
ax.set_xlim(0)
ax.set_ylim(0)
line = ax.plot(droplets['position'][0, 0], droplets['position'][0, 1],'b.')[0]
line = ax.plot(droplets['position'][:, 0], droplets['position'][:, 1],'b.')[0]
xdata = [droplets['position'][0, 0]]
ydata = [droplets['position'][0, 1]]
ln = plt.plot([],[],'b')[0]
def initfunc():
droplets['position'][0,:] = 0
ln.set_data(droplets['position'][0, 0], droplets['position'][0, 1])
return ln
def update(framenum):
index = framenum
cd = 0.5 #drag coefficient of a sphere;
rho = 1.225 #density of air; kg/m^3
A = 4*np.pi*droplets['radius']**2 #surface area of droplet; m^2
mass = ((4*np.pi*droplets['radius']**3)/3)*1000 #mass of waterdroplet
#Update the drag force on the droplet
drag['dragx'] = -0.5*rho*cd*A*droplets['velocity'][:,0]
drag['dragy'] = -0.5*rho*cd*A*droplets['velocity'][:,1]
droplets['force'][index,0] += drag['dragx'][index]
droplets['force'][index,1] += drag['dragy'][index]
#droplets['position'][0] = [0,0]
droplets['velocity'][index,0] = droplets['velocity'][index,0] + (droplets['force'][index,0]/mass[index])*index
droplets['velocity'][index,1] = droplets['velocity'][index,1] + (droplets['force'][index,1]/mass[index])*index
droplets['position'][index,0] = droplets['position'][index,0] + (droplets['velocity'][index,0])*index
droplets['position'][index,1] = droplets['position'][index,1] + (droplets['velocity'][index,1])*index
xdata.append(droplets['position'][index,0])
ydata.append(droplets['position'][index,1])
ln.set_data(xdata,ydata)
line.set_data(droplets['position'][:,0], droplets['position'][:,1])
return ln
sprink = animation.FuncAnimation(fig, update,init_func = initfunc,interval= 200, frames = numframes)
plt.show()
sprink.save('Sprinkler.mp4', fps = fps)
【问题讨论】:
-
在
update()drag['dragx']和drag['dragy']内部设置为相同的值。为什么?此外,每次更新时都会一次又一次地重新计算所有阻力值。也许只对当前索引这样做?
标签: python matplotlib animation physics projectile