Scratch实现
素材准备
本案例会用到的3个素材,分别是:预瞄线,炮弹,轨迹
素材很简单,这里就不放绘制视频了,大家自己手画一下吧。
(懒得画虚线的话,直接用实线也行)
程序实现
再回过头来看看我们的问题:
已知发射炮弹的角度和力度,计算炮弹的飞行轨迹。
发射程序
为了方便,我们:
用 [面向 鼠标指针] 来控制发射炮弹的角度; 用 (到鼠标的距离) 来控制发射的力度; 用 <按下鼠标> 来控制发射炮弹。
很快,我们就能搭出一个发射炮弹的程序:
运行一下:
注:我认为16:9的舞台更适合抛物线演示。 如果你用的是原版的4:3,则需要调整一下发射起点的坐标,确保它在舞台内)
预瞄线已经会跟随鼠标方向了,但现在克隆出来的炮弹还不会动。 下面我们要为炮弹编写程序,让它画出抛物线。
计算初速度
问题来了:炮弹的速度是多少?等同于力度吗? 遗憾的是:力度≠速度
推导它们之间的关系需要一些物理知识——
假设炮管长度为L炮弹在炮管内时,会受到固定的火药燃气推力F;离开炮管后,就不再受到推力
发射期间,火药燃气对炮弹做的功W为:
W = FL
炮弹出膛时动能为Ek,根据能量守恒(不计阻力):
Ek = W
炮弹质量为m,出膛时的速度为v,那么有:
Ek = 1/2 * mv²
联立以上3式,可知:
FL = 1/2 * mv² v = sqrt(2FL/m)
其中炮管长度和炮弹质量都是固定的,只是一个常数。
因此炮弹出膛速度和燃气推力的关系可表示为:
v = sqrt(2L/m) * sqrt(F) v = k * sqrt(F)
过程看不懂没关系,只看结论就行:
炮弹速度的大小 = k * sqrt(发射力度)。
至于k是多少,这个我们可以自由调整,只要控制起来舒服就行。我觉得1.5不错。
根据我们前面的分析,我们需要把炮弹的速度拆成x和y两个方向,这样对模拟来说会比较方便。
新建两个私有变量:speed x和speed y,分别表示x、y方向的速度
已知炮弹速度的大小和方向,计算炮弹x、y方向的分速度。
这个我们可太熟悉了。直接使用向量正交分解公式——
然后我们希望炮弹根据speed x,speed y移动,直到飞出屏幕:
再运行一下试试——
现在炮弹已经会沿射击方向移动了。而且鼠标离发射点越近,炮弹速度越快。
但是现在还没有添加重力,炮弹是沿直线移动的,不会下坠。
模拟重力
在现有的程序框架下,添加重力只需要一块积木:
把速度改为坐标表示后就可以直接加减了,真是方便。
再看看效果:
炮弹会随重力下坠了,运动的轨迹就是我们想要的抛物线!
面向速度
然而目前还存在一些问题:炮弹一直保持着发射时的方向,没有旋转。
我们希望炮弹面向它移动的方向——也就是速度的方向。
炮弹速度的方向一直在改变,我们需要根据speed x和speed y实时计算炮弹方向。
是不是有点眼熟?这不就是计算坐标方向的方法吗!
速度是向量,而向量可以用坐标表示。既然是坐标,为什么不能用坐标的方法呢?
在讲勾股定理和三角函数时,我们就已经推导出了distance R(x, y)和direction R(x, y)这两个方法,但我当时没有说过它们能用在什么地方。后面学了相对坐标和向量,我们发现它们不仅能用在坐标上,还可以用在任何向量上。
这也是为什么这篇教程要花这么多篇幅讲解相对坐标和向量这种“看起来是废话”的东西。
注:如果你在使用没有返回值函数(return)的原版Scratch,这里需要这样写:
运行一下吧——
炮弹的方向也正确了。
添加轨迹
最后,我们还需要让炮弹留下轨迹。
这部分跟数学没什么关系,我就一笔带过了——
(因为只是个小项目,我就直接用造型名区分克隆体了。大型项目请不要学我这么做!)
最后来看看效果——
附上完整的代码。
如果你没有得到以上效果,可以对照检查一下是哪里错了。
注:所有的变量都是私有变量
<iframe
width="100%"
height="800px"
scrolling="no"
src="https://www.ccw.site/embed?id=simple-math/simple/lec0702&type=comment"
title="{小Simple也能看懂的Scratch常用数学知识 0702}"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
scrolling="0"
></iframe>