单摆交互课件

这个互动程序要实现的是沪科技版第二章 第三节 单摆中的图 2–19,如下图所示。

图 2–19  摆球的受力分析图

做出的成品如下所示:

物理知识

记得我 1997 年刚参加工作,年底到市三女中听课,第一次见识了在课堂上用 PPT 展示内容,第 2 年的高一下开了一节新教师汇报课,上的就是《单摆》,用上了投影和 PPT,现在看来很平常,但在那时却是本校首开先河的。但更大的亮点在于一个用 Visual Basic 编写的单摆互动程序,是我下一届的一位师弟编写的,那时市里正在推广多媒体教学,这个课件还在市里获了奖。没想到在近 30 年后,才在 AI 的帮助下自己完成了对单摆的计算机模拟。

在弹簧振子互动课件中提到,本来准备使用动力学模式进行模拟的,即:先由牛顿第二定律从 F 算得 a,然后用半隐式欧拉法进行数值积分求得速度 v = v0 + aΔt,最后再进行一次数值积分求得位移 x = x0 + vΔt,而位移的数值就可以对应平面上的坐标。

从物理学的角度,上述过程其实就是解一个微分方程。由牛顿第二定律:

\[{F_合} =  - kx = ma = m\frac{{{{\rm{d}}^2}x}}{{{\rm{d}}{t^2}}}\]

令固有角频率 ω = \(\sqrt {\dfrac{k}{m}} \),则上式可以写成:

\[\frac{{{{\rm{d}}^2}x}}{{{\rm{d}}{t^2}}} + {\omega ^2}x = 0\]

这个二阶线性常系数齐次微分方程的通解为

\[x = A\cos (\omega t + \varphi )\]

其中振幅 A 和初相位 φ 都是由初始条件决定的。这就是简谐振动的运动学方程。

在弹簧振子互动课件中,由于没有模拟阻尼振动等复杂情况,因此直接使用了上面的运动学方程,程序获取时间 t 直接算出 x,根据 x 在屏幕上设置振子小球的位置。

单摆也可以做同样的处理,但单摆实际的运动轨迹是曲线,因此需要沿切线方向列牛顿第二定律,而且使用广义坐标——摆角 θ,而不是常用的直角坐标系的 x。

长为 l 的轻绳一端固定,另一端系质量为 m 的小球,摆角为 θ。重力沿切线方向的分力作为回复力,根据牛顿第二定律有:

\[ - mg\sin \theta  = ml\frac{{{{\rm{d}}^2}\theta }}{{{\rm{d}}{t^2}}}\]

令固有角频率 ω = \(\sqrt {\dfrac{l}{g}} \),则上式可以写成:

\[\frac{{{{\rm{d}}^2}x}}{{{\rm{d}}{t^2}}} + {\omega ^2}\sin \theta  = 0\]

上式是非线性方程。当摆角 θ 很小时,sinθ ≈ θ,上式可写成二阶线性常系数齐次微分方程:

\[\frac{{{{\rm{d}}^2}x}}{{{\rm{d}}{t^2}}} + {\omega ^2}\theta  = 0\]

此方程的通解为:

\[\theta  = {\theta _0}\cos (\omega t + \varphi )\]

周期 T = \(\dfrac{{2\pi }}{\omega }\) = 2π\(\sqrt {\dfrac{l}{g}} \),与振幅无关。这个通解长得和弹簧振子的运动方程很像,只不过用角位移 θ 替代了 x。

补充:那么非线性方程如何解?需要涉及第一类椭圆积分(这个我不懂),严格单摆的周期可以写成级数:

\[T = 2\pi \sqrt {\frac{l}{g}} \left[ {1 + {{\left( {\frac{1}{2}} \right)}^2}{{\sin }^2}\frac{{{\theta _0}}}{2} + {{\left( {\frac{{1 \cdot 3}}{{2 \cdot 4}}} \right)}^2}{{\sin }^4}\frac{{{\theta _0}}}{2} +  \cdots } \right]\]

从上式可以看出:大角度时单摆周期是与振幅有关的,振幅越大,周期越大。

核心代码解读

因为要实现阻尼振动,所以这个程序并没有使用运动学公式 θ = θ0cos(ωt + φ),而是使用动力学方法实现。

计算机的数值模拟可以无视复杂的解析解,只需由牛顿第二定律从 F 算得 a,然后用半隐式欧拉法进行数值积分求得速度 v = v0 + aΔt,再求得位移 x = x0 + vΔt。

在单摆的例子中有一点不同,先求的是角加速度 β,若是小角近似则 β = \(\dfrac{g}{l}\)θ,若精确解则 β = \(\dfrac{g}{l}\)sinθ,然后求角速度 ω = ω0 + βΔt,最后求角位移 θ = θ0 + ωΔt。对应的代码在 update 方法中:

// 半隐式欧拉积分:先更新角速度,再用新角速度更新角度(辛积分,振幅长期稳定)
// —— 摆1积分 ——
const angAcc1 = this.calculateAcceleration(this.angle, this.angularVelocity, this.length);
this.angularVelocity += angAcc1 * dt;
this.angle += this.angularVelocity * dt;

其中还调用了 calculateAcceleration 方法,代码如下:

// 计算单摆加速度(length 为 cm,需转 m)
calculateAcceleration(angle, angularVelocity, length) {
    const L_m = length / 100;
    const gOverL = this.gravity / L_m;
    // 小角近似:α = -(g/L)·θ(把 sinθ ≈ θ 严格化),周期与摆角无关
    // 精确模型:α = -(g/L)·sinθ(真实单摆方程),大摆角周期增大
    const restoringAngle = this.mode === 'smallAngle' ? angle : Math.sin(angle);
    const gravityTerm = -gOverL * restoringAngle;
    const dampingTerm = -this.damping * angularVelocity;
    return gravityTerm + dampingTerm;
}

上述代码中还包含了阻尼项,可以模拟有空气阻力情况下单摆的振动。

最后还需要根据 θ 值、悬点位置和绳长计算出摆球在屏幕上的直角坐标。

// 获取摆球位置(which=1 默认摆1,which=2 摆2)
getBobPosition(which = 1) {
    const centerX = this.width / 2;
    const centerY = 0; // 悬点
    const len = which === 2 ? this.length2 : this.length;
    const ang = which === 2 ? this.angle2 : this.angle;
    const visualLen = len * this.pxPerCm; // cm → px
    const x = centerX + visualLen * Math.sin(ang);
    const y = centerY + visualLen * Math.cos(ang);
    return { x, y };
}

使用的一点说明

PhET 的单摆模拟程序做得比较精致,但针对教材的内容用起来不顺手。

我在使用本课件时,首先会进入 2 个单摆的界面,设置不同的摆球质量和振幅,但保持摆长相同,展示单摆的周期与摆球质量和振幅无关,引入伽利略的等时性原理,这个原理在初中课本八上的一开始的“有用的物理学”中有介绍,不过下一届学生改用新教材,这个内容已经删去了。注意选择“小角近似”,如果你选择“精确模拟”,那么摆了几次之后两者就开始明显不同步了,“PhET的单摆模拟程序”就会出现这种情况,此时可以向学生解释:如果摆角过大不能看成简谐振动,则振幅越大周期越大。

然后,进入一个单摆的界面,向学生展示重力、拉力、重力的分力、合外力的变化情况,这也是本节课的难点:F回 = mgsinθ ≠ F合,平衡位置并不平衡。

最后是本节课的重点,通过改变摆长和重力加速度,观察摆动周期的变化,直观地理解单摆周期公式。

接下来的一节课是使用单摆测量重力加速度,需要切换到秒表界面,虽然上海高考自 1999 起就不再考查秒表的读数,但课本中的学生实验用的还是秒表,这个技能不敢完全不讲。

然后有两个选择:用真单摆、屏幕上的秒表演示测量周期的操作,或者用屏幕上的单摆、手中的真秒表演示同样的操作。重点让学生关注:(1)最低点开始计时;(2)开始计时时数 0;(3)每次同方向经过最低点计数 1 次。

完整代码

 

发布时间:2026/10/14 21:16:58  阅读次数:33