动画弹丸的轨迹Python

时间:2016-11-07 16:32:31

标签: python physics projectile

我正在努力学习python,而不是之前的问题,因为我的实习已经结束,我遇到了问题

我正在使用一本书"用Python做数学"作者:阿米特萨哈,我决定跳到那里,就是给动物的弹道动画。我花了一个小时试图自己解决这个问题,然后在互联网上再过2天,我仍然无法理解为什么我会收到错误

  

AttributeError:' float'对象没有属性'追加'

如果我在代码中没有浮动,那么它根本不起作用我得到了这个

  

TypeError:需要浮点数

我希望在我们将高中物理学中的射弹运动单元留下来之前完成这个项目,这是我学会做的一件很酷的事情。请帮忙。我可以得到它来绘制轨迹,只是没有动画它:(

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)

1 个答案:

答案 0 :(得分:3)

您的代码非常接近!现在,基于变量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

现在代码将会运行,但是对于各种速度和方法,情节看起来会非常不同。事实上,对于许多初始条件,您只会看到蓝色图。让我们一个一个地看问题:

  1. 球的半径rad为1米。如果球在x方向或y方向上移动不到1米,那么蓝色球将占据屏幕的主导地位。
  2. x轴和y轴具有非常不同的尺寸和比例。这将使球变成椭圆形而不是圆形。
  3. 我更改了您的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()