动画射弹的轨迹 Python
Animating a Projectile's Trajectory Python
现在我的实习结束了,我遇到了一个问题,因此我正在努力学习 python 比我以前的问题更深入的知识
我正在使用 Amit Saha 的一本书 "Doing Math With Python",我决定跳转到这本书是“动画射弹的轨迹”。我花了一个小时试图自己解决这个问题,然后又在互联网上花了 2 天时间,但我仍然不明白为什么我会收到我收到的错误
AttributeError: 'float' object has no attribute 'append'
如果代码中没有浮点数,那么它根本不起作用,我得到了这个
TypeError: a float is required
我希望在我们离开高中物理中的弹丸运动单元之前,满怀希望地完成这个项目,就像我学会做的一件很酷的事情一样。请帮忙。我可以用它来绘制轨迹,只是不设置动画:(
from matplotlib import pyplot as plt
from matplotlib import animation
import math
g = 9.8
def get_intervals(u, theta):
t_flight = 2*u*math.sin(theta)/g
intervals = []
start = 0
intervals = 0.005
while start < t_flight:
intervals.append(start)
start = start + interval
return intervals
def update_position(i, circle, intervals, u, theta):
t = intervals[i]
x = u*math.cos(theta)*t
y = u*math.sin(theta)*t - 0.5*g*t*t
circle.center = x, y
return circle,
def create_animation(u, theta):
intervals = get_intervals(u,theta)
xmin = 0
xmax = u*math.cos(theta)*intervals[-1]
ymin = 0
t_max = u*math.sin(theta)/g
ymax = u*math.sin(theta)*t_max - 0.5*g*t_max**2
fig = plt.gcf()
ax = plt.axes(xlim=(xmin, xmax), ylim=(ymin, ymax))
circle = plt.Circle((xmin, ymin), 1.0)
ax.add_patch(circle)
anim = animation.FuncAnimation(fig, update_position,
fargs=(circle, intervals, u, theta),
frames=len(intervals), interval=1,
repeat=False)
plt.title('Projectile Motion')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
if __name__ == '__main__':
try:
u = float(input('Enter the initial velocity (m/s): '))
theta = float(input('Enter the angle of projection (degrees): '))
except ValueError:
print('You Entered an invalid input')
else:
theta = (math.radians(theta))
create_animation(u, theta)
您的代码非常接近!现在有一个基于变量 intervals
被定义两次而变量 interval
从未被定义的错误。因此,将 intervals = 0.005
更改为 interval = 0.005
,如下代码所示:
def get_intervals(u, theta):
t_flight = 2*u*math.sin(theta)/g
intervals = []
start = 0
interval = 0.005
while start < t_flight:
intervals.append(start)
start = start + interval
return intervals
现在代码将 运行 但对于不同的速度和 thetas,绘图看起来会非常不同。事实上,对于许多初始条件,您只会看到蓝色图。让我们一一来看问题:
- 球的半径
rad
为 1 米。如果球在 x 方向或 y 方向上的行进距离小于 1 m,则蓝色球将占据屏幕。
- x 轴和 y 轴的大小和刻度非常不同。这将使球变成椭圆形而不是圆形。
我更改了您的 create_animation()
功能以解决这些小问题。请阅读我放置的评论以了解细微的变化
def create_animation(u, theta):
intervals = get_intervals(u,theta)
xmin = 0
xmax = u*math.cos(theta)*intervals[-1]
ymin = 0
t_max = u*math.sin(theta)/g
ymax = u*math.sin(theta)*t_max - 0.5*g*t_max**2
plotmax = max(xmax, ymax) # Pick the largest dimension of the two
fig = plt.gcf()
# Set both maxima to the same value to make a square plot
ax = plt.axes(xlim=(xmin, plotmax), ylim=(ymin, plotmax))
# Make sure the two axes are scaled the same...
# (we want a circle.. not a messed up oval)
ax.set_aspect('equal')
rad = plotmax/20. # Make sure the circle doesn't dominate the plot
circle = plt.Circle((xmin, ymin), rad) # Use rad instead of 1.0
ax.add_patch(circle)
anim = animation.FuncAnimation(fig, update_position,
fargs=(circle, intervals, u, theta),
frames=len(intervals), interval=1,
repeat=False)
plt.title('Projectile Motion')
plt.xlabel('X [m]') # Units are nice :)
plt.ylabel('Y [m]')
plt.show()
现在我的实习结束了,我遇到了一个问题,因此我正在努力学习 python 比我以前的问题更深入的知识
我正在使用 Amit Saha 的一本书 "Doing Math With Python",我决定跳转到这本书是“动画射弹的轨迹”。我花了一个小时试图自己解决这个问题,然后又在互联网上花了 2 天时间,但我仍然不明白为什么我会收到我收到的错误
AttributeError: 'float' object has no attribute 'append'
如果代码中没有浮点数,那么它根本不起作用,我得到了这个
TypeError: a float is required
我希望在我们离开高中物理中的弹丸运动单元之前,满怀希望地完成这个项目,就像我学会做的一件很酷的事情一样。请帮忙。我可以用它来绘制轨迹,只是不设置动画:(
from matplotlib import pyplot as plt
from matplotlib import animation
import math
g = 9.8
def get_intervals(u, theta):
t_flight = 2*u*math.sin(theta)/g
intervals = []
start = 0
intervals = 0.005
while start < t_flight:
intervals.append(start)
start = start + interval
return intervals
def update_position(i, circle, intervals, u, theta):
t = intervals[i]
x = u*math.cos(theta)*t
y = u*math.sin(theta)*t - 0.5*g*t*t
circle.center = x, y
return circle,
def create_animation(u, theta):
intervals = get_intervals(u,theta)
xmin = 0
xmax = u*math.cos(theta)*intervals[-1]
ymin = 0
t_max = u*math.sin(theta)/g
ymax = u*math.sin(theta)*t_max - 0.5*g*t_max**2
fig = plt.gcf()
ax = plt.axes(xlim=(xmin, xmax), ylim=(ymin, ymax))
circle = plt.Circle((xmin, ymin), 1.0)
ax.add_patch(circle)
anim = animation.FuncAnimation(fig, update_position,
fargs=(circle, intervals, u, theta),
frames=len(intervals), interval=1,
repeat=False)
plt.title('Projectile Motion')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
if __name__ == '__main__':
try:
u = float(input('Enter the initial velocity (m/s): '))
theta = float(input('Enter the angle of projection (degrees): '))
except ValueError:
print('You Entered an invalid input')
else:
theta = (math.radians(theta))
create_animation(u, theta)
您的代码非常接近!现在有一个基于变量 intervals
被定义两次而变量 interval
从未被定义的错误。因此,将 intervals = 0.005
更改为 interval = 0.005
,如下代码所示:
def get_intervals(u, theta):
t_flight = 2*u*math.sin(theta)/g
intervals = []
start = 0
interval = 0.005
while start < t_flight:
intervals.append(start)
start = start + interval
return intervals
现在代码将 运行 但对于不同的速度和 thetas,绘图看起来会非常不同。事实上,对于许多初始条件,您只会看到蓝色图。让我们一一来看问题:
- 球的半径
rad
为 1 米。如果球在 x 方向或 y 方向上的行进距离小于 1 m,则蓝色球将占据屏幕。 - x 轴和 y 轴的大小和刻度非常不同。这将使球变成椭圆形而不是圆形。
我更改了您的 create_animation()
功能以解决这些小问题。请阅读我放置的评论以了解细微的变化
def create_animation(u, theta):
intervals = get_intervals(u,theta)
xmin = 0
xmax = u*math.cos(theta)*intervals[-1]
ymin = 0
t_max = u*math.sin(theta)/g
ymax = u*math.sin(theta)*t_max - 0.5*g*t_max**2
plotmax = max(xmax, ymax) # Pick the largest dimension of the two
fig = plt.gcf()
# Set both maxima to the same value to make a square plot
ax = plt.axes(xlim=(xmin, plotmax), ylim=(ymin, plotmax))
# Make sure the two axes are scaled the same...
# (we want a circle.. not a messed up oval)
ax.set_aspect('equal')
rad = plotmax/20. # Make sure the circle doesn't dominate the plot
circle = plt.Circle((xmin, ymin), rad) # Use rad instead of 1.0
ax.add_patch(circle)
anim = animation.FuncAnimation(fig, update_position,
fargs=(circle, intervals, u, theta),
frames=len(intervals), interval=1,
repeat=False)
plt.title('Projectile Motion')
plt.xlabel('X [m]') # Units are nice :)
plt.ylabel('Y [m]')
plt.show()