想象有人从阳台上以一定的角度theta
和速度v0
(阳台的高度表示为ystar
)。在二维中看这个问题,考虑阻力,你会得到一个微分方程组,可以用龙格库塔方法来求解(我选择显式的中点,不确定这个问题的布彻表是什么)。我实现了这个,它工作得非常好,对于一些给定的初始条件,我得到了运动粒子的轨迹。在
我的问题是我想修正两个初始条件(x轴上的起点为零,y轴上的起点为ystar
),并确保轨迹穿过x轴上的某个点(我们称之为xstar
)。对于这一点,当然存在其他两个初始条件的多重组合,在这种情况下,是x和y方向的速度。问题是我不知道如何实现它。在
到目前为止,我用来解决问题的代码:
1)Runge-Kutta方法的实现
import numpy as np
import matplotlib.pyplot as plt
def integrate(methode_step, rhs, y0, T, N):
star = (int(N+1),y0.size)
y= np.empty(star)
t0, dt = 0, 1.* T/N
y[0,...] = y0
for i in range(0,int(N)):
y[i+1,...]=methode_step(rhs,y[i,...], t0+i*dt, dt)
t = np.arange(N+1) * dt
return t,y
def explicit_midpoint_step(rhs, y0, t0, dt):
return y0 + dt * rhs(t0+0.5*dt,y0+0.5*dt*rhs(t0,y0))
def explicit_midpoint(rhs,y0,T,N):
return integrate(explicit_midpoint_step,rhs,y0,T,N)
微分方程和Cernessy参数的实现
^{pr2}$3)用它解决问题
^{3}$4)可视化
plt.figure()
plt.plot(0,ystar,"ro")
plt.plot(x,0,"ro")
plt.plot(z[:,0],z[:,1])
plt.grid(True)
plt.xlabel(r"$x$")
plt.ylabel(r"$y$")
plt.show()
为了使问题具体化:考虑到这一点,我如何找到v0
和{z[some_element,0]==xstar
我当然尝试了一些东西,主要是用蛮力法固定theta
,然后尝试所有可能的速度(在一个合理的间隔内),但最后不知道如何将结果数组与期望的结果进行比较。。。在
由于这主要是一个编码问题,我希望堆栈溢出是请求帮助的正确位置。。。在
编辑: 根据要求,我试着从上面解决问题(替换3和4)。。在
theta = np.pi/4.
xy = np.zeros((50,1001,2))
z1 = np.zeros((1001,2))
count=0
for v0 in range(0,50):
v0x = v0 * np.cos(theta)
v0y = v0 * np.sin(theta)
z0 = np.array([0, v0x, ystar, v0y])
# Calculate solution
t, z = explicit_midpoint(rhs, z0, 5, 1000)
if np.around(z[:,0],3).any() == round(xstar,3):
z1[:,0] = z[:,0]
z1[:,1] = z[:,2]
break
else:
xy[count,:,0] = z[:,0]
xy[count,:,1] = z[:,2]
count+=1
plt.figure()
plt.plot(0,ystar,"ro")
plt.plot(xstar,0,"ro")
for k in range(0,50):
plt.plot(xy[k,:,0],xy[k,:,1])
plt.plot(z[:,0],z[:,1])
plt.grid(True)
plt.xlabel(r"$x$")
plt.ylabel(r"$y$")
plt.show()
我确信我使用.any()
函数是错误的,我们的想法是将z[:,0]
的值四舍五入为三位数,然后将它们与xstar
进行比较,如果匹配,则循环应终止并重新运行当前的z
,如果不匹配,则应将其保存在另一个数组中,然后增加v0
。在
编辑2018-07-16
在这里,我发布了一个考虑到空气阻力的正确答案。在
下面是一个python脚本,用于计算}的依赖性。达到正确的
(v0,theta)
值的集合,以便空气拖动轨迹在某个时间通过(x,y) = (xstar,0)
。我使用没有空气阻力的轨迹作为初始猜测,并且还猜测了x(tstar)
对{v0
所需的迭代次数通常是3到4次。这个脚本在我的笔记本电脑上完成了0.99秒,包括生成数字的时间。在脚本生成两个图形和一个文本文件。在
fig_xdrop_v0_theta.png
(v0,theta)
(v0,theta)
,如果没有空气阻力,这将是一个解决方案。在fig_traj_sample.png
(v0,theta)
进行采样时,轨迹(蓝色实线)是否通过(x,y)=(xstar,0)
。在output.dat
(v0,theta)
的数值数据,以及着陆时间tstar
和找到{脚本开始了。在
这是图
fig_xdrop_v0_theta.png
。在这是图
fig_traj_sample.png
。在编辑2018-07-15
我意识到我忽略了这个问题考虑的是空气阻力。真可惜。所以,我下面的答案是不正确的。我担心自己删除我的答案看起来像是在隐藏一个错误,我现在就把它留在下面。如果有人认为不正确的答案到处都是令人讨厌的,我没问题,有人把它删掉。在
微分方程实际上可以用手来求解, 而且不需要太多的计算资源 找出那个人离阳台有多远 在地面上作为初始速度
v0
和 角度theta
。然后,您可以选择条件(v0,theta)
使distance_from_balcony_on_the_ground(v0,theta) = xstar
从这个数据表。在让我们写下 时间}。
我想你把}。
^{pr2}$t
的人分别是x(t)
和{x=0
放在大楼的墙上,y=0
作为地面,我也在这里。比如说 人在时间t
时的水平和垂直速度 分别是v_x(t)
和{t=0
处的初始条件如下你要解的牛顿方程是
其中
m
是人的质量,g
是一个常量,我不知道它的英文名, 但我们都知道那是什么。在根据公式(3)
与公式(1)一起使用
我们也使用了初始条件。}的积分。在
\int_0^t
表示 从0
到{根据式(4)
我们用了初始条件。 将其与公式(3)一起使用,并使用初始条件
其中
t^2
表示t
的平方。 从y(t)
的表达式中,我们可以得到时间tstar
当人撞到地上时。也就是说,y(tstar) =0
。 这个方程可以用二次公式求解 (或类似的名字)如我使用了一个条件
tstar>0
。现在我们知道了 他撞到阳台的距离 地面为x(tstar)
。使用上面的x(t)
表达式实际上},以及{}和{}。
您将
x(tstar)
依赖于v0
和{g
和ystar
作为常量,您想要找到 所有(v0,theta)
使得给定xstar
值的x(tstar) = xstar
。在由于公式(5)的右侧可以便宜地计算, 您可以为
v0
和theta
设置网格并计算xstar
在这个二维网格上。那么,你可以看看解集大致在哪里 的谎言。如果你需要精确的解决方案,你可以 包围此数据表中的解决方案的段。在下面是一个python脚本来演示这个想法。在
我还附上了一个由这个脚本生成的图形。 黄色曲线是解集}时。
蓝色坐标表示
(v0,theta)
,因此 一个人从墙上掉到地上 当xstar = 8.0*1.95
和{x(tstar)
,即 有人从阳台上水平跳起。 注意,在给定的v0
(高于阈值aroundv0=9.9
)时, 有两个theta
值(对于人来说有两个方向 达到目的点(x,y) = (xstar,0)
。theta
值的较小分支可以为负值,这意味着只要初始速度足够高,人就可以向下跳到目标点。在该脚本还生成一个数据文件
output.dat
,该文件具有 封闭段的解决方案。在假设x方向上的速度永远不会降到零,你可以取x作为独立参数,而不是时间。然后,状态向量是时间、位置、速度,并且这个状态空间中的向量场被缩放,使得vx分量始终为1。然后从0到xstar进行积分,以计算轨迹与xstar相遇的状态(近似值)作为x值。在
或者用你自己的积分方法。我使用odeint作为文档化接口来展示这个导数函数在集成中是如何使用的。在
产生的时间和y值可能是极端的
所以经过一番尝试,我找到了一个方法来实现我想要的。。。这是我在开始的帖子中提到的暴力方法,但至少现在它起作用了。。。在
其思想非常简单:定义一个函数
find_v0
,它为给定的theta
av0
查找。在这个函数中,您为v0
取一个起始值(我选择了8,但这只是我的猜测),然后取起始值并用difference
函数检查感兴趣的点离(xstar,0)
有多远。在这种情况下,可以通过将x轴上大于xstar
的所有点设置为零(以及它们对应的y值),然后用trim_zeros
修剪所有零,现在的最后一个元素对应于所需的输出。如果这个函数的输出值小于cd1,那么再增加一次。在代码如下(再次替换3和4):
这个东西的问题是,它需要永远计算(当前设置大约5-6分钟)。如果有人对如何改进代码以更快一点或者有不同的方法有一些建议,我们还是会很感激的。在
相关问题 更多 >
编程相关推荐