1 using System; 2 3 namespace TrainManager.Power 4 { 5 /// <summary>An abstract acceleration curve</summary> 6 public abstract class AccelerationCurve 7 { 8 /// <summary>Gets the acceleration output for this curve</summary> 9 /// <param name="Speed">The current speed</param> 10 /// <param name="Loading">A double between 0 (Unloaded) and 1.0 (Loaded) representing the load factor</param> 11 /// <returns>The acceleration output</returns> GetAccelerationOutput(double Speed, double Loading)12 public abstract double GetAccelerationOutput(double Speed, double Loading); 13 14 /// <summary>Gets the maximum possible acceleration output for this curve</summary> 15 // ReSharper disable once UnusedMemberInSuper.Global 16 public abstract double MaximumAcceleration 17 { 18 get; 19 } 20 } 21 22 /// <summary>Represents a BVE2 / BVE4 format Acceleration Curve</summary> 23 public class BveAccelerationCurve : AccelerationCurve 24 { 25 public double StageZeroAcceleration; 26 public double StageOneSpeed; 27 public double StageOneAcceleration; 28 public double StageTwoSpeed; 29 public double StageTwoExponent; 30 public double Multiplier; 31 GetAccelerationOutput(double Speed, double Loading)32 public override double GetAccelerationOutput(double Speed, double Loading) 33 { 34 if (Speed <= 0.0) 35 { 36 return Multiplier * this.StageZeroAcceleration; 37 } 38 39 if (Speed < this.StageOneSpeed) 40 { 41 double t = Speed / this.StageOneSpeed; 42 return Multiplier * (this.StageZeroAcceleration * (1.0 - t) + this.StageOneAcceleration * t); 43 } 44 45 if (Speed < this.StageTwoSpeed) 46 { 47 return Multiplier * this.StageOneSpeed * this.StageOneAcceleration / Speed; 48 } 49 50 return Multiplier * this.StageOneSpeed * this.StageOneAcceleration * Math.Pow(this.StageTwoSpeed, this.StageTwoExponent - 1.0) * Math.Pow(Speed, -this.StageTwoExponent); 51 } 52 53 public override double MaximumAcceleration => Math.Max(StageZeroAcceleration, StageOneAcceleration); 54 Clone(double multiplier)55 public BveAccelerationCurve Clone(double multiplier) 56 { 57 return new BveAccelerationCurve 58 { 59 StageZeroAcceleration = this.StageZeroAcceleration, 60 StageOneSpeed = this.StageOneSpeed, 61 StageOneAcceleration = this.StageOneAcceleration, 62 StageTwoSpeed = this.StageTwoSpeed, 63 StageTwoExponent = this.StageTwoExponent, 64 Multiplier = multiplier 65 }; 66 } 67 } 68 69 public class BveDecelerationCurve : AccelerationCurve 70 { 71 private readonly double MaxDecelerationOutput; 72 GetAccelerationOutput(double Speed, double Loading)73 public override double GetAccelerationOutput(double Speed, double Loading) 74 { 75 return this.MaxDecelerationOutput; 76 } 77 78 public override double MaximumAcceleration => MaxDecelerationOutput; 79 BveDecelerationCurve(double Deceleration)80 public BveDecelerationCurve(double Deceleration) 81 { 82 this.MaxDecelerationOutput = Deceleration; 83 } 84 } 85 } 86