| | | 1 | | using System; |
| | | 2 | | using System.Collections.Generic; |
| | | 3 | | using UnityEngine; |
| | | 4 | | |
| | | 5 | | // Base implementation of a launch angle interpolator. |
| | | 6 | | // |
| | | 7 | | // The interpolator determines the optimal launch angle and the time-to-target given the horizontal |
| | | 8 | | // distance and altitude of the target. |
| | | 9 | | public abstract class LaunchAngleInterpolatorBase : LaunchAnglePlannerBase { |
| | | 10 | | // Launch angle data interpolator. |
| | | 11 | | protected IInterpolator2D _interpolator; |
| | | 12 | | |
| | 42 | 13 | | public LaunchAngleInterpolatorBase(IAgent agent) : base(agent) {} |
| | | 14 | | |
| | | 15 | | // Calculate the optimal launch angle in degrees and the time-to-target in seconds. |
| | 0 | 16 | | public override LaunchAngleOutput Plan(in LaunchAngleInput input) { |
| | 0 | 17 | | if (_interpolator == null) { |
| | 0 | 18 | | InitInterpolator(); |
| | 0 | 19 | | } |
| | | 20 | | |
| | 0 | 21 | | Interpolator2DDataPoint interpolatedDataPoint = |
| | | 22 | | _interpolator.Interpolate(input.Distance, input.Altitude); |
| | 0 | 23 | | if (interpolatedDataPoint == null || interpolatedDataPoint.Data == null || |
| | 0 | 24 | | interpolatedDataPoint.Data.Count < 2) { |
| | 0 | 25 | | throw new InvalidOperationException("Interpolator returned invalid data."); |
| | | 26 | | } |
| | | 27 | | |
| | 0 | 28 | | return new LaunchAngleOutput { LaunchAngle = interpolatedDataPoint.Data[0], |
| | | 29 | | TimeToPosition = interpolatedDataPoint.Data[1] }; |
| | 0 | 30 | | } |
| | | 31 | | |
| | | 32 | | // Return the absolute intercept position given the absolute target position. |
| | 0 | 33 | | public override Vector3 InterceptPosition(in Vector3 targetPosition) { |
| | 0 | 34 | | if (_interpolator == null) { |
| | 0 | 35 | | InitInterpolator(); |
| | 0 | 36 | | } |
| | | 37 | | |
| | 0 | 38 | | Direction direction = ConvertToRelativeDirection(targetPosition); |
| | 0 | 39 | | Interpolator2DDataPoint interpolatedDataPoint = |
| | | 40 | | _interpolator.Interpolate(direction.Distance, direction.Altitude); |
| | 0 | 41 | | if (interpolatedDataPoint == null || interpolatedDataPoint.Data == null || |
| | 0 | 42 | | interpolatedDataPoint.Data.Count < 2) { |
| | 0 | 43 | | throw new InvalidOperationException("Interpolator returned invalid data."); |
| | | 44 | | } |
| | | 45 | | |
| | 0 | 46 | | Vector3 relativePosition = targetPosition - Agent.Position; |
| | 0 | 47 | | Vector3 cylindricalRelativePosition = |
| | | 48 | | Coordinates3.ConvertCartesianToCylindrical(relativePosition); |
| | 0 | 49 | | return Coordinates3.ConvertCylindricalToCartesian( |
| | | 50 | | r: interpolatedDataPoint.Coordinates[0], azimuth: cylindricalRelativePosition.y, |
| | | 51 | | height: interpolatedDataPoint.Coordinates[1]) + |
| | | 52 | | Agent.Position; |
| | 0 | 53 | | } |
| | | 54 | | |
| | | 55 | | // Initialize the interpolator. |
| | | 56 | | protected abstract void InitInterpolator(); |
| | | 57 | | } |