| | | 1 | | using System; |
| | | 2 | | using CounterDrone.Core.Models; |
| | | 3 | | |
| | | 4 | | namespace CounterDrone.Core.Algorithms |
| | | 5 | | { |
| | | 6 | | /// <summary>高斯烟团扩散模型 — 简化实现</summary> |
| | | 7 | | public class GaussianPuffDispersion : ICloudDispersionModel |
| | | 8 | | { |
| | 19 | 9 | | private AmmunitionSpec _ammo = null!; |
| | | 10 | | private float _elapsed; |
| | | 11 | | private float _currentRadius; |
| | | 12 | | private Vector3 _center; |
| | | 13 | | private Vector3 _windVelocity; |
| | | 14 | | |
| | 2186 | 15 | | public Vector3 Center => _center; |
| | 367 | 16 | | public float Radius => _currentRadius; |
| | 785 | 17 | | public float CoreDensity { get; private set; } |
| | 364 | 18 | | public float EffectiveRadius => _currentRadius; // 简化:有效半径 = 物理半径 |
| | 1128 | 19 | | public ParticleParams Particles { get; } = new(); |
| | 1122 | 20 | | public bool IsDissipated { get; private set; } |
| | | 21 | | |
| | | 22 | | public void Initialize(AmmunitionSpec ammo, CombatScene env, Vector3 releasePos, float releaseTime) |
| | 18 | 23 | | { |
| | 18 | 24 | | _ammo = ammo; |
| | 18 | 25 | | _elapsed = 0f; |
| | 18 | 26 | | _currentRadius = (float)ammo.InitialRadius; |
| | 18 | 27 | | _center = releasePos; |
| | 18 | 28 | | CoreDensity = (float)ammo.CoreDensity; |
| | 18 | 29 | | IsDissipated = false; |
| | | 30 | | |
| | | 31 | | // 风速 → 速度矢量 |
| | 18 | 32 | | var (vx, vy, vz) = Kinematics.WindToVector((WindDirection)env.WindDirection, (float)env.WindSpeed); |
| | 18 | 33 | | _windVelocity = new Algorithms.Vector3(vx, vy, vz); |
| | 18 | 34 | | } |
| | | 35 | | |
| | | 36 | | public void Tick(float deltaTime, float windSpeed, WindDirection windDir) |
| | 370 | 37 | | { |
| | 370 | 38 | | if (IsDissipated) return; |
| | | 39 | | |
| | 370 | 40 | | _elapsed += deltaTime; |
| | | 41 | | |
| | | 42 | | // 更新风速(允许动态变化) |
| | 370 | 43 | | var (vx, vy, vz) = Kinematics.WindToVector(windDir, windSpeed); |
| | 370 | 44 | | _windVelocity = new Algorithms.Vector3(vx, vy, vz); |
| | | 45 | | |
| | | 46 | | // 半径膨胀:初始半径 + 扩散速率 × 时间 |
| | | 47 | | // 加入大气稳定度因子(简化:1.0) |
| | 370 | 48 | | var dispersionRate = (float)(_ammo.DispersionRateBase * 1.0f); |
| | 370 | 49 | | _currentRadius = (float)_ammo.InitialRadius + dispersionRate * _elapsed; |
| | | 50 | | |
| | | 51 | | // 中心随风漂移 |
| | 370 | 52 | | _center += _windVelocity * deltaTime; |
| | | 53 | | |
| | | 54 | | // 密度衰减:核心密度 × (初始半径 / 当前半径)³ |
| | 370 | 55 | | if (_currentRadius > 0.001f) |
| | 370 | 56 | | { |
| | 370 | 57 | | var volumeRatio = (float)System.Math.Pow((float)_ammo.InitialRadius / _currentRadius, 3); |
| | 370 | 58 | | CoreDensity = (float)_ammo.CoreDensity * volumeRatio; |
| | 370 | 59 | | } |
| | | 60 | | |
| | | 61 | | // 更新粒子参数 |
| | 370 | 62 | | Particles.Opacity = System.Math.Max(0.1f, CoreDensity / (float)_ammo.CoreDensity); |
| | 370 | 63 | | Particles.SizeMultiplier = _currentRadius / (float)_ammo.InitialRadius; |
| | | 64 | | |
| | | 65 | | // 消散条件 |
| | 370 | 66 | | if (_elapsed >= (float)_ammo.MaxDuration || _currentRadius >= (float)_ammo.MaxRadius) |
| | 3 | 67 | | { |
| | 3 | 68 | | IsDissipated = true; |
| | 3 | 69 | | Particles.Opacity = 0f; |
| | 3 | 70 | | } |
| | 370 | 71 | | } |
| | | 72 | | } |
| | | 73 | | } |