Skip to main content

Command Palette

Search for a command to run...

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

Updated
•2 min read•View as Markdown

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⁡=12mvmax⁡2K_{\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 中檢測並確保質量、動量嚴格不變。


More from this blog

【5/8 更新】2d 粒子模擬系統:ui 分區、標籤管理、邊界限制與力向量可視化

畫面 UI 三區塊化 標籤動態顯示與排序 畫面邊界位置強制約束 萬有引力向量可視化 以下分別介紹每個部分的需求、實作與程式碼重點。 一、畫面 UI 三區塊化 需求: 左側輸入區(僅在按下「開始」前顯示) 中間世界區(永遠用來渲染粒子本體與標籤) 右側控制區(開始後顯示所有操作按鈕/滑桿/圖表,不覆蓋世界區) 實作: 在 Canvas 下建立三個 Panel:LeftPanel、WorldPanel、RightPanel LeftPanel:固定寬 300px,掛 Ver...

May 9, 20253 min read

Unity 2D 粒子模擬系統 — 今日更新總結

已思考 2 秒鐘 在本次更新中,我們從架構、效能、物理到 UI,都進行了大規模的優化與功能擴充,包含: 模組化重構 效能優化五部曲 互動式 UI 強化 Collider2D 碰撞檢測 動態縮放與顏色漸變 邊界管理 以下依序詳述每個部分。 1. 模組化重構 ParticleManager.cs:集中管理粒子與標籤,採用物件池(Pool)技術。 GravitationalSystem.cs:只負責萬有引力計算,碰撞行為改由 HandleCollision 處理。 Partic...

May 7, 20252 min read

郭sir's Blog

7 posts