平抛运动交互课件

平抛运动可能是物理交互性课件中必做的一个内容,近 20 年前用 flash 做过一个,那时还是看《电脑报》上的教程学会的,不过现在连源码都找不到了。

这次要实现的是沪科版必修二第五章 第二节 平抛运动中的图 5–16,如下图所示。

图 5–16  平抛运动的分解

做出的成品如下所示:

用 svg 绘制函数曲线的基本思路

数学函数是无限连续的,而计算机屏幕是由有限个像素点组成的离散世界。连续函数就像真实世界中的公路——它是连续、光滑、无限精细的,SVG 路径就像 GPS 为你规划的导航路线——它是由有限个关键点(航路点)连接而成的折线。

例如要绘制 y = sin(x) 的函数图像的具体操作步骤如下:

1.确定采样范围:比如在 x = [− π,π] 之间绘制。

2.决定采用点数量,比方说 1000。采样点太少曲线会出现锯齿,不够光滑;采样点太多计算量大,文件体积大;经验法则是相邻两点在屏幕上距离不超过 1 ~ 2 像素为宜。

3.计算每个点的坐标:

4.有了一系列离散点,需要像珍珠那样用“线”把它们穿起来。在 SVG 中,这是通过 <path> 元素的“d”属性实现的。

假设我们有 3 个点:P1(100,200)2,P2(300,150),P3(500,250),步骤如下:

(1)移动到起点:M 100 200。M 是“Move to”的缩写,相当于把笔尖放到纸上起点处。

(2)画直线到第二点:L 300 150。L 是“Line to”的缩写,从当前位置画直线到这个点。

(3)画直线到第三点:L 500 250。继续用直线连接。

完整路径字符串:“M 100 200 L 300 150 L 500 250

绘制抛物线轨迹的代码如下:

// 绘制轨迹
function drawTrajectory() {
    // 确保必要的物理参数有效
    const validScale = state.scale > 0 ? state.scale : 10;

    const originX = CONSTANTS.ORIGIN_X;
    const originY = CONSTANTS.ORIGIN_Y;
    const scale = validScale;
    const steps = CONSTANTS.TRAJECTORY_STEPS;  // 轨迹点数量,设置为55
    const dt = CONSTANTS.MAX_TIME / steps;      // CONSTANTS.MAX_TIMEs设置为 3 秒

    let path = `M ${originX} ${originY}`;

    for (let i = 1; i <= steps; i++) {
        const t = i * dt;
        const pos = calculatePosition(t);
        const x = originX + pos.x * scale;
        const y = originY + pos.y * scale;

        // 如果y坐标超过最大允许像素值,停止绘制
        if (y > CONSTANTS.Y_MAX_PIXEL) {
            break;
        }
        path += ` L ${x} ${y}`;
    }

    elements.trajectoryPath.setAttribute('d', path);
}

// 计算平抛运动的位置
function calculatePosition(t) {
    // 确保时间值有效
    const validT = isFinite(t) && t >= 0 ? t : 0;
    // 确保物理参数有效
    const validV0 = state.v0 >= 1 ? state.v0 : 1;
    const validG = state.g > 0 ? state.g : 10;

    const x = validV0 * validT;
    const y = 0.5 * validG * validT * validT;

    // 确保返回的坐标值有效
    return {
        x: isFinite(x) ? x : 0,
        y: isFinite(y) ? y : 0
    };
}

在 600 像素见方的范围内只取了 55 个采样点,但画出的图线已经足够光滑了。calculatePosition(t) 方法 AI 写得有点啰嗦,但它说:从用户界面角度:这些检查不是必需的,因为输入已经被严格限制;从代码健壮性角度 :保留这些检查是有益的,可以增强代码的可靠性;从实际使用角度:这些检查不会造成明显的性能问题。

简化的代码可写成:

// 计算平抛运动的位置
function calculatePosition(t) {
    const x = state.v0 * t;
    const y = 0.5 * state.g * t * t;

    return {
        x,
        y
    };
}

数学公式在页面上的显示

在页面上出现了带有分数、根号的数学公式,但为寥寥几个公式而引入 MathJaxKatex 库没有必要,方法是将公式转换为 svg 图形,然后将它们插入页面的对应位置。我采用的是在线转换工具:Codecogs Equation Editor

完整代码


发布时间:2026/1/5 上午10:38:22  阅读次数:246

2006 - 2026,推荐分辨率 1024*768 以上,推荐浏览器 Chrome、Edge 等现代浏览器,截止 2021 年 12 月 5 日的访问次数:1872 万 9823 站长邮箱

沪 ICP 备 18037240 号-1

沪公网安备 31011002002865 号