774 lines
23 KiB
C#
774 lines
23 KiB
C#
using MetroGauges.General;
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Linq;
|
||
using System.Runtime.CompilerServices;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace MetroGauges.Model
|
||
{
|
||
public class CurEquiModel : DataModel
|
||
{
|
||
public CurEquiModel()
|
||
{
|
||
_r = 350;
|
||
r_v = 3000;
|
||
}
|
||
public CurEquiModel(string strPosition, string name, double x, double y)
|
||
{
|
||
StrPosition = strPosition;
|
||
Name = name;
|
||
X = x;
|
||
Y = y;
|
||
}
|
||
/// <summary>
|
||
/// 行进速度
|
||
/// </summary>
|
||
private static double v;
|
||
//public double Δq;
|
||
//public double Δw;
|
||
#region 曲线段设备限界
|
||
/// <summary>
|
||
/// 线路竖曲线半径 (m)
|
||
/// </summary>
|
||
public double R_v
|
||
{
|
||
get => r_v;
|
||
set
|
||
{
|
||
r_v = value;
|
||
if (R_v < 2000)
|
||
{
|
||
throw new ArgumentOutOfRangeException("竖曲线半径必须大于2000m。");
|
||
}
|
||
OnPropertyChanged();
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 线路平面曲线半径 (m)
|
||
/// </summary>
|
||
private static double _r;
|
||
public static Ballast c_Bal;
|
||
public static Vertical vc;
|
||
private static double _l;
|
||
private static double _a;
|
||
private static double _n;
|
||
private static double _m;
|
||
public static HorizonDirection dir;
|
||
public static NMetro nMetro;
|
||
private static double r_v;
|
||
private static double _h_ac;
|
||
public double Δ_de => 0;
|
||
public double m
|
||
{
|
||
get => _m; set { _m = value; OnPropertyChanged(); }
|
||
}
|
||
public double n { get => _n; set { _n = value; OnPropertyChanged(); } }
|
||
public double p
|
||
{
|
||
get
|
||
{
|
||
switch (nMetro)
|
||
{
|
||
case NMetro.A:
|
||
return 2.5;
|
||
case NMetro.B:
|
||
return 2.3;
|
||
default:
|
||
return double.NaN;
|
||
}
|
||
}
|
||
}
|
||
|
||
public double a { get => _a; set { _a = value; OnPropertyChanged(); } }
|
||
public double V { get => v; set { v = value; OnPropertyChanged(); } }
|
||
public double L
|
||
{
|
||
get => _l; set
|
||
{
|
||
_l = value; OnPropertyChanged();
|
||
}
|
||
}
|
||
public double R { get => _r; set { _r = value; OnPropertyChanged(); } }
|
||
public double h_ac { get => _h_ac; set { _h_ac = value; OnPropertyChanged(); } }
|
||
|
||
public override PositionI Position
|
||
{
|
||
get
|
||
{
|
||
if (StrPosition == "受电弓")
|
||
{
|
||
return PositionI.Pantograph;
|
||
}
|
||
else if (StrPosition == "车体")
|
||
{
|
||
return PositionI.Body;
|
||
}
|
||
else if (StrPosition == "转向架构架")
|
||
{
|
||
return PositionI.BogieFrame;
|
||
}
|
||
else
|
||
{
|
||
return PositionI.INVAIL;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 车体在平面曲线外侧几何偏移量(mm)
|
||
/// </summary>
|
||
public double T_a
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.Body)
|
||
{
|
||
double para = (L * L - (a * a + p * p)) / (8 * R) * 1000;
|
||
return Math.Round(para, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
}
|
||
//set
|
||
//{
|
||
// double para = (L * L - (a * a + p * p)) / (8 * R * 1000);
|
||
// double result = Math.Round(para, decimals, MidpointRounding.AwayFromZero);
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 车体在平面曲线内侧几何偏移量(mm)
|
||
/// </summary>
|
||
public double T_i
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.Body)
|
||
{
|
||
double result = (a * a + p * p) / (8 * R) * 1000;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
}
|
||
|
||
//set
|
||
//{
|
||
// double result = (a * a + p * p) / (8 * R * 1000);
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 车体在凸形竖曲线外侧几何偏移量(mm)
|
||
/// </summary>
|
||
public double _T_a
|
||
{
|
||
get
|
||
{
|
||
if (vc == Vertical.Convex)
|
||
{
|
||
double result = (4 * n * (n + a) - Squa(p)) / (8 * R_v) * 1000;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
|
||
}
|
||
|
||
//set
|
||
//{
|
||
|
||
// double para = 1000 * (4 * n * (n + a) - Squa(p)) / (8 * R_v);
|
||
// double result = Math.Round(para, decimals, MidpointRounding.AwayFromZero);
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 车体在凹形竖曲线内侧几何偏移量(mm)
|
||
/// </summary>
|
||
public double _T_i
|
||
{
|
||
get
|
||
{
|
||
if (vc == Vertical.Concave)
|
||
{
|
||
double result = (4 * n * (a - n) + Squa(p)) / (8 * R_v) * 1000;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
}
|
||
|
||
//set
|
||
//{
|
||
// double para = 1000 * (4 * n * (a - n) + Squa(p)) / (8 * R_v);
|
||
// double result = Math.Round(para, decimals, MidpointRounding.AwayFromZero);
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 转向架在平面曲线外侧几何偏移量(mm)
|
||
/// </summary>
|
||
public double T_ba
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.BogieFrame)
|
||
{
|
||
double result = m * (m + p) / (2 * R) * 1000;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
|
||
}
|
||
//set
|
||
//{
|
||
// double para = 540 * (540 + p) / (2 * R);
|
||
// double result = Math.Round(para, decimals, MidpointRounding.AwayFromZero);
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 转向架在平面曲线内侧几何偏移量(mm)
|
||
/// </summary>
|
||
public double T_bi
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.BogieFrame)
|
||
{
|
||
double result = p * p / (8 * R) * 1000;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
|
||
}
|
||
//set
|
||
//{
|
||
// double result = p * p / (8 * R * 1000);
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 曲线轨距加宽外轨分量及外轨磨耗量(mm)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public double ΔS_a
|
||
{
|
||
get
|
||
{
|
||
double result;
|
||
if (R >= 800)
|
||
{
|
||
result = 3;
|
||
}
|
||
else if (R > 110 && R < 800)
|
||
{
|
||
result = 3 + 300.0 / R;
|
||
}
|
||
else
|
||
{
|
||
result = double.NaN;
|
||
}
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
//set
|
||
//{
|
||
// double result;
|
||
// if (R >= 800)
|
||
// {
|
||
// result = 3;
|
||
// }
|
||
// else if (R > 110 && R < 800)
|
||
// {
|
||
// result = 3 + 300.0 / R;
|
||
// }
|
||
// else
|
||
// {
|
||
// result = -1;
|
||
// }
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 曲线轨距加宽内轨分量及内轨磨耗量(mm)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public double ΔS_i
|
||
{
|
||
get
|
||
{
|
||
double result;
|
||
if (R >= 800)
|
||
result = 0;
|
||
else if (R >= 110 && R < 800)
|
||
result = 300.0 / R;
|
||
else
|
||
result = double.NaN;
|
||
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
//set
|
||
//{
|
||
// double result;
|
||
// if (R >= 800)
|
||
// result = 0;
|
||
// else if (R >= 110 && R < 800)
|
||
// result = 300.0 / R;
|
||
// else
|
||
// result = -1;
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
|
||
}
|
||
/// <summary>
|
||
/// 车体由于轨道参数在整体道床曲线区段的变化引起的设备限界外侧加宽量(mm)
|
||
/// </summary>
|
||
public double ΔX_ca
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.Body)
|
||
{
|
||
double result = (ΔS_i + ΔS_a + 5) * (2 * n + a) / (2 * a) + Δ_de;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
|
||
}
|
||
//set
|
||
//{
|
||
// double para = (ΔS_i + ΔS_a + 5) * (2 * n + a) / (2 * a) + Δ_de;
|
||
// double result = Math.Round(para, decimals, MidpointRounding.AwayFromZero);
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 车体由于轨道参数在整体道床曲线区段的变化引起的设备限界内侧加宽量(mm)
|
||
/// </summary>
|
||
public double ΔX_ci
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.Body)
|
||
{
|
||
return ΔS_i + Δ_de;
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
}
|
||
//set
|
||
//{
|
||
// double result = ΔS_i + Δ_de;
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 车体由于轨道参数在碎石道床曲线区段的变化引起的设备限界外侧加宽量(mm)
|
||
/// </summary>
|
||
public double _ΔX_ca
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.Body)
|
||
{
|
||
double result = (ΔS_i + ΔS_a + 5) * (2 * n + a) / (2 * a) + 1000 / R + Δ_de;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
}
|
||
//set
|
||
//{
|
||
// double para = (ΔS_i + ΔS_a + 5) * (2 * n + a) / (2 * a) + 1000 / R + Δ_de;
|
||
// double result = Math.Round(para, decimals, MidpointRounding.AwayFromZero);
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 车体由于轨道参数在碎石道床曲线区段的变化引起的设备限界内侧加宽量(mm)
|
||
/// </summary>
|
||
public double _ΔX_ci
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.Body)
|
||
{
|
||
double result = ΔS_i + 1000 / R + Δ_de;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
else
|
||
{
|
||
return double.NaN;
|
||
}
|
||
}
|
||
//set
|
||
//{
|
||
// double result = ΔS_i + 1000 / R + Δ_de;
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 转向架由于轨道参数在整体道床曲线区段的变化引起的设备限界外侧加宽量(mm)
|
||
/// </summary>
|
||
public double ΔX_cat
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.BogieFrame)
|
||
{
|
||
double result = (ΔS_i + ΔS_a) * (2 * m + p) / (2 * p) + Δ_de;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
return double.NaN;
|
||
}
|
||
//set
|
||
//{
|
||
// double result = (ΔS_i + ΔS_a) * (2 * m + p) / (2 * p) + Δ_de;
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 转向架由于轨道参数在整体道床曲线区段的变化引起的设备限界内侧加宽量(mm)
|
||
/// </summary>
|
||
public double ΔX_cit
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.BogieFrame)
|
||
{
|
||
return ΔS_i + Δ_de;
|
||
}
|
||
return double.NaN;
|
||
}
|
||
//set
|
||
//{
|
||
// double result = ΔS_i + Δ_de;
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 转向架由于轨道参数在碎石道床曲线区段的变化引起的设备限界外侧加宽量(mm)
|
||
/// </summary>
|
||
public double _ΔX_cat
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.BogieFrame)
|
||
{
|
||
double result = (ΔS_i + ΔS_a) * (2 * m + p) / (2 * p) + 1000 / R + Δ_de;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
return double.NaN;
|
||
}
|
||
//set
|
||
//{
|
||
// double result = (ΔS_i + ΔS_a) * (2 * m + p) / (2 * p) + 1000 / R + Δ_de;
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 转向架由于轨道参数在碎石道床曲线区段的变化引起的设备限界内侧加宽量(mm)
|
||
/// </summary>
|
||
public double _ΔX_cit
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.BogieFrame)
|
||
{
|
||
double result = ΔS_i + (1000 / R) + Δ_de;
|
||
return Math.Round(result, decimals, MidpointRounding.AwayFromZero);
|
||
}
|
||
return double.NaN;
|
||
}
|
||
//set
|
||
//{
|
||
// double result = ΔS_i + 1000 / R + Δ_de;
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 车体设备限界在曲线地段外侧总加宽量(mm)
|
||
/// </summary>
|
||
public double ΔX_a
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.Body)
|
||
{
|
||
switch (c_Bal)
|
||
{
|
||
case Ballast.Monolithic:
|
||
return T_a + ΔX_ca;
|
||
case Ballast.Gravel:
|
||
return T_a + _ΔX_ca;
|
||
default:
|
||
return double.NaN;
|
||
}
|
||
}
|
||
return double.NaN;
|
||
}
|
||
//set
|
||
//{
|
||
// double result;
|
||
// switch (c_Bal)
|
||
// {
|
||
// case Ballast.Monolithic:
|
||
// result = T_a + ΔX_ca;
|
||
// break;
|
||
// case Ballast.Gravel:
|
||
// result = T_a + _ΔX_ca;
|
||
// break;
|
||
// default:
|
||
// result = -1;
|
||
// break;
|
||
// }
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
|
||
}
|
||
/// <summary>
|
||
/// 车体设备限界在曲线地段内侧总加宽量(mm)
|
||
/// </summary>
|
||
public double ΔX_i
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.Body)
|
||
{
|
||
switch (c_Bal)
|
||
{
|
||
case Ballast.Monolithic:
|
||
return T_i + ΔX_ci;
|
||
case Ballast.Gravel:
|
||
return T_i + _ΔX_ci;
|
||
default:
|
||
return double.NaN;
|
||
}
|
||
}
|
||
return double.NaN;
|
||
}
|
||
//set
|
||
//{
|
||
// double result;
|
||
// switch (c_Bal)
|
||
// {
|
||
// case Ballast.Monolithic:
|
||
// result = T_i + ΔX_ci;
|
||
// break;
|
||
// case Ballast.Gravel:
|
||
// result = T_i + _ΔX_ci;
|
||
// break;
|
||
// default:
|
||
// result = -1;
|
||
// break;
|
||
// }
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 车体设备限界在曲线地段总加高量(mm)
|
||
/// </summary>
|
||
public double ΔY_jg
|
||
{
|
||
get
|
||
{
|
||
if (Position== PositionI.Body)
|
||
{
|
||
switch (vc)
|
||
{
|
||
case Vertical.Convex:
|
||
return _T_a;
|
||
case Vertical.Concave:
|
||
return _T_i;
|
||
default:
|
||
return double.NaN;
|
||
}
|
||
}
|
||
return double.NaN;
|
||
}
|
||
//set
|
||
//{
|
||
// double result;
|
||
// switch (vc)
|
||
// {
|
||
// case Vertical.Convex:
|
||
// result = _T_a;
|
||
// break;
|
||
// case Vertical.Concave:
|
||
// result = _T_i;
|
||
// break;
|
||
// default:
|
||
// result = -1;
|
||
// break;
|
||
// }
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
|
||
}
|
||
/// <summary>
|
||
/// 转向架设备限界在曲线地段外侧总加宽量(mm)
|
||
/// </summary>
|
||
public double ΔX_at
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.BogieFrame)
|
||
{
|
||
switch (c_Bal)
|
||
{
|
||
case Ballast.Monolithic:
|
||
return T_ba + ΔX_cat;
|
||
case Ballast.Gravel:
|
||
return T_ba + _ΔX_cat;
|
||
default:
|
||
return double.NaN;
|
||
}
|
||
}
|
||
return double.NaN;
|
||
}
|
||
//set
|
||
//{
|
||
// double result;
|
||
// switch (c_Bal)
|
||
// {
|
||
// case Ballast.Monolithic:
|
||
// result = T_ba + ΔX_cat;
|
||
// break;
|
||
// case Ballast.Gravel:
|
||
// result = T_ba + _ΔX_cat;
|
||
// break;
|
||
// default:
|
||
// result = -1;
|
||
// break;
|
||
// }
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 转向架设备限界在曲线地段内侧总加宽量(mm)
|
||
/// </summary>
|
||
public double ΔX_it
|
||
{
|
||
get
|
||
{
|
||
if (Position == PositionI.BogieFrame)
|
||
{
|
||
switch (c_Bal)
|
||
{
|
||
case Ballast.Monolithic:
|
||
return T_bi + ΔX_cit;
|
||
case Ballast.Gravel:
|
||
return T_bi + _ΔX_cit;
|
||
default:
|
||
return double.NaN;
|
||
}
|
||
}
|
||
return Double.NaN;
|
||
}
|
||
//set
|
||
//{
|
||
// double result;
|
||
// switch (c_Bal)
|
||
// {
|
||
// case Ballast.Monolithic:
|
||
// result = T_bi + ΔX_cit;
|
||
// break;
|
||
// case Ballast.Gravel:
|
||
// result = T_bi + _ΔX_cit;
|
||
// break;
|
||
// default:
|
||
// result = -1;
|
||
// break;
|
||
// }
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 对称时车体横向总加宽量
|
||
/// </summary>
|
||
public double ΔX
|
||
{
|
||
get
|
||
{
|
||
return ΔX_a > ΔX_i ? ΔX_a : ΔX_i;
|
||
}
|
||
//set
|
||
//{
|
||
// double result = ΔX_a > ΔX_i ? ΔX_a : ΔX_i;
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 对称时车体横向总加宽量
|
||
/// </summary>
|
||
public double ΔX_t
|
||
{
|
||
get
|
||
{
|
||
return ΔX_at > ΔX_it ? ΔX_at : ΔX_it;
|
||
}
|
||
//set
|
||
//{
|
||
// double result = ΔX_a > ΔX_i ? ΔX_a : ΔX_i;
|
||
// result = value;
|
||
// OnPropertyChanged();
|
||
//}
|
||
}
|
||
#endregion
|
||
public static CurEquiModel Copy(CurEquiModel lieq)
|
||
{
|
||
return new CurEquiModel(lieq.StrPosition, lieq.Name, lieq.X, lieq.Y);
|
||
}
|
||
|
||
}
|
||
}
|