88 lines
3.1 KiB
C#
88 lines
3.1 KiB
C#
using CounterDrone.Core.Algorithms;
|
|
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;
|
|
|
|
private bool _hasExceededReleaseAltitude;
|
|
|
|
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.001f ? (float)System.Math.Atan2(dx, dz) : 0;
|
|
|
|
_launchAngle = Kinematics.CalculateLaunchAngle(horizontalDist, muzzleVelocity, releaseAltitude);
|
|
}
|
|
|
|
public void Update(float deltaTime)
|
|
{
|
|
if (HasArrived) return;
|
|
_time += deltaTime;
|
|
|
|
if (LaunchMode == PlatformType.GroundBased)
|
|
{
|
|
(float x, float y, float z) = Kinematics.ParabolicPosition(
|
|
_startX, _startY, _startZ, _launchAngle, _azimuth, _muzzleVelocity, _time);
|
|
PosX = x; PosY = y; PosZ = z;
|
|
|
|
// 必须先从上方越过释放高度,再回落时才触发
|
|
if (PosY > ReleaseAltitude)
|
|
_hasExceededReleaseAltitude = true;
|
|
|
|
if (_hasExceededReleaseAltitude && 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|