主題

【Unity / C#】研究布料模擬公式,談談Euler integration (歐拉積分)和 Verlet integration(韋爾萊積分)

%%鼠 | 2021-07-24 04:21:26 | 巴幣 1430 | 人氣 187

前言:
想直接看怎麼不用Unity joint做繩子模擬可以看:

想直接看原文的理論教學可以看:

數學令人著迷。
完整筆記和 摳程式碼:Notion



以下筆記:
你能用

h= −16t^2+vt+k

取得拋物線上任一時間點的高度。

但物理引擎為了省運算效能,會用固定的delta時間去計算。(疊代次數越高畫得曲線越圓滑。)
以上是當v只有單純重力的時候,當v來源多變的話,可以用以下公式:

NewPos = PrePos + v * t
優點:運算快、簡單
缺點:不夠準確(疊代次數越低越不準確)、容易得到誇張的值(例如東西直接飛出去)。
照時間直接修改速度
影片解釋:時間點
當疊代次數過低,導致球明明趨近反曲點了,但因為疊代次數過低,使之沿用過快的速度,拋物線逐漸歪掉。

2. Verlet integration(韋爾萊積分)
NewPos = CurrPos + (CurrPos - OldPos)
用位移量當速度,又稱為Ragdoll物理(布娃娃物理)
優點: 執行效能還行、數值穩定。
缺點:比Euler還不精確,但穩定。

基於數值穩定,選擇Verlet integration。

點 架構:
為了圖形話物件,所以加個transform去操作球球~

計算速度:
NewPos = CurrPos + (CurrPos - OldPos)

59行 要先宣告一個變數是因為struct無法直接改值,若是用class就沒這問題。
60行 計算速度乘上磨擦力

計算牆壁碰撞:
偷懶不做collider,用畫面4邊當牆壁:

反彈力道影片:時間點
假設撞到y軸牆面,將原本的x軸鏡射,變成力道方向從牆壁出發。
彈跳球:

(拍謝,為了看撞牆效果,此demo重力是(-0.1f, -0.5f) )


加入Stick支撐
架構

計算柱子拉縮:
第108行 magnitude=向量長度
第109行 算出每點各需退/進的比例。  距離差 除以 實際距離 / 2
※不太確定為甚麼109行不是 _difference / sticks[i].fixedDistance / 2 ?  (用固定距離當除數而不是兩點的距離,但這樣改Unity會有(-Infinity, Infinity)問題)

程式碼解說:時間點
影片解說:時間點
假設兩點固定長度設定80,但經速度計算下來,兩點相距只有60,則每點往內縮(80-60)/2。反之亦然

有點太怪是因為需要增加疊代次數:
Unity物理本身也有疊代次數的設定(例 Physics2D.velocityIterations),每FixedUpdate會執行幾次運算,預設好像是8。

畫方形:
不小心拉到sprite。orz

太軟Q了就加支柱!
又不小心拉到sprite。 orz


備註:
Δ位移量 = 速度
Δ速度 = 加速度
Δ(Δ位移量) = 加速度  

三階以上微分沒意義。

腦洞:
配上f=ma,有位移量就能知道動能了

創作回應

⊰⊱大報社⊰⊱
感謝教學
2021-07-24 08:20:20
%%鼠
學習辛苦了! 來杯熱牛奶
2021-07-25 00:20:06
is樂小呈
微積分 https://i.imgur.com/i5ZIGoo.gif
2021-07-24 11:03:49
%%鼠
我覺得滿有趣的耶
2021-07-25 00:20:38
追蹤 創作集

作者相關創作

相關創作

更多創作