fork download
  1. #!/usr/bin/env python3
  2.  
  3. import argparse
  4. from itertools import accumulate, count, cycle, repeat, takewhile
  5. from math import cos, gcd, pi, sin
  6. import matplotlib.pyplot as plt
  7. from matplotlib.animation import FuncAnimation
  8.  
  9. parser = argparse.ArgumentParser()
  10. parser.add_argument('v0', help = '初速度', type = float)
  11. parser.add_argument('theta', help = '入射角', type = float)
  12. parser.add_argument('-w', '--width', help = '横軸', type = int, default = 8)
  13. parser.add_argument('--height', help = '縦軸', type = int, default = 6)
  14. parser.add_argument('-dt', help = '微小時間', type = float, default = 0.04)
  15. parser.add_argument('-y0', help = '初期位置(高さ)', type = float, default = 0)
  16. parser.add_argument('-s', '--scale', help = '倍率', type = int, default = 10)
  17.  
  18. if __name__ == '__main__':
  19. args = parser.parse_args()
  20. width, height = args.width * args.scale, args.height * args.scale
  21.  
  22. # Figure と Axes
  23. fig, ax = plt.subplots()
  24. ax.grid()
  25. ax.set(xlim = [0, width], ylim = [-height//2, height//2], xlabel = 'x', ylabel = 'y')
  26.  
  27. # 初期条件設定
  28. dt = args.dt
  29. y0 = args.y0
  30. v0 = args.v0
  31. degree = args.theta * pi / 180
  32. g = -9.8
  33.  
  34. # x, y 座標計算
  35. positions = takewhile(
  36. lambda r: r[0] >= 0 and r[0] <= width and
  37. r[1] >= - height/2 and r[1] <= height / 2,
  38. accumulate(
  39. zip(
  40. repeat(v0 * cos(degree)),
  41. accumulate(
  42. count(),
  43. func = lambda v, n: v + g * dt,
  44. initial = v0 * sin(degree) + 0.5 * g * dt
  45. )
  46. ),
  47. func = lambda r, v: (r[0] + v[0] * dt, r[1] + v[1] * dt),
  48. initial = (0, y0)
  49. )
  50. )
  51.  
  52. # ボールの作成
  53. ball = ax.scatter(*next(positions), 5, color = "r", label = f'v0 = {v0} m/s')
  54.  
  55. # ボールの更新関数
  56. def update(frame):
  57. ball.set_offsets(frame)
  58. return (ball,)
  59.  
  60. # アニメーション作成
  61. anim = FuncAnimation(
  62. fig,
  63. update,
  64. frames = positions,
  65. interval = 1000 * dt,
  66. blit = True
  67. )
  68.  
  69. fig.suptitle("Projectile Motion")
  70. # anim.save('projectile.gif') # gifアニメを作る
  71. plt.show()
  72.  
Runtime error #stdin #stdout #stderr 2.29s 53848KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
usage: prog [-h] [-w WIDTH] [--height HEIGHT] [-dt DT] [-y0 Y0] [-s SCALE]
            v0 theta
prog: error: the following arguments are required: v0, theta