
教程文档示例工程【免费下载链接】website-archiveArchive of the Coding Train website (first version)项目地址https://gitcode.com/gh_mirrors/we/website-archive点击查看免费下载导读本指南以 Coding Train 开源仓库中《The Nature of Code》第 2 章「力Forces」系列的摩擦力专题文档为核心讲解如何把物理中的滑动摩擦力kinetic friction公式翻译成可运行的 p5.js 模拟代码。你将掌握摩擦力如何作为一类普通力并入已有的applyForce()力驱动框架、如何用向量运算表达摩擦力的方向与大小、以及摩擦系数mu和质量mass对模拟效果的实际影响。读完本文你可以直接复制仓库中的 Mover 实现把它扩展进自己的重力、风力和碰撞模拟中。摩擦力专题在课程体系中的位置本文对应的是仓库中两份同主题文档2015 年的原始版 _more/archive/nature-of-code/2-Forces/2.4-Friction-Force.md即关联文档与 2020 年重制版 _learning/nature-of-code/2.3-friction.md。两份文档主题一致——模拟摩擦力重制版视频编号为 2.3属于「Nature of Code」系列见 _learning/nature-of-code/index.md。在课程脉络上它是「力」章节的承前启后之作前置2.1 用applyForce()引入「力」概念2.1-simulating-forces.md2.2 为 Mover 添加质量属性、实现F ma2.2-mass-acceleration.md本篇把真实物理公式——摩擦力——作为第三种力接入同一套框架后续2.4 继续把「阻力/空气阻力Drag」同样实现为公式力2.4-drag.md。也就是说摩擦力是「真实物理公式 → 模拟代码」这条教学主线上的第一个完整案例前面章节用的是随手设定的虚构力数值made-up values见原始版 2.2-Applying-a-Force.md而从本篇开始力的大小由物理公式计算得出。摩擦力的物理公式在代码中如何表达要理解模拟代码先看物理模型。滑动摩擦力kinetic friction的大小由下式给出F_friction -μ × N × v̂其中μmu摩擦系数无量纲反映接触面粗糙程度N法向力normal force即物体对接触面的正压力大小v̂速度方向的单位向量负号表示摩擦力方向始终与运动方向相反。代码实现的关键是把公式拆成「方向」和「大小」两步方向取当前速度向量的单位向量取反——this.vel.copy().normalize().mult(-1)大小摩擦系数mu乘以法向力normal本模拟中直接用质量this.mass近似。在物体与地面接触的简化场景水平地面、无垂直方向运动中法向力约等于物体重量即N ≈ mg在本例代码中取normal this.mass相当于按单位重力简化处理。当物体弹起、与地面短暂分离时diff 1的接触判定会失效摩擦力自然不生效这与物理直觉一致。完整源码解析Mover 类的摩擦力实现仓库中该专题的完整可运行源码位于 learning/nature-of-code/2.3_friction/P5包含三个文件index.html页面骨架、mover.jsMover 类、sketch.js主程序。对应 p5.js Web Editor 草稿为zcTpMCpA见 2.3-friction.md 的 front matter。主程序 sketch.js力的组装let movers []; let mu 0.1; function setup() { createCanvas(400, 400); for (let i 0; i 10; i) { movers[i] new Mover(random(width), 200, random(1, 8)); } } function draw() { background(0); for (let mover of movers) { if (mouseIsPressed) { let wind createVector(0.1, 0); mover.applyForce(wind); } let gravity createVector(0, 0.2); let weight p5.Vector.mult(gravity, mover.mass); mover.applyForce(weight); mover.friction(); mover.update(); mover.edges(); mover.show(); } }关键点全局摩擦系数mu 0.1一个偏小的值让物体缓慢减速而不是骤然停止便于观察重力weightgravity向量(0, 0.2)乘以质量得到重量再交给applyForce()——这是 2.2 章引入的质量处理方式风力按住鼠标时施加水平力(0.1, 0)模拟横向气流每帧调用顺序先施加外力再调用mover.friction()计算并施加摩擦力最后更新位置、处理边界、绘制。Mover 类摩擦力是「读速度、写加速度」的力mover.js 中的核心是friction()方法class Mover { constructor(x, y, m) { this.pos createVector(x, y); this.vel createVector(0, 0); this.acc createVector(0, 0); this.mass m; this.r sqrt(this.mass) * 10; } friction() { let diff height - (this.pos.y this.r); if (diff 1) { // shorcut to friction! // this.vel.mult(0.95); // Direction of Friction let friction this.vel.copy(); friction.normalize(); friction.mult(-1); // chained version // let friction this.vel.copy().normalize().mult(-1); // Magnitude of Friction let normal this.mass; friction.setMag(mu * normal); this.applyForce(friction); } } applyForce(force) { let f p5.Vector.div(force, this.mass); this.acc.add(f); } edges() { if (this.pos.y height - this.r) { this.pos.y height - this.r; this.vel.y * -1; } if (this.pos.x width - this.r) { this.pos.x width - this.r; this.vel.x * -1; } else if (this.pos.x this.r) { this.pos.x this.r; this.vel.x * -1; } } update() { this.vel.add(this.acc); this.pos.add(this.vel); this.acc.set(0, 0); } show() { stroke(255); strokeWeight(2); fill(255, 100); ellipse(this.pos.x, this.pos.y, this.r * 2); } }逐步拆解friction()的实现逻辑接触判定diff height - (this.pos.y this.r)计算物体底边到画布底部的间隙diff 1表示物体贴着地面含轻微穿透方向this.vel.copy().normalize().mult(-1)取速度的单位向量并反向——摩擦力永远与运动方向相反。注释中还给出了链式写法let friction this.vel.copy().normalize().mult(-1);以及一个偷懒的简化替代this.vel.mult(0.95)直接每帧把速度打 95 折能模拟减速效果但没有物理依据大小friction.setMag(mu * normal)其中normal this.mass——把法向力近似为质量施加把构造好的摩擦力向量交给applyForce()与重力、风力走同一条F ma通道。质量如何影响摩擦力效果注意normal this.mass使摩擦力大小与质量成正比而applyForce()中F ma又要除以质量因此摩擦力导致的加速度与质量无关a F/m μN/m μ·m/m μ。实际效果是大质量物体与地面接触时表现与小质量物体一致的减速体验——这正是伽利略「落体与质量无关」思想在水平摩擦场景的再现。你可以通过修改setup()中random(1, 8)的质量范围或全局mu值直观验证这一特性。页面加载与运行方式仓库源码通过 index.html 组织依赖!DOCTYPE html html head script srchttps://cdn.jsdelivr.net/npm/p51.4.1/lib/p5.min.js/script meta charsetutf-8 / /head body script srcmover.js/script script srcsketch.js/script /body /html运行要点p5.js 版本从 CDN 引入p51.4.1若本地调试请保持版本一致加载顺序mover.js类定义必须先于sketch.js主程序加载否则new Mover()会报Mover is not defined本地运行直接用浏览器打开index.html即可p5.js 绘制无需本地服务器按住鼠标施加风力松开后观察摩擦力让物体在弹跳中逐渐减速、最终静止于地面。交互验证与扩展练习从源码结构可以推断该模拟的「可调旋钮」集中在三个位置可用于教学实验参数/代码位置默认值调整效果全局musketch.js0.1摩擦系数越大物体减速越快超过约0.5时物体会被「粘」在地面上难以横向移动gravity向量sketch.js(0, 0.2)增大则落得更快、反弹更强间接改变接触瞬间的速度与摩擦生效时长random(1, 8)质量范围sketch.js18控制物体大小半径r sqrt(mass) * 10与重力大小值得尝试的扩展方向把normal this.mass改为normal this.mass * 0.5观察「减半法向力」后物体滑得更远的差异参考本章 2.2 的F ma框架把摩擦力的setMag计算推广为更通用的「速度相关阻尼力」对照后续的阻力篇2.4-drag.md体会「摩擦力与速度无关、阻力与速度有关」两种公式在实现上的差异——摩擦力大小恒定由μN决定而阻力大小随速度平方变化。小结摩擦力模拟是《The Nature of Code》中「真实公式驱动模拟」的典范案例它的代码量极小却完整覆盖了向量方向运算、单位向量、标量缩放、F ma力叠加等核心技能。通过本仓库源码你可以清楚地看到一条可复用的编码路径——任何公式力都可以拆成「方向向量 大小标量」然后用setMag()组装并交给applyForce()。这条路径将贯穿整本书的引力、阻力、弹力等所有力的模拟。赞分享教程文档示例工程【免费下载链接】website-archiveArchive of the Coding Train website (first version)项目地址https://gitcode.com/gh_mirrors/we/website-archive点击查看免费下载相关推荐Nature of Code 5.18用 p5.js 与 matter.js 搭建 2D 物理世界Coding Train 仓库实战Nature of Code 5.18用 p5.js 与 matter.js 搭建 2D 物理世界Coding Train 仓库实战 本篇文章以 Codi教程文档示例工程The Nature of Code p5.js 示例项目教程The Nature of Code p5.js 示例项目教程 1. 项目介绍 The Nature of Code p5.js 是一个开源项目旨在将《The示例工程文档/教程前端用 p5.js 的 sin() 函数模拟简谐运动Nature of Code 3.5 完整实战指南用 p5.js 的 sin 函数模拟简谐运动Nature of Code 3.5 完整实战指南 本文基于 Coding Train 网站归档仓库中《Natur教程文档示例工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考