110 lines
3.6 KiB
C#
110 lines
3.6 KiB
C#
|
|
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);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|