public Lut Optimize(double threshold = 0.07) { if (Count < 3) { return(new Lut(this)); } var optimized = new Lut { this[0] }; var offset = 1; for (var i = 1; i < Count - 1; i++) { var current = this[i]; var coefficient = 1 - GetTangent(current, this[i + 1]) / GetTangent(this[i - offset], current); if (double.IsInfinity(coefficient) || double.IsNaN(coefficient) || Math.Abs(coefficient) > threshold) { optimized.Add(current); offset = 1; } else { offset++; } } optimized.Add(this[Count - 1]); return(optimized); }
public Lut Select(SelectPoint callback, int detalization = 100, bool linearInterpolation = true) { var result = new Lut(); ForEach((x, y) => { result.Add(callback(x, y)); }, detalization, linearInterpolation); return(result); }
public Lut Transform(Func <LutPoint, LutPoint> fn) { var result = new Lut(Count); for (var i = 0; i < Count; i++) { var point = this[i]; result.Add(fn(point)); } return(result); }
public Lut TransformHorizontally(Func <LutPoint, double> fn) { var result = new Lut(Count); for (var i = 0; i < Count; i++) { var point = this[i]; result.Add(new LutPoint(fn(point), point.Y)); } return(result); }
public static Lut FromValue([NotNull, LocalizationRequired(false)] string value) { var capacity = 0; for (var i = 1; i < value.Length; i++) { if (value[i] == '=') { capacity++; } } var result = new Lut(capacity); if (value.Length > 2 && value[0] == '(' && value[value.Length - 1] == ')') { var j = 1; double?key = null; for (var i = 1; i < value.Length; i++) { switch (value[i]) { case '|': case ')': if (i > j && key.HasValue) { result.Add(new LutPoint(key.Value, FlexibleParser.ParseDouble(value.Substring(j, i - j), 0d))); key = null; } j = i + 1; break; case '=': if (i > j) { key = FlexibleParser.ParseDouble(value.Substring(j, i - j), 0d); } j = i + 1; break; } } } return(result); }
public static Lut PowerToTorque(Lut torque, int detalization = 100) { torque.UpdateBoundingBox(); var startFrom = torque.MinX; var limit = torque.MaxX; var result = new Lut(); var previousTorquePoint = 0; var previousRpm = 0d; for (var i = 0; i <= detalization; i++) { var rpm = detalization == 0 ? limit : (limit - startFrom) * i / detalization + startFrom; for (var j = previousTorquePoint; j < torque.Count; j++) { var p = torque[j]; if (p.X > rpm) { previousTorquePoint = j > 0 ? j - 1 : 0; break; } if ((i == 0 || p.X > previousRpm) && p.X < rpm) { result.Add(new LutPoint(p.X, PowerToTorque(p.Y, p.X))); } } result.Add(new LutPoint(rpm, PowerToTorque(torque.InterpolateLinear(rpm), rpm))); previousRpm = rpm; } return(Result(result)); }
public static void ConsiderTurbo(IReadOnlyList <TurboDescription> turbo, Lut torqueValues) { torqueValues.TransformSelf(x => ConsiderTurbo(turbo, x.X, x.Y)); }
private static Lut Result(Lut v) { v = v.Optimize(); v.UpdateBoundingBox(); return(v); }
public static Lut LoadCarTorque([NotNull] IDataWrapper data, bool considerLimiter = true, int detalization = 100) { /* read torque curve and engine params */ var torqueFile = data.GetLutFile("power.lut"); if (torqueFile.IsEmptyOrDamaged()) { throw new FileNotFoundException("Cannot load power.lut", "data/power.lut"); } var engine = data.GetIniFile("engine.ini"); if (engine.IsEmptyOrDamaged()) { throw new FileNotFoundException("Cannot load engine.ini", "data/engine.ini"); } /* prepare turbos and read controllers */ var turbos = ReadTurbos(engine); for (var i = 0; i < turbos.Count; i++) { turbos[i].Controllers = ReadControllers(data.GetIniFile($"ctrl_turbo{i}.ini")); } /* prepare torque curve and limits */ var torque = torqueFile.Values; torque.UpdateBoundingBox(); var limit = considerLimiter && engine.ContainsKey("ENGINE_DATA") ? engine["ENGINE_DATA"].GetDouble("LIMITER", torque.MaxX) : torque.MaxX; var startFrom = considerLimiter ? 0d : torque.MinX; /* build smoothed line */ var result = new Lut(); var previousTorquePoint = 0; var previousRpm = 0d; for (var i = 0; i <= detalization; i++) { var rpm = detalization == 0 ? limit : (limit - startFrom) * i / detalization + startFrom; for (var j = previousTorquePoint; j < torque.Count; j++) { var p = torque[j]; if (p.X > rpm) { previousTorquePoint = j > 0 ? j - 1 : 0; break; } if ((i == 0 || p.X > previousRpm) && p.X < rpm && p.X >= 0) { result.Add(new LutPoint(p.X, ConsiderTurbo(turbos, p.X, p.Y))); } } var baseTorque = torque.InterpolateLinear(rpm); result.Add(new LutPoint(rpm, ConsiderTurbo(turbos, rpm, baseTorque))); previousRpm = rpm; } return(Result(result)); }
public static Lut PowerToTorque(Lut torque, int detalization = 100) { return(Result(torque.Select((x, y) => new LutPoint(x, PowerToTorque(y, x)), detalization))); }