【5/8 更新】2d 粒子模擬系統-萬有引力還原、全系統速度上限、能量門檻設定

2 min read
1. 純粹萬有引力還原,移除阻尼與軟化
動力學:回到經典 F=G m1m2/r2F = G\,m_1m_2/r^2,不再在分母加 ε 軟化,也不做任何速度阻尼。
程式碼:
// GravitationalSystem.ApplyForces() float forceMag = gravitationalConstant * (rbA.mass * rbB.mass) / (dist * dist); Vector2 force = forceMag * dir.normalized; rbA.AddForce(force); rbB.AddForce(-force);
2. 全系統速度上限(systemSpeedLimit)
需求:不只是初速限制,而是讓所有粒子在任何時刻都無法超過指定速度。
實作:在
SimulationController.FixedUpdate()
的力運算後呼叫:private void ClampVelocities() { foreach (var p in particleManager.GetActiveParticles()) { var rb = p.GetComponent<Rigidbody2D>(); if (rb.velocity.magnitude > systemSpeedLimit) rb.velocity = rb.velocity.normalized * systemSpeedLimit; } }
初始化:由使用者在 UI 輸入框設定
systemSpeedLimit
,並在GenerateParticlesFromInput()
一併讀取。
3. 能量門檻動態設定
門檻欄位:在
GravitationalSystem
中新增public float mergeEnergyThreshold; // 合併時總動能 ≤ 此值 public float splitEnergyThreshold; // 分裂時總動能 ≥ 此值
同步速度上限:
SimulationController
讀取systemSpeedLimit
後,計算「最大動能」Kmax=12mvmax2K_{\max} = \tfrac12 m v_{\max}^2,並依 UI 參數mergeThresholdFactor
/splitThresholdFactor
自動更新:float maxEnergy = 0.5f * systemSpeedLimit * systemSpeedLimit; gravitationalSystem.mergeEnergyThreshold = mergeThresholdFactor * maxEnergy; gravitationalSystem.splitEnergyThreshold = splitThresholdFactor * maxEnergy;
4. 嚴格守恆驗證:合併與分裂
合併
private void MergeParticles(...) { // 計算合併前質量與動量 float mA = rbA.mass, mB = rbB.mass; Vector2 pBefore = mA*rbA.velocity + mB*rbB.velocity; // 更新質量與速度 float mTotal = mA + mB; rbA.mass = mTotal; rbA.velocity = pBefore / mTotal; // 視覺更新 ← 調整大小與顏色 // … // 驗證質量與動量守恆 Debug.Assert(Mathf.Approximately(rbA.mass, mTotal)); Vector2 pAfter = rbA.mass * rbA.velocity; Debug.Assert((pAfter - pBefore).sqrMagnitude < 1e-6f); particleManager.RemoveParticle(j); }
分裂
private void FragmentParticles(...) { float mB = rbB.mass; Vector2 pBefore = mB * rbB.velocity; // 移除原粒子,產生兩個子粒子(各半質量、動量分配) // … // 驗證守恆 float mAfter = fragMass*2f; Vector2 pAfter = fragMass*v1 + fragMass*v2; Debug.Assert(Mathf.Approximately(mAfter, mB)); Debug.Assert((pAfter - pBefore).sqrMagnitude < 1e-6f); }
如此一來,每次合併/分裂都會在 Console 中檢測並確保質量、動量嚴格不變。
0
Subscribe to my newsletter
Read articles from 郭俊鑫 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
