130 lines
3.9 KiB
C#
130 lines
3.9 KiB
C#
using System;
|
||
using System.IO;
|
||
using CounterDrone.Core.Algorithms;
|
||
using CounterDrone.Core.Models;
|
||
using Xunit;
|
||
|
||
namespace CounterDrone.Core.Tests
|
||
{
|
||
public class DispersionModelTests
|
||
{
|
||
private AmmunitionSpec CreateTestAmmo()
|
||
{
|
||
return new AmmunitionSpec
|
||
{
|
||
InitialRadius = 50.0,
|
||
InitialVolume = 500000.0,
|
||
CoreDensity = 1.2,
|
||
EdgeDensity = 0.1,
|
||
DispersionRateBase = 5.0,
|
||
MaxRadius = 200.0,
|
||
MaxDuration = 60.0,
|
||
EffectiveConcentration = 0.05,
|
||
};
|
||
}
|
||
|
||
private CombatScene CreateTestEnv(float windSpeed = 5.0f, WindDirection dir = WindDirection.E)
|
||
{
|
||
return new CombatScene
|
||
{
|
||
WindSpeed = windSpeed,
|
||
WindDirection = (int)dir,
|
||
Temperature = 20,
|
||
Humidity = 60,
|
||
Pressure = 1013,
|
||
};
|
||
}
|
||
|
||
[Fact]
|
||
public void Initialize_SetsProperties()
|
||
{
|
||
var model = new GaussianPuffDispersion();
|
||
var ammo = CreateTestAmmo();
|
||
var env = CreateTestEnv();
|
||
|
||
model.Initialize(ammo, env, new Vector3(1000, 0, 300), 0f);
|
||
|
||
Assert.Equal(50f, model.Radius);
|
||
Assert.Equal(1.2f, model.CoreDensity);
|
||
Assert.False(model.IsDissipated);
|
||
}
|
||
|
||
[Fact]
|
||
public void Tick_ExpandsRadius()
|
||
{
|
||
var model = new GaussianPuffDispersion();
|
||
model.Initialize(CreateTestAmmo(), CreateTestEnv(), new Vector3(0, 0, 0), 0f);
|
||
|
||
// 5 秒后
|
||
model.Tick(5f, 5f, WindDirection.E);
|
||
// 初始 50 + 扩散速率 5 × 5s = 75
|
||
Assert.True(model.Radius > 55f && model.Radius < 80f);
|
||
}
|
||
|
||
[Fact]
|
||
public void Tick_WindDrift_MovesCenter()
|
||
{
|
||
var model = new GaussianPuffDispersion();
|
||
model.Initialize(CreateTestAmmo(), CreateTestEnv(10f, WindDirection.E), new Vector3(0, 0, 0), 0f);
|
||
|
||
model.Tick(10f, 10f, WindDirection.E);
|
||
|
||
// 东风 10 m/s × 10s = 100m,东是 +X
|
||
Assert.True(model.Center.X > 80f);
|
||
Assert.True(model.Center.Z < 20f); // 纯东向,Z 不应有大偏移
|
||
}
|
||
|
||
[Fact]
|
||
public void Tick_DensityDecays()
|
||
{
|
||
var model = new GaussianPuffDispersion();
|
||
model.Initialize(CreateTestAmmo(), CreateTestEnv(0f, WindDirection.N), new Vector3(0, 0, 0), 0f);
|
||
|
||
model.Tick(20f, 0f, WindDirection.N);
|
||
|
||
// 半径膨胀后密度应下降
|
||
Assert.True(model.CoreDensity < 1.2f);
|
||
}
|
||
|
||
[Fact]
|
||
public void Tick_DissipatesAfterMaxDuration()
|
||
{
|
||
var model = new GaussianPuffDispersion();
|
||
var ammo = CreateTestAmmo();
|
||
ammo.MaxDuration = 5.0; // 5秒消散
|
||
model.Initialize(ammo, CreateTestEnv(), new Vector3(0, 0, 0), 0f);
|
||
|
||
model.Tick(6f, 0f, WindDirection.N);
|
||
|
||
Assert.True(model.IsDissipated);
|
||
}
|
||
|
||
[Fact]
|
||
public void Tick_DissipatesAtMaxRadius()
|
||
{
|
||
var model = new GaussianPuffDispersion();
|
||
var ammo = CreateTestAmmo();
|
||
ammo.MaxRadius = 60.0;
|
||
ammo.DispersionRateBase = 100.0; // 快速膨胀
|
||
model.Initialize(ammo, CreateTestEnv(), new Vector3(0, 0, 0), 0f);
|
||
|
||
model.Tick(1f, 0f, WindDirection.N);
|
||
|
||
Assert.True(model.IsDissipated);
|
||
}
|
||
|
||
[Fact]
|
||
public void ParticleOpacity_DecaysWithDensity()
|
||
{
|
||
var model = new GaussianPuffDispersion();
|
||
model.Initialize(CreateTestAmmo(), CreateTestEnv(0f, WindDirection.N), new Vector3(0, 0, 0), 0f);
|
||
|
||
Assert.Equal(1.0f, model.Particles.Opacity, 0.01f);
|
||
|
||
model.Tick(30f, 0f, WindDirection.N);
|
||
|
||
Assert.True(model.Particles.Opacity < 1.0f);
|
||
}
|
||
}
|
||
}
|