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.pswp.cn/news/214570.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/214570.shtml
英文地址,請注明出處:http://en.pswp.cn/news/214570.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

控制臺打印如來佛圖像

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

python——第十七天

方法重寫(overwrite) 、方法覆蓋(override ):在繼承的基礎上,子類繼承了父類的方法,如果不能滿足自己使用,我們就可以重寫或覆蓋該方法 函數重載(overload): 在強數據類型的編程語言中(如Java、C、C等等): 函數名稱…

轉換 pytorch 格式模型為 caffe格式模型 pth2caffemodel

基于 GitHub xxradon/PytorchToCaffe 源碼,修改 example\resnet_pytorch_2_caffe.py 如下 import os import sys sys.path.insert(0, .)import torch from torch.autograd import Variable from torchvision.models import resnet import pytorch_to_caffe"&q…

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,這種模型目的是減少…

測距傳感器

測距傳感器 電子元器件百科 文章目錄 測距傳感器前言一、測距傳感器是什么二、測距傳感器的類別三、測距傳感器的應用實例四、測距傳感器的作用原理總結前言 測距傳感器廣泛應用于自動化控制、機器人導航、無人駕駛、測量儀器等領域。不同類型的測距傳感器具有不同的測距范圍、…

xtu oj 1178 Rectangle

題目描述 給你兩個平行于坐標軸的矩形,請判斷兩者是不是相交(面積有重合的部分)? 輸入 第一行是一個整數K,表示樣例數。 每個樣例占兩行,每行是4個整數,表示一個矩形的對角線點的坐標&#x…

重磅!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…

測試經理主管面試題

測試專業技能 請談談您對軟件測試生命周期(STLC)的理解 需求分析:在這個階段,測試團隊仔細分析項目需求,理解產品功能和非功能需求。這有助于確定測試的范圍和目標,為后續階段奠定基礎。測試計劃&#xf…

【桌面應用開發】Tauri是什么?基于Rust的桌面應用

自我介紹 做一個簡單介紹,酒架年近48 ,有20多年IT工作經歷,目前在一家500強做企業架構.因為工作需要,另外也因為興趣涉獵比較廣,為了自己學習建立了三個博客,分別是【全球IT瞭望】,【…

深入.NET平臺和C#編程總結大全

第一章 簡單認識.NET框架 (1)首先我們得知道 .NET框架具有兩個主要組件:公共語言進行時CLR(Common Language Runtime)和框架類庫FCL(Framework Class Library) 配圖: (…

JSON

JSON指的是 JavaScript 對象表示法(JavaScript Object Notation) javascript對象:javascript中,除開JavaScript原始值(字符串,數字,布爾值,null,正則表達式)的都是javascript對象 JS…

Java - JVM內存區域的劃分

Java 程序運行時,需要在內存中分配空間。為了提高運算效率,就對空間進行了不同區域的劃分,因為每一片區域都有特定的處理數據方式和內存管理方式。 分配:通過關鍵字new創建對象分配內存空間,對象存在堆中。 釋放 &…

柔性數組詳解

前言:柔性數組是C99中新添加的概念,它是結構體里面的最后一個成員,因為它的大小未知,所以很靈活,稱之為柔 1 柔性數組占不占結構體的空間呢? 不占 typedef struct Stu {char y;int x;int arr[];//有些編譯器…

數據在內存中的存儲(整型篇)

1.辨析原碼反碼補碼: 1.原碼:有32位(int類四個字節,一個字節八個比特位),第一位是符號位,0正1負,其余為二進制位。 2.計算一般是對原碼進行計算,但在負數計算使用原碼會導…

強化學習(二)——Dueling Network(DQN改進)

與DNQ相比,使用優勢函數(A函數)和狀態價值函數(V)代替之前的Q(動作價值)函數, 最核心公式為 Q ? ( s , a ) A ? ( s , a ) V ? ( s ) ? max ? a A ? ( s , a ) Q^*(s,a)A^*(s,a)V^*(s)-\max_a A^*(s,a) Q?(s,a)A?(s,a)V…

高效利用內存資源之動態內存管理詳解

目錄 一、為什么存在動態內存分配 二、動態內存函數的介紹 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連接池&…