using System; using System.Globalization; namespace Assets.Scenes.Ride.Scripts { public class Helper { /// /// 计算速度 /// 参考 http://bikecalculator.com/index.html /// /// 海拔 /// 坡度% /// 功率 /// 体重 /// 自行车重量 /// km/h public static double CalculateSpeed(double elevationv, double gradev, double powerv, double rweightv, double bweightv) { if (powerv < 0) { return 0; } if (gradev < -10) { gradev = -10; } var tireValues = new double[] { 0.005, 0.004, 0.012 }; var aeroValues = new double[] { 0.388, 0.445, 0.420, 0.300, 0.233, 0.200 }; var units = 0; //温度 var temperaturev = 25; //海拔 //var elevationv = 100; //坡度 //var gradev = 6 * 0.01 * -1; //风,转换成m/s var headwindv = 0 / 3.6; var frontalArea = aeroValues[0]; var transv = 0.95; // no one knows what this is, so why bother presenting a choice? var rollingRes = tireValues[0]; //应该是空气密度 var density = (1.293 - 0.00426 * temperaturev) * Math.Exp(-elevationv / 7000.0); //全空气阻力参数 var a2 = 0.5 * frontalArea * density; // full air resistance parameter var twt = 9.8 * (rweightv + bweightv); // total weight in newtons var tres = twt * (gradev * 0.01 + rollingRes); // gravity and rolling resistance //var powerv = 195; var v = Newton(a2, headwindv, tres, transv, powerv) * 3.6;// convert to km/h //Trace.WriteLine($"速度为:{ v }"); var t1 = makeDecimal2(v * (units == 1 ? 1.609 : 1.0)); return double.Parse(t1, CultureInfo.InvariantCulture); } private static double Newton(double aero, double hw, double tr, double tran, double p) { var vel = 20D; var MAX = 10; var TOL = 0.05; for (int i = 0; i < MAX; i++) { var tv = vel + hw; var aeroEff = (tv > 0.0) ? aero : -aero; // wind in face, must reverse effect var f = vel * (aeroEff * tv * tv + tr) - tran * p; // the function var fp = aeroEff * (3.0 * vel + hw) * tv + tr; // the derivative var vNew = vel - f / fp; if (Math.Abs(vNew - vel) < TOL) { return vNew; // success } vel = vNew; } return 0.0; } private static string makeDecimal2(double value) { if (value != 0) { var x = Math.Round(value * 100); int d; if (x < 100) { d = 0; } else { d = Convert.ToInt32(Math.Floor(x / 100), CultureInfo.InvariantCulture); }; var c = x % 100; var g = (c >= 10) ? "" : "0"; return "" + d + "." + g + c; } return value.ToString(CultureInfo.InvariantCulture); } } }