canvas 有趣的弹簧效果

先上效果

两个小球之间有一根弹簧,这里有一条线表示,其中左球固定,在点击开始后,右球开始做自由落体

思路

先做受力分析

经过受力分析可以发现,整个系统一共有三个在起作用,我们分别把他们求出来并合成为一个,然后这个加速度即可

重力

右边小球全程受到方向向下的重力,其公式为

G = m * g
弹力

右边小球全程受到从自身中心指向左边小球中心方向的的弹力,其公式为

// 胡克定律
F = -△x * k
空气阻力

可以简化成和速度方向相反,乘一个小于1的阻力系数的力

// dragCoefficient值越大说明阻力越大
F = -v * dragCoefficient

我们先创建重力的单位向量代表重力的方向,因为重力永远是垂直向下的所以向量其单位向量是(0, 1),然后给定一个重力大小,根据重力公式,质量乘重力加速度即可,这里质量我给了 10,重力加速度给 9.8,代码如下

// 获取重力单位向量
function getGravityNorVector() {return {x: 0,y: 1,};
}// 获取重力大小
function getGravitySize() {return m * g;
}

然后创建弹力单位向量表示弹力的方向,其方向永远是右球的球心指向左球的球心,其大小根据胡克定律给到,即形变距离 乘以 弹簧弹性系数

// 获取弹力单位向量
function getElasticityNorVector() {// 左球球心坐标减右球球心坐标,然后做向量归一化return normalized(createVector(originPosition, targetPosition));
}// 获取弹力大小
function getElasticitySize() {// 计算Δxconst offsetX =length(createVector(originPosition, targetPosition)) - originElasticitySize;// 胡克定律,只要大小,所以取绝对值return Math.abs(-offsetX * K);
}

然后我们计算空气阻力,其方向和速度方向相反,阻力系数我给了个 0.1,由于一开始初速度为 0,所以阻力为 0,只用等到动起来有速度的时候才会产生阻力

// 空气阻力,dragCoefficient为阻力系数,输出是一个向量
const other = {x: -vx * dragCoefficient,y: -vy * dragCoefficient,
};

现在我们所有力的大小和方向都求出来了,然后根据向量平行四边形法则,先合成弹力重力

// 单位向量 * 向量长度可以得到矢量力,输出是一个向量
const elasticityAndGravity = add(mul(getElasticitySize(), getElasticityNorVector()),mul(getGravitySize(), getGravityNorVector())
);

然后再和空气阻力合成最终的力

// 所有力的合成,输出是一个向量
const total = add(elasticityAndGravity, other);

然后再把合成后的力分解成水平和垂直的两个分力,这里用到向量投影算法就能实现,即可以先通过向量点积的形式,求出与水平单位向量(1,0)和垂直单位向量(0,1)的余弦值,然后用合成力的大小乘以这个余弦值得到投影到水平方向和垂直方向的大小,再用这个大小分别乘以水平单位向量(1,0)和垂直单位向量(0,1)就能得到水平和垂直的两个分力向量

// 获取力在x轴和y轴分量向量
function getXYAxisVector(fNorVector, fSize) {const yAxisNorVector = createVector({x: targetPosition.x,y: targetPosition.y - 1,},targetPosition);const xAxisNorVector = createVector({x: targetPosition.x - 1,y: targetPosition.y,},targetPosition);// 分别点击求向量在水平单位向量和垂直单位向量的余弦值const cosYAxis = dot(yAxisNorVector, fNorVector);const cosXAxis = dot(xAxisNorVector, fNorVector);return {yVector: mul(fSize * cosYAxis, yAxisNorVector),xVector: mul(fSize * cosXAxis, xAxisNorVector),};
}// 获取水平和垂直分力向量
const result = getXYAxisVector(normalized(total), length(total));

然后根据公式

F = m * a;

把得到的两个分力分别除以质量 m,目前 m 给的是 10,得到 x 和 y 方向的加速度

// 获取水平和垂直方向加速度
const xAcceleration = result.xVector.x / m;
const yAcceleration = result.yVector.y / m;

然后再每一帧渲染的时候,把加速度加到速度上,右球的坐标加上速度,即可以渲染出效果,这里除以100是防止速度太快

vx += xAcceleration;
vy += yAcceleration;
targetPosition.x += vx / 100;
targetPosition.y += vy / 100;

就能得到最终这个效果了

源码

可以关注下我的公众号,对应的文章有源码,还有其他有趣的干货文章哦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/214570.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

控制台打印如来佛图像

代码 System.out.println(" _ooOoo_ \n"" o8888888o \n"" 88 \".\" 88 …

python——第十七天

方法重写(overwrite) 、方法覆盖(override ):在继承的基础上,子类继承了父类的方法,如果不能满足自己使用,我们就可以重写或覆盖该方法 函数重载(overload): 在强数据类型的编程语言中(如Java、C、C等等): 函数名称…

PDI/Kettle-9.4.0.0-343源码下载及编译

目录 🍑一、概要🍊最新版本10.x(2023-11-30) 🍑二、下载🍑三、编译🍊3.1、导入开发工具🍊3.2、开始编译🍊3.3、编译报错🍊3.4、报错原因:jdk版本低…

centos7安全防护_CPU占用率超过百分之300_centos7.4中毒CPU百分之百_清理毒源---Linux工作笔记068

执行top命令的时候看到有个进程: sshd占用cpu百分之300多...而且就算是kill -9 杀掉进程以后,进程又会自动启动 ll /proc/7298 我们执行这个命令,可以看到有个/var/tmp/sshd的文件 我们进入cd /var/tmp 然后我们执行 rm -rf sshd删除这个文件,然后我们再去top可以看到 cpu就…

【数仓理论】

一、数仓建模方法论 1.1 ER模型(Entity Relationship、实体关系模型、范式模型) ER模型是Bill Inmon提出的一种建模方法,实体关系模型将复杂的数据抽象为两个概念 ---- 实体和关系 该模型在范式理论上符合3NF,这种模型目的是减少…

测距传感器

测距传感器 电子元器件百科 文章目录 测距传感器前言一、测距传感器是什么二、测距传感器的类别三、测距传感器的应用实例四、测距传感器的作用原理总结前言 测距传感器广泛应用于自动化控制、机器人导航、无人驾驶、测量仪器等领域。不同类型的测距传感器具有不同的测距范围、…

重磅!2023中国高校计算机大赛-人工智能创意赛结果出炉

目录 中国计算机大赛-人工智能创意赛现场C4-AI大赛颁奖及留影800个AI应用?这届大学生真能“搞事情”AI原生时代,百度要再培养500万大模型人才 中国计算机大赛-人工智能创意赛现场 12月8日,杭州,一位“白发老人”突然摔倒在地&…

[基础IO]文件描述符{C库函数\系统接口\初识fd}

文章目录 1.基础知识1.1对文件的认识1.2对系统调用接口的认识1.3如何理解LInux下一切皆文件? 2.C语言的库函数2.1FILE *fopen(const char *path, const char *mode);2.2对fopen()的mode的w/a的深层认识2.3fclose()2.4size_t fwrite(const void *ptr, size_t size, size_t nmem…

【桌面应用开发】Tauri是什么?基于Rust的桌面应用

自我介绍 做一个简单介绍,酒架年近48 ,有20多年IT工作经历,目前在一家500强做企业架构.因为工作需要,另外也因为兴趣涉猎比较广,为了自己学习建立了三个博客,分别是【全球IT瞭望】,【…

深入.NET平台和C#编程总结大全

第一章 简单认识.NET框架 (1)首先我们得知道 .NET框架具有两个主要组件:公共语言进行时CLR(Common Language Runtime)和框架类库FCL(Framework Class Library) 配图: (…

Java - JVM内存区域的划分

Java 程序运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。 分配:通过关键字new创建对象分配内存空间,对象存在堆中。 释放 &…

柔性数组详解

前言:柔性数组是C99中新添加的概念,它是结构体里面的最后一个成员,因为它的大小未知,所以很灵活,称之为柔 1 柔性数组占不占结构体的空间呢? 不占 typedef struct Stu {char y;int x;int arr[];//有些编译器…

数据在内存中的存储(整型篇)

1.辨析原码反码补码: 1.原码:有32位(int类四个字节,一个字节八个比特位),第一位是符号位,0正1负,其余为二进制位。 2.计算一般是对原码进行计算,但在负数计算使用原码会导…

高效利用内存资源之动态内存管理详解

目录 一、为什么存在动态内存分配 二、动态内存函数的介绍 2.1malloc 2.2free 2.3calloc 2.4realloc 三、常见的动态内存错误 3.1对NULL指针的解引用操作 3.2对动态开辟空间的越界访问 3.3对非动态开辟内存使用free释放 3.4使用free释放一块动态开辟内存的一部分 3.…

Spring Boot 3 集成 Druid 连接池详解

在现代的Java应用中,使用一个高效可靠的数据源是至关重要的。Druid连接池作为一款强大的数据库连接池,提供了丰富的监控和管理功能,成为很多Java项目的首选。本文将详细介绍如何在Spring Boot 3项目中配置数据源,集成Druid连接池&…

【ACM独立出版、确定的ISBN号】第三届密码学、网络安全和通信技术国际会议(CNSCT 2024)

第三届密码学、网络安全和通信技术国际会议(CNSCT 2024) 2024 3rd International Conference on Cryptography, Network Security and Communication Technology 随着互联网和网络应用的不断发展,网络安全在计算机科学中的地位越来越重要&…

精选:免费且高效的邮件营销软件推荐

好用的邮件营销软件可以帮助企业获取客户、维系客户关系。对于有想做邮件营销想法,但是想先试试的企业来讲,免费版邮件营销软件就是个不错的选择。当然,免费的邮件邮件营销软件虽然在价格上有极大的优势,但是功能上会有各种限制。…

【小白专用】MySQL查询数据库所有表名及表结构其注释

一、先了解下INFORMATION_SCHEMA 1、在MySQL中,把INFORMATION_SCHEMA看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权 限等。在INF…

网络安全——SSH密码攻击实验

一、实验目的要求: 二、实验设备与环境: 三、实验原理: 四、实验步骤:​ 五、实验现象、结果记录及整理: 六、分析讨论与思考题解答: 一、实验目的要求: 1、了解SSH密码攻击、FTP密码攻击…

Jmeter 请求签名api接口-BeanShell

Jmeter 请求签名api接口-BeanShell 项目签名说明编译扩展jar包jmeter 使用 BeanShell 调用jar包中的签名方法 项目签名说明 有签名算法的api接口本地不好测试,使用BeanShell 扩展jar 包对参数进行签名,接口签名算法使用 sha512Hex 算法。签名的说明如下…