2021-03-23 16:07:31 +08:00

110 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Globalization;
namespace Assets.Scenes.Ride.Scripts
{
public class Helper
{
/// <summary>
/// 计算速度
/// 参考 http://bikecalculator.com/index.html
/// </summary>
/// <param name="elevationv">海拔</param>
/// <param name="gradev">坡度%</param>
/// <param name="powerv">功率</param>
/// <param name="rweightv">体重</param>
/// <param name="bweightv">自行车重量</param>
/// <returns>km/h</returns>
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);
}
}
}