今亮点!用ggb模拟物体运动的四种基础方法(以竖直弹簧为例)
2023-01-28 18:51:08 哔哩哔哩

用ggb模拟物体运动的四种基础方法(以竖直弹簧为例)

准备工作

首先,输入初始参数,画一个弹簧

初始参数:重物质量m=5, g=9.8, 弹簧原长l_0=10, 劲度系数k=10.


(资料图片)

弹簧位置:创建原点O=(0,0),重物所在位置P=(x(O),y(O)-l_0).

画弹簧:两段线段segment(O,O-(0,1))以及segment(P,P+(0,1)). 弹簧本体用参数方程来画较为方便(n为该段距离内有多少个完整的周期),

从F-x关系出发的微元法(已知受力与物体位置的关系)

时间微元与时间:dt=0.01,t1=1,t=slider(0,40)

力矢量:F=vector((0,-m g)+(0,-k (y(P)+l_0)))

加速度矢量:a=F/m

速度矢量微元:dv=a*dt

速度矢量:v=(0,0)

位移矢量微元:dP=v*dt

初速度:v_0=0  //可随意调节

重新定义重物位置:P=(0,-10)

按钮1 重置:启动动画(t1,false);  赋值(t,0);  赋值(P,(x(O),y(O)-l_0));  赋值(v,(0,v_0))  //此处P的初始位置也可随意调节,每次开始前要按一下重置按钮。

按钮2 开始:启动动画(t1,true)

按钮3 暂停: 启动动画(t1,false)

t1脚本 更新时:赋值(t,t+dt);  赋值(P,P+dP);  赋值(v,v+dv).

从原长无处速度释放的振幅:A=mg/k

速度箭头:vector(P,P+v),设置标题为“v”

y-t图:(t,y(P)+l_0+A),显示轨迹

数值解微分方程法(已知受力与物体位置的关系)

受力分析可知:F=-mg-k(y+l_0)

因此有微分方程组:  

创建初始值:

v_0=0;  x_0=-10;  //初始值可随意调整

模拟运动的结束时间:t_f=50  //可随意调整

计算轨迹:nsolveode({x’,v’},0,{x_0,v_0},t_f)  //可得两个轨迹,第一个为x-t,第二个为v-t。

len=length(numericalIntegral1)  //测量该轨迹的点的个数

c=slider(0,1,1/len)  // 创建一个滑动条以便于在轨迹上描点

A=point(numericalIntegral1,c)  //其横纵坐标为对应的时间与位移,即x-t图

B=point(numericalIntegral2,c)  //其横纵坐标为对应的时间与速度,即v-t图

t=x(A)  //时间

P=(x(O),y(A))  //重新定义重物坐标

直接模拟(已知位移与时间的关系)

创建时间:t=slider(0,50)   //进入设置页面将滑动条的速度设置为1/5

创建:偏离平衡位置的位移d=0

从原长释放时的振幅:A_0=mg/k

原长处:y=-l_0

平衡位置:y=-l_0-A_0

实际的振幅:A=d

规定重物所到达的最低位置为零势能面,则物体高度:h=y(P)+l_0+d+A_0

//(物体能到达的最低位置:y=-l_0-A_0-d,最高位置:y=-l_0-A_0+d)

重新定义重物位置:P=(x(O),)  //可随意更改初相位

对上述关系式求导可得速度与时间的关系:

速度箭头:vector(P,P+(0,v)),设置标题为“v”

y-t图:(t,y(P)+l_0+A_0),显示轨迹

按钮1 重置:启动动画(t,false);  赋值(t,0);

按钮2 开始:启动动画(t,true)

按钮3 暂停: 启动动画(t,false)

从v-x关系出发的微元法(已知速度与物体位置的关系)

创建:偏离平衡位置的位移d=0

时间微元与时间:dt=0.01,t1=1,t=slider(0,40)

从原长释放时的振幅:A_0=mg/k

原长处:y=-l_0

平衡位置:y=-l_0-A_0

实际的振幅:A=d

规定重物所到达的最低位置为零势能面,则物体高度:h=y(P)+l_0+d+A_0

//(物体能到达的最低位置:y=-l_0-A_0-d,最高位置:y=-l_0-A_0+d)

//找到v-x关系:

速度:

重新定义重物位置:P=(0,-10)

按钮1 重置:启动动画(t1,false);  赋值(t,0);  赋值(P, (x(O),y(O)-l_0-A_0+d));

按钮2 开始:启动动画(t1,true)

按钮3 暂停: 启动动画(t1,false)

以下操作包含了速度方向的判断:

创建空列表:l1={}

t1脚本 更新时:

赋值(l1,insert(y(P),l1,1))  //获取最新的y坐标

if(t==0,赋值(P,P-(0,dt)))  //给一个微扰,让模型启动

赋值(t,t+dt)

if(length(l1)≥3,赋值(l1,take(l1,1,3)))    //减小内存,避免卡顿

if(l1(1)-l1(2)≤0&&y(P)+v_2*dt≥(-l_0-A_0-d) ∨y(P)+v_1*dt>-l_0-A_0+d ,赋值(P,P+v_2*dt))   //这一步是速度小于零,即速度向下的情况,避免了在临界点因模拟精度问题而导致的bug

if(l1(1)-l1(2)≥0&&y(P)+v_1*dt≤(-l_0-A_0+d) ∨y(P)+v_2*dt<-l_0-A_0-d ,赋值(P,P+v_1*dt))  //这一步是速度大于零,即速度向上的情况

速度矢量:v=vector((0,if(l1(1)-l1(2) ≤0,v_2,v_1)))

速度箭头:vector(P,P+v),设置标题为“v”

y-t图:(t,y(P)+l_0+A_0),显示轨迹

另:只知物体运动轨迹且物体速度大小不变时。

以匀速圆周运动为例:

半径:r=5

圆心:A=(0,0)

圆周:c=circle(A,r)

速度大小:v=2

滑动条:a=slider(0,1)  //进入设置,设置滑动条速度为v或者v/2等,以及重复方式为递增,非递增(一次)。

描点:B=point(c,a)

启动滑动条a的动画即可。

若要表示出速度矢量,则:

作切线:tangent(B,c)

在正确的方向上任取一点C,然后取向量BC:u=vector(B,C)

速度箭头:vector(B,B+v*u/|u|),然后取标题为v

相关新闻: