diff --git a/src/CounterDrone.Core/Algorithms/DefensePlanner.cs b/src/CounterDrone.Core/Algorithms/DefensePlanner.cs index 838ef62..cd5e556 100644 --- a/src/CounterDrone.Core/Algorithms/DefensePlanner.cs +++ b/src/CounterDrone.Core/Algorithms/DefensePlanner.cs @@ -138,16 +138,16 @@ namespace CounterDrone.Core.Algorithms // 单机需求 var (effectiveRadius, expansionTime, turbulentRadius) = ComputeEffectiveRadius(ammo, env); - int singleNeeded = CalcRoundsNeeded(threat, ammo, env, false, turbulentRadius); + int singleNeeded = CalcRoundsNeeded(threat, ammo, env, false, effectiveRadius); // 车道划分(可替换策略) - var (yLanes, laneSpacing) = _laneDivider.Divide(threat, turbulentRadius); + var (yLanes, laneSpacing) = _laneDivider.Divide(threat, effectiveRadius); float formationWidth = yLanes > 1 ? (yLanes - 1) * laneSpacing : 0f; int totalRoundsNeeded = singleNeeded * yLanes; // 逐单元分配:每个单元锁定一个 Y 车道 - // 云团间距 = 2R × (1 - 重叠比例),重叠由配置驱动,保证有效区互相覆盖 - float spacing = 2f * turbulentRadius * (1f - _config.CloudOverlapRatio); + // 云团间距 = 2R × (1 - 重叠比例),R 为穿越时刻的有效半径,保证无缝覆盖 + float spacing = 2f * effectiveRadius * (1f - _config.CloudOverlapRatio); int[] laneNeeded = new int[yLanes]; float[] laneBaseTime = new float[yLanes]; bool[] laneBaseSet = new bool[yLanes]; @@ -178,7 +178,7 @@ namespace CounterDrone.Core.Algorithms laneBaseTime[yLane] = refEvt[0].FireTime; laneBaseSet[yLane] = true; } - float stagger = Kinematics.CloudCoverInterval(turbulentRadius * 2f, GetDroneSpeedKph(threat), c.Unit.ChannelInterval); + float stagger = Kinematics.CloudCoverInterval(effectiveRadius * 2f, GetDroneSpeedKph(threat), c.Unit.ChannelInterval); var fevents = new List(); int unitIdx = fireUnits.IndexOf(c.Unit); @@ -381,10 +381,8 @@ namespace CounterDrone.Core.Algorithms AmmunitionSpec ammo, CombatScene env) { var model = new CloudExpansionModel(ammo, env); - float rPhase2 = model.RadiusAt(30f); - float expansionTime = model.TimeToReach(rPhase2); - // 云团被穿过时的真实年龄 = expansionTime(云团生成后膨胀到有效半径的时长)。 - // 这是云团自身的物理量,与无人机飞行时间无关。 + float rPhase2 = model.RadiusAt(model.Phase2Duration); + float expansionTime = model.TimeToReach(rPhase2) * _config.ExpansionFactor; float effectiveR = model.RadiusAt(expansionTime); return (effectiveR, expansionTime, rPhase2); } @@ -407,7 +405,7 @@ namespace CounterDrone.Core.Algorithms { float avgSpeed = GetDroneSpeedMs(threat); var (effectiveR, _, _) = ComputeEffectiveRadius(ammo, env); - float spacing = 2f * effectiveR; + float spacing = 2f * effectiveR * (1f - _config.CloudOverlapRatio); float actualCoverage = spacing * (rounds - 1) + 2f * effectiveR; float actualExposure = actualCoverage / avgSpeed; @@ -430,10 +428,7 @@ namespace CounterDrone.Core.Algorithms if (wps == null || wps.Count < 2) return (events, "航路无效"); var cloudModel = new CloudExpansionModel(ammo, env); - // 云龄 = expansionTime(云团生成后膨胀到有效半径的时长) - float effectiveAge = cloudModel.TimeToReach(cloudModel.TurbulentRadius) * _config.ExpansionFactor; - float effectiveR = cloudModel.RadiusAt(effectiveAge); - float expansionTime = cloudModel.TimeToReach(effectiveR); + var (effectiveR, expansionTime, _) = ComputeEffectiveRadius(ammo, env); float densityAtPassage = cloudModel.DensityAt(expansionTime); if (densityAtPassage < (float)ammo.EffectiveConcentration) diff --git a/src/CounterDrone.Core/Algorithms/GaussianPuffDispersion.cs b/src/CounterDrone.Core/Algorithms/GaussianPuffDispersion.cs index 09ed683..6390d8a 100644 --- a/src/CounterDrone.Core/Algorithms/GaussianPuffDispersion.cs +++ b/src/CounterDrone.Core/Algorithms/GaussianPuffDispersion.cs @@ -61,7 +61,7 @@ namespace CounterDrone.Core.Algorithms var (vx, vy, vz) = Kinematics.WindToVector(windDir, windSpeed); _windVelocity = new Vector3(vx, vy, vz); - if (!_inPhase3 && _elapsed >= 30f) + if (!_inPhase3 && _elapsed >= (float)_ammo.Phase2Duration) _inPhase3 = true; if (!_inPhase3) @@ -76,7 +76,7 @@ namespace CounterDrone.Core.Algorithms else { // Phase 3: 高斯扩散 - float x = windSpeed * (_elapsed - 30f); + float x = windSpeed * (_elapsed - (float)_ammo.Phase2Duration); if (x <= 0) return; // 尚未进入有效扩散距离 var cls = Kinematics.GetStabilityClass((WeatherType)_env.WeatherType, windSpeed); var sY = Kinematics.SigmaY(cls, x); diff --git a/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll b/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll index 1873c29..a75e497 100644 Binary files a/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll and b/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll differ diff --git a/unity_plugins/CounterDrone.Core.dll b/unity_plugins/CounterDrone.Core.dll index 1873c29..a75e497 100644 Binary files a/unity_plugins/CounterDrone.Core.dll and b/unity_plugins/CounterDrone.Core.dll differ