CounterDroneBackend/src/CounterDrone.Core/Simulation/MunitionEntity.cs

86 lines
3.1 KiB
C#

using CounterDrone.Core.Models;
namespace CounterDrone.Core.Simulation
{
public class MunitionEntity
{
public string Id { get; }
public PlatformType LaunchMode { get; }
public AerosolType AerosolType { get; }
public float PosX { get; private set; }
public float PosY { get; private set; }
public float PosZ { get; private set; }
public float TargetX { get; }
public float TargetY { get; }
public float TargetZ { get; }
public float ReleaseAltitude { get; }
public bool HasArrived { get; private set; }
private readonly float _muzzleVelocity;
private float _time;
private readonly float _launchAngle;
private readonly float _azimuth;
private readonly float _startX, _startY, _startZ;
public MunitionEntity(string id, PlatformType launchMode, AerosolType aerosolType,
float startX, float startY, float startZ,
float targetX, float targetY, float targetZ,
float muzzleVelocity, float releaseAltitude)
{
Id = id;
LaunchMode = launchMode;
AerosolType = aerosolType;
_startX = startX; _startY = startY; _startZ = startZ;
PosX = startX; PosY = startY; PosZ = startZ;
TargetX = targetX; TargetY = targetY; TargetZ = targetZ;
_muzzleVelocity = muzzleVelocity;
ReleaseAltitude = releaseAltitude;
// 计算发射角(简化抛物线)
var dx = targetX - startX;
var dz = targetZ - startZ;
var horizontalDist = (float)System.Math.Sqrt(dx * dx + dz * dz);
_azimuth = horizontalDist > 0 ? (float)System.Math.Atan2(dx, dz) : 0;
_launchAngle = 45f * (float)System.Math.PI / 180f;
}
public void Update(float deltaTime)
{
if (HasArrived) return;
_time += deltaTime;
if (LaunchMode == PlatformType.GroundBased)
{
// 抛物线弹道
var v0 = _muzzleVelocity;
var cosA = (float)System.Math.Cos(_launchAngle);
var sinA = (float)System.Math.Sin(_launchAngle);
var horizontalDist = v0 * cosA * _time;
PosX = _startX + horizontalDist * (float)System.Math.Sin(_azimuth);
PosZ = _startZ + horizontalDist * (float)System.Math.Cos(_azimuth);
PosY = _startY + v0 * sinA * _time - 0.5f * 9.81f * _time * _time;
if (PosY <= ReleaseAltitude)
{
PosY = ReleaseAltitude;
HasArrived = true;
}
}
else
{
// 空基投放:自由落体
PosY -= 9.81f * deltaTime;
PosX += (TargetX - PosX) * 0.1f;
PosZ += (TargetZ - PosZ) * 0.1f;
if (PosY <= ReleaseAltitude)
{
PosY = ReleaseAltitude;
HasArrived = true;
}
}
}
}
}