100 lines
3.7 KiB
C#
100 lines
3.7 KiB
C#
using CounterDrone.Core.Algorithms;
|
||
using CounterDrone.Core.Models;
|
||
using CounterDrone.Core.Simulation;
|
||
using Xunit;
|
||
|
||
namespace CounterDrone.Core.Tests
|
||
{
|
||
public class MunitionEntityTests
|
||
{
|
||
[Fact]
|
||
public void GroundBased_DoesNotArriveImmediately()
|
||
{
|
||
var m = new MunitionEntity("m1", PlatformType.GroundBased,
|
||
AerosolType.InertGas,
|
||
startX: 0, startY: 0, startZ: 0,
|
||
targetX: 5000, targetY: 300, targetZ: 0,
|
||
muzzleVelocity: 500f, releaseAltitude: 300f);
|
||
|
||
m.Update(0.05f);
|
||
Assert.False(m.HasArrived, "炮弹不能第一帧就到达");
|
||
}
|
||
|
||
[Fact]
|
||
public void GroundBased_ArrivesAtTargetPosition()
|
||
{
|
||
// 验证炮弹到达时,水平位置接近目标
|
||
var m = new MunitionEntity("m1", PlatformType.GroundBased,
|
||
AerosolType.InertGas,
|
||
startX: 0, startY: 0, startZ: 0,
|
||
targetX: 5000, targetY: 300, targetZ: 0,
|
||
muzzleVelocity: 500f, releaseAltitude: 300f);
|
||
|
||
for (int i = 0; i < 500; i++)
|
||
{
|
||
m.Update(0.05f);
|
||
if (m.HasArrived) break;
|
||
}
|
||
|
||
Assert.True(m.HasArrived, "炮弹应到达");
|
||
// 到达释放高度
|
||
Assert.True(System.Math.Abs(m.PosY - 300f) < 5f, $"PosY={m.PosY:F1} 应≈300");
|
||
// 水平位置接近目标
|
||
var dist = System.Math.Sqrt(
|
||
(m.PosX - m.TargetX) * (m.PosX - m.TargetX) +
|
||
(m.PosZ - m.TargetZ) * (m.PosZ - m.TargetZ));
|
||
Assert.True(dist < 1000f, $"到达点距目标 {dist:F0}m,应<1000m");
|
||
}
|
||
|
||
[Fact]
|
||
public void GroundBased_LaunchAngle_ReachesReleaseAltitude()
|
||
{
|
||
// 验证运动学:给定距离和初速,弹道能达到释放高度
|
||
var range = 5000f;
|
||
var v0 = 500f;
|
||
var releaseAlt = 300f;
|
||
var angle = Kinematics.CalculateLaunchAngle(range, v0, releaseAlt);
|
||
|
||
// 弹道顶点高度 >= 释放高度
|
||
var peakH = v0 * v0 * (float)System.Math.Sin(angle) * (float)System.Math.Sin(angle) / (2f * 9.81f);
|
||
Assert.True(peakH >= releaseAlt,
|
||
$"弹道顶点 {peakH:F0}m ≥ 释放高度 {releaseAlt}m, angle={angle * 180 / System.Math.PI:F1}°");
|
||
}
|
||
|
||
[Fact]
|
||
public void GroundBased_MovesForwardOverTime()
|
||
{
|
||
var m = new MunitionEntity("m1", PlatformType.GroundBased,
|
||
AerosolType.InertGas,
|
||
startX: 0, startY: 0, startZ: 0,
|
||
targetX: 1000, targetY: 300, targetZ: 0,
|
||
muzzleVelocity: 500f, releaseAltitude: 300f);
|
||
|
||
m.Update(1f);
|
||
var dist = System.Math.Sqrt(m.PosX * m.PosX + m.PosZ * m.PosZ);
|
||
Assert.True(dist > 100f, "1秒后炮弹应水平移动 > 100m");
|
||
}
|
||
|
||
[Fact]
|
||
public void AirBased_DropsToReleaseAltitude()
|
||
{
|
||
var m = new MunitionEntity("m1", PlatformType.AirBased,
|
||
AerosolType.InertGas,
|
||
startX: 0, startY: 500, startZ: 0,
|
||
targetX: 1000, targetY: 300, targetZ: 0,
|
||
muzzleVelocity: 0, releaseAltitude: 300f);
|
||
|
||
// 空基投放:自由落体 500m → 300m = 200m 下落
|
||
// h = 0.5*g*t² → t = sqrt(2*200/9.81) ≈ 6.4s
|
||
for (int i = 0; i < 500; i++)
|
||
{
|
||
m.Update(0.05f);
|
||
if (m.HasArrived) break;
|
||
}
|
||
|
||
Assert.True(m.HasArrived, "空基弹药应到达释放高度");
|
||
Assert.True(m.PosY <= 300f + 1f);
|
||
}
|
||
}
|
||
}
|