(24)滑板少年达朗贝尔
本集我们再请一位数学家登场,做程序里的模特。这位踏着滑板出来的,就是生于 1717 年的法国大数学家、物理学家、天文学家,让·勒朗·达朗贝尔(Jean le Rond d’Alembert)。
请数学家有个好处,那就是他们老人家的肖像大多已经在公共版权领域中了,大概没有侵权可言。相比起来,僵尸就要危险多了,如果哪天 Popcap 较起真来,本站还要把它们统统撤换下去。
本集的代码很短,但却模仿了一种物理中的运动——简谐振动。回忆在《投篮球》那集,我们也用不长的代码模拟了抛物线运动。这集可以看作是姐妹篇,我们定义了另一种运动的微分方程,构造出了“简谐振动”这种运动模式。
高年级同学可以注意,本集没有使用任何三角函数,却也画出了正弦曲线,背后的数学原理,要到大学才能明白。对于幼儿园的小朋友们,你们可以按上、下键,推达朗贝尔滑得更高,甚至翻出筋斗来。
代码量:18 块积木
素材:
帅气的达朗贝尔 dAlembert.png
舞台背景:Scratch 内置的 Slopes
添加扩展:画笔
代码搭建:
dAlembert:
讲解:
严格来说,我们的角色是在竖直方向上做简谐振动,在 x 方向上是在匀速向右移动。
如果要只显示简谐振动的效果,不显示水平的漂移,可以把“将x坐标增加( )” 里的数字改为 0。
程序里让达朗贝尔在竖直方向简谐振动的同时水平漂移,是为了让他画出正弦曲线(波浪线)。
这集我们还是用了跟以前一样的老把戏,用角色的方向作为记录它垂直速度的变量。只不过稍微有点复杂的是,这次我们对方向进行了一个除 -10 的运算,以 (方向 / (-10))作为角色的垂直速度。
如果你对程序背后的物理和数学感兴趣,不妨琢磨一下“重复执行”循环体内,每次代码的逻辑:
在每次执行中,会进行以下 3 个操作:
将 x 坐标增加 1 ;
将 y 坐标增加1个“垂直速度”
—— “将 y坐标增加 (方向 / (-10))”
将“垂直速度”减少一些,具体的减少数量和 y 坐标有关
—— “右转( y坐标 / 20 )度”。
还有一个隐含的变化,那就是每一次循环也会消耗一个很短的时间 dt = 1 / FPS。FPS 是动画最终的帧率,一般为 30~60帧/秒。
换句话说,1 / dt = FPS,它就是一秒内动画的帧数。
我们如果用 dx、dy 表示每次执行中,x、y坐标的增加量,那么有:
dx / dt = 1 * FPS
dy / dt = (方向 / (-10)) * FPS
用 d(方向) 表示每次执行中,方向的增加量,有:
d(方向) / dt = y / 20 * FPS
由 dy / dt = (方向 / (-10)) * FPS,可以知道:
方向 = -10 * dy / dt / FPS
因此 d(方向) 也可以写成
d(方向) =
d(-10 * dy / dt / FPS) = -10 * d(dy / dt) / FPS
又由 d(方向) / dt = y / 20 * FPS,可以知道
-10 * d(dy / dt) / dt / FPS = y / 20 * FPS
即:
d(dy / dt) / dt + y * FPS² / 200 = 0
我们在数学上,把 dy / dt 称为 y 对 t 的导数,d(dy / dt) / dt 称为 y 对 t 的二阶导数,也记为 d²y / dt²,因此上面的方程也记为:
d²y / dt² + y * FPS² / 200 = 0
这是一个二阶齐次常微分方程,它描述的运动就是简谐振动。
如果我们代入 dx / dt = FPS,还可以化为对 x 的微分方程:
d²y / dx² + y / 200 = 0
该方程描述的就是达朗贝尔的运动轨迹。也就是我们画笔画出来的波浪线 —— 正弦(余弦)曲线,它有固定的波长(从一个最高点,到下一个最高点之间的距离),为 2π * sqrt(200) ≈ 89。这个波长的数值和振动的振幅及动画的帧率都无关。
在我们的程序中,达朗贝尔的 x坐标从 -205 增加到 240,移动了 445 个单位,正好是波长 89 的 5 倍。因此,达朗贝尔总是画出 5 个完整的“波形”。
无论初始时滑得猛烈,还是滑得柔和,只要你不按上、下键人为干预,他总是滑出 5 个完整波浪,这就是数学的神奇,小朋友们可以试试吧。