[关闭]
@2014301020054 2016-10-30T16:49:49.000000Z 字数 4910 阅读 587

Exercise_6:The trajectory of a cannon shell_2

physics python


Abstract

2.10 Generalize the program developed for the previous problem so that it can deal with situations in which the target is at a different altitude than the cannon. Consider cases in which the target is higher and lower than the cannon. Also investigate how the minimum firing velocity required to hit the target varies as the altitude of the target is varied.


Background

The Euler method we used to treat the bicycle problem can easily be generalized to deal with motion in two spatial dimensions. To be specific, we consider a projectile such as a shell shot by a cannon. We have a very large cannon in mind, and the large size will determine some of the important physics...


Main body

2.10 Generalize the program developed for the previous problem so that it can deal with situations in which the target is at a different altitude than the cannon. Consider cases in which the target is higher and lower than the cannon. Also investigate how the minimum firing velocity required to hit the target varies as the altitude of the target is varied.

Solution

We firstly define a function pre_run_test to calculate the range of da and dxdy to save the operation time.

  1. def pre_run_test(self):
  2. _a= 0.001*math.pi
  3. da= 0.001*math.pi
  4. dxdy=1.0
  5. aa=[]
  6. t=1
  7. a_max=0.5 * math.pi
  8. while(t<8):
  9. can2=0
  10. while (_a < a_max):
  11. can = 0
  12. vx = math.cos(_a) * self.v
  13. vy = math.sin(_a) * self.v
  14. xi = [0]
  15. yi = [0]
  16. while (yi[-1] >= 0):
  17. xi.append(xi[-1] + self.dt * vx)
  18. yi.append(yi[-1] + self.dt * vy)
  19. v = ((vx + self.Vw)**2+vy**2)**0.5
  20. vx = vx \
  21. - math.exp(-yi[-1] / 10) * self.b_m * v * vx * self.dt
  22. vy = vy \
  23. - self.g * self.dt \
  24. - math.exp(-yi[-1] / 10) * self.b_m * v * vy * self.dt
  25. if (abs(xi[-1] - self.xt) < dxdy and abs(yi[-1] - self.yt) < dxdy):
  26. can = 1
  27. break
  28. if can:
  29. aa.append(_a)
  30. can2=2
  31. elif can==0 and can2>1: break
  32. _a = _a + da
  33. if aa==[]:
  34. if t==1 :print "无法命中目标"
  35. else:break
  36. _a=min(aa)-da
  37. a_max=max(aa)+da
  38. da=da/5
  39. dxdy=dxdy/4
  40. _aa =aa
  41. aa=[]
  42. print t
  43. t+=1
  44. self.a= 0.5*max(_aa)+0.5*min(_aa)
  45. self.dxdy=dxdy*4

The running results are normal.

And the total codes can be typed like this:

codes

  1. #coding:utf-8
  2. import pylab as pl
  3. import math
  4. import random
  5. class cannon_shell:
  6. def __init__(self,initial_velocity=0.7,g=0.0098,range=0,height=0,target_range=10,target_height=10,time_step=0.005,\
  7. da=0.00001*math.pi,\
  8. wind_speed=0.01,accuracy=0.01):
  9. self.v=initial_velocity
  10. self.Vw=wind_speed
  11. self.a=math.atan((target_height-height)/(target_range-range))
  12. self.g=g
  13. self.dt=time_step
  14. self.da=da
  15. self.x=[range]
  16. self.y=[height]
  17. self.xt=target_range
  18. self.yt=target_height
  19. self.b_m=0.04
  20. self.ture_x=[]
  21. self.ture_y=[]
  22. self.dxdy=accuracy
  23. def pre_run_test(self):
  24. _a= 0.001*math.pi
  25. da= 0.001*math.pi
  26. dxdy=1.0
  27. aa=[]
  28. t=1
  29. a_max=0.5 * math.pi
  30. while(t<8): #减少计算时间用
  31. can2=0 #辅助跳出循环用
  32. while (_a < a_max):
  33. can = 0 # 判断命中用
  34. vx = math.cos(_a) * self.v
  35. vy = math.sin(_a) * self.v
  36. xi = [0]
  37. yi = [0]
  38. while (yi[-1] >= 0):
  39. xi.append(xi[-1] + self.dt * vx)
  40. yi.append(yi[-1] + self.dt * vy)
  41. v = ((vx + self.Vw)**2+vy**2)**0.5
  42. vx = vx \
  43. - math.exp(-yi[-1] / 10) * self.b_m * v * vx * self.dt
  44. vy = vy \
  45. - self.g * self.dt \
  46. - math.exp(-yi[-1] / 10) * self.b_m * v * vy * self.dt
  47. if (abs(xi[-1] - self.xt) < dxdy and abs(yi[-1] - self.yt) < dxdy): # 判断是否命中
  48. can = 1
  49. break
  50. if can: #找出近似的角度
  51. aa.append(_a)
  52. can2=2
  53. elif can==0 and can2>1: break #跳出之后的多余循环
  54. _a = _a + da
  55. if aa==[]:
  56. if t==1 :print "无法命中目标" #第一次循环时如果无法命中则判断无法命中目标
  57. else:break #输出当前条件下可以达成的最高精度,使程序不至报错
  58. _a=min(aa)-da
  59. a_max=max(aa)+da
  60. da=da/5
  61. dxdy=dxdy/4
  62. _aa =aa #将本次正确计算的结果保存在_aa中
  63. aa=[]
  64. print t
  65. t+=1
  66. self.a= 0.5*max(_aa)+0.5*min(_aa)
  67. self.dxdy=dxdy*4
  68. def run(self): #绘制图象用
  69. _a = self.a
  70. vx = math.cos(_a) * self.v
  71. vy = math.sin(_a) * self.v
  72. xi = [0]
  73. yi = [0]
  74. t=0
  75. while (yi[-1] >= 0):
  76. t=t+self.dt
  77. xi.append(xi[-1] + self.dt * vx)
  78. yi.append(yi[-1] + self.dt * vy)
  79. v = ((vx + self.Vw) ** 2 + vy ** 2) ** 0.5
  80. vx = vx \
  81. - math.exp(-yi[-1] / 10) * self.b_m * v * vx * self.dt
  82. vy = vy \
  83. - self.g * self.dt \
  84. - math.exp(-yi[-1] / 10) * self.b_m * v * vy * self.dt
  85. if (abs(xi[-1] - self.xt) < self.dxdy and abs(yi[-1] - self.yt) < self.dxdy): # 判断是否命中
  86. print abs(xi[-1] - self.xt), abs(yi[-1] - self.yt)
  87. print abs(xi[-1]), yi[-1],t
  88. print ((xi[-1] - self.xt)**2+(yi[-1] - self.yt)**2)**0.5
  89. self.ture_x = xi
  90. self.ture_y = yi
  91. def show_result(self):
  92. x_y=self.ture_y+self.ture_x
  93. xy=max(x_y)+1
  94. pl.plot(self.xt,self.yt,'r*')
  95. pl.plot(self.ture_x,self.ture_y,color="green",linewidth=1)
  96. pl.xlabel('x ($m$)')
  97. pl.ylim(0, xy)
  98. pl.xlim(0, xy)
  99. pl.ylabel('y ($m$)')
  100. pl.show()
  101. a=cannon_shell()
  102. a.pre_run_test()
  103. a.run()
  104. a.show_result()

!number_1

number_2

Then initial codes can be modified like this:

  1. def __init__(self,initial_velocity=0.7,g=0.0098,range=0,height=0,target_range=20,target_height=5,time_step=0.005,\
  2. da=0.00001*math.pi,\
  3. wind_speed=0.01,accuracy=0.01):
  4. ...
  5. ...
  6. ...

number_3

number_4


Conclusion

The final number of the running result is variance.

The initial number can also be set to many other parameters as you like. And the variance can be given easily.


Acknowledgment

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注