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; } } } } }