namespace IStation.Curve
|
{
|
/// <summary>
|
///
|
/// </summary>
|
public partial class CurveCoordinate
|
{
|
#region 计算显示参数方法
|
|
#region 默认
|
/// <summary>
|
/// 最大流量(显示参数)
|
/// </summary>
|
public double DispMaxQ()
|
{
|
return this.CoordMinQ + (double)this.GridNumberX * this.CoordSpaceQ;
|
}
|
|
/// <summary>
|
/// 最小扬程(显示参数)
|
/// </summary>
|
public double DispMinH()
|
{
|
return this.CoordMinH + (double)this.StartLineNoH * this.CoordSpaceH;
|
}
|
|
/// <summary>
|
/// 最大扬程(显示参数)
|
/// </summary>
|
public double DispMaxH()
|
{
|
return CoordMinH + (double)this.EndLineNoH * this.CoordSpaceH;
|
}
|
|
/// <summary>
|
/// 最小效率(显示参数)
|
/// </summary>
|
public double DispMinE()
|
{
|
return this.CoordMinE + (double)this.StartLineNoE * this.CoordSpaceE;
|
}
|
|
/// <summary>
|
/// 最大效率(显示参数)
|
/// </summary>
|
public double DispMaxE()
|
{
|
return this.CoordMinE + (double)this.EndLineNoE * this.CoordSpaceE;
|
}
|
|
/// <summary>
|
/// 最小功率(显示参数)
|
/// </summary>
|
public double DispMinP()
|
{
|
return this.CoordMinP + (double)this.StartLineNoP * this.CoordSpaceP;
|
}
|
|
/// <summary>
|
/// 最大功率(显示参数)
|
/// </summary>
|
public double DispMaxP()
|
{
|
return this.CoordMinP + (double)this.EndLineNoP * this.CoordSpaceP;
|
}
|
|
#endregion
|
|
/// <summary>
|
/// 重置扬程坐标
|
/// </summary>
|
public void ResetCoordH(double space, double disMinH, double disMaxH)
|
{
|
this.CoordSpaceH = space;
|
this.EndLineNoH = this.GridNumberY;
|
this.StartLineNoH = this.EndLineNoH - (int)((disMaxH - disMinH) / this.CoordSpaceH);
|
this.CoordMinH = disMaxH - (double)this.EndLineNoH * this.CoordSpaceH;
|
}
|
#endregion
|
|
#region 计算坐标
|
|
/// <summary>
|
/// 计算坐标
|
/// </summary>
|
/// <param name="QH">流量扬程线</param>
|
/// <param name="QE">流量效率线</param>
|
/// <param name="QP">流量功率线</param>
|
/// <returns></returns>
|
public static CurveCoordinate CalcCoordinate(CurveExpress QH, CurveExpress QE, CurveExpress QP)
|
{
|
if (QH == null)
|
return null;
|
|
List<CurvePoint> pointsQH = QH.GetFitPoints(20);
|
List<CurvePoint> pointsQE = null;
|
if (QE != null)
|
pointsQE = QE.GetFitPoints(20);
|
List<CurvePoint> pointsQP = null;
|
if (QP != null)
|
pointsQP = QP.GetFitPoints(20);
|
|
return CalcCoordinate(pointsQH, pointsQE, pointsQP);
|
}
|
|
/// <summary>
|
/// 计算坐标
|
/// </summary>
|
/// <param name="QH">流量扬程线</param>
|
/// <param name="QE">流量效率线</param>
|
/// <param name="QP">流量功率线</param>
|
/// <returns></returns>
|
public static CurveCoordinate CalcCoordinate(List<CurvePoint> QH, List<CurvePoint> QE, List<CurvePoint> QP)
|
{
|
if (QH == null)
|
return null;
|
double maxQ = 0.0;
|
double minQ = 1000.0;
|
double maxH = 0.0;
|
double minH = 1000.0;
|
double maxE = 0.0;
|
double minE = 1000.0;
|
double maxP = 0.0;
|
double minP = 1000.0;
|
|
if (QE == null && QP == null)
|
{
|
minQ = QH.Min(x => x.X);
|
maxQ = QH.Max(x => x.X);
|
if (minQ > maxQ)
|
{
|
return null;
|
}
|
minH = QH.Min(x => x.Y);
|
maxH = QH.Max(x => x.Y);
|
if (minH > maxH)
|
{
|
return null;
|
}
|
}
|
else
|
{
|
CalcMinMaxValue(QH, QE, QP, ref maxQ, ref minQ, ref maxH, ref minH, ref maxE, ref minE, ref maxP, ref minP);
|
}
|
|
return CalcCoordinate(minQ, maxQ, minH, maxH, minE, maxE, minP, maxP);
|
}
|
|
/// <summary>
|
/// 计算最大最小值
|
/// </summary>
|
/// <param name="QH">流量扬程线</param>
|
/// <param name="QE">流量效率线</param>
|
/// <param name="QP">流量功率线</param>
|
/// <param name="maxQ">最大流量</param>
|
/// <param name="minQ">最小流量</param>
|
/// <param name="maxH">最大扬程</param>
|
/// <param name="minH">最小扬程</param>
|
/// <param name="maxE">最大效率</param>
|
/// <param name="minE">最小效率</param>
|
/// <param name="maxP">最大功率</param>
|
/// <param name="minP">最小功率</param>
|
/// <returns></returns>
|
public static bool CalcMinMaxValue(List<CurvePoint> QH, List<CurvePoint> QE, List<CurvePoint> QP, ref double maxQ, ref double minQ, ref double maxH, ref double minH, ref double maxE, ref double minE, ref double maxP, ref double minP)
|
{
|
maxQ = 0.0;
|
minQ = 1000.0;
|
maxH = 0.0;
|
minH = 1000.0;
|
maxE = 0.0;
|
minE = 1000.0;
|
maxP = 0.0;
|
minP = 1000.0;
|
if (QH == null)
|
{
|
return false;
|
}
|
minQ = QH.Min(x => x.X);
|
maxQ = QH.Max(x => x.X);
|
if (minQ > maxQ)
|
{
|
return false;
|
}
|
minH = QH.Min(x => x.Y);
|
maxH = QH.Max(x => x.Y);
|
if (QE != null && QE.Count > 0)
|
{
|
minE = QE.Min(x => x.Y);
|
maxE = QE.Max(x => x.Y);
|
}
|
if (QP != null && QP.Count > 0)
|
{
|
minP = QP.Min(x => x.Y);
|
maxP = QP.Max(x => x.Y);
|
}
|
return true;
|
}
|
|
/// <summary>
|
/// 计算坐标
|
/// </summary>
|
/// <param name="minQ">最小流量</param>
|
/// <param name="maxQ">最大流量</param>
|
/// <param name="minH">最小扬程</param>
|
/// <param name="maxH">最大扬程</param>
|
/// <param name="minE">最小效率</param>
|
/// <param name="maxE">最大效率</param>
|
/// <param name="minP">最小功率</param>
|
/// <param name="maxP">最大功率</param>
|
/// <returns></returns>
|
public static CurveCoordinate CalcCoordinate(double minQ, double maxQ, double minH, double maxH, double minE, double maxE, double minP, double maxP)
|
{
|
if (minQ > maxQ - 0.01)
|
return null;
|
|
if (minH > maxH - 0.01)
|
return null;
|
|
var validGridNumH = 6;
|
var coordinateParas = new CurveCoordinate();
|
coordinateParas.GridNumberX = 10;
|
coordinateParas.GridNumberY = 18;
|
CalcCoordinateQ(minQ, maxQ, ref coordinateParas, coordinateParas.GridNumberX);
|
CalcCoordinateH(minH, maxH, validGridNumH, ref coordinateParas, out double disMinH, out double disMaxH);
|
|
if (maxP > minP + 0.01)
|
CalcCoordinateP(minP, maxP, disMaxH, 0, ref coordinateParas);
|
|
if (maxE > minE + 0.01)
|
CalcCoordinateE(minE, maxE, ref coordinateParas);
|
|
return coordinateParas;
|
}
|
|
#endregion
|
|
#region 计算对应线坐标
|
|
/// <summary>
|
/// 计算流量坐标
|
/// </summary>
|
/// <param name="minQ">最小流量</param>
|
/// <param name="maxQ">最大流量</param>
|
/// <param name="coordinateParas">坐标Model</param>
|
/// <param name="validGridNum">有效刻度点</param>
|
/// <param name="default_num">放大系数</param>
|
public static void CalcCoordinateQ(double minQ, double maxQ, ref CurveCoordinate coordinateParas, int validGridNum = 10, double default_num = 1.0)
|
{
|
var coordSpaceQ = GetOptimalSpaceMin(minQ / default_num, maxQ / default_num, validGridNum, out double disMinQ, out double disMaxQ) * default_num;
|
coordSpaceQ = Math.Max(0.5, coordSpaceQ / default_num) * default_num;
|
if (coordSpaceQ == 8.0)
|
coordSpaceQ = 10.0;
|
|
disMinQ *= default_num;
|
//disMaxQ *= default_num;
|
var gridNumberX = 0;
|
|
double min_q = disMinQ;
|
while (min_q < maxQ)
|
{
|
gridNumberX++;
|
min_q = disMinQ + gridNumberX * coordSpaceQ;
|
}
|
|
if (gridNumberX <= 5)
|
{
|
coordSpaceQ *= 0.5;
|
gridNumberX *= 2;
|
}
|
|
coordinateParas.CoordSpaceQ = coordSpaceQ;
|
coordinateParas.CoordMinQ = disMinQ;
|
coordinateParas.GridNumberX = gridNumberX;
|
}
|
|
/// <summary>
|
/// 计算扬程坐标 含过滤 (Eventech: CalcCoordinateH2)
|
/// </summary>
|
/// <param name="minH">最小扬程</param>
|
/// <param name="maxH">最大扬程</param>
|
/// <param name="validGridNumH">有效扬程刻度数</param>
|
/// <param name="coordinateParas">坐标Model</param>
|
/// <param name="disMinH">最小显示扬程</param>
|
/// <param name="disMaxH">最大显示扬程</param>
|
public static void CalcCoordinateH_Filter(double minH, double maxH, int validGridNumH, ref CurveCoordinate coordinateParas, out double disMinH, out double disMaxH)
|
{
|
if (maxH < 1.0)
|
{
|
disMinH = 0.0;
|
disMaxH = 1.0;
|
coordinateParas.ResetCoordH(0.1, disMinH, disMaxH);
|
}
|
else if (maxH < 2.0)
|
{
|
disMinH = 0.0;
|
disMaxH = 2.0;
|
coordinateParas.ResetCoordH(0.2, disMinH, disMaxH);
|
}
|
else if (maxH < 5.0)
|
{
|
disMinH = 0.0;
|
disMaxH = 5.0;
|
coordinateParas.ResetCoordH(0.5, disMinH, disMaxH);
|
}
|
else if (maxH < 10.0)
|
{
|
disMinH = 0.0;
|
disMaxH = 10.0;
|
coordinateParas.ResetCoordH(1.0, disMinH, disMaxH);
|
}
|
else if (maxH < 12.0)
|
{
|
coordinateParas.CoordSpaceH = 1.0;
|
disMinH = 0.0;
|
disMaxH = 12.0;
|
coordinateParas.ResetCoordH(1.0, disMinH, disMaxH);
|
}
|
else if (maxH < 15.0)
|
{
|
coordinateParas.CoordSpaceH = 2.0;
|
disMinH = 0.0;
|
disMaxH = 16.0;
|
coordinateParas.ResetCoordH(2.0, disMinH, disMaxH);
|
}
|
else if (maxH < 20.0)
|
{
|
coordinateParas.CoordSpaceH = 2.0;
|
disMinH = 0.0;
|
disMaxH = 20.0;
|
coordinateParas.ResetCoordH(2.0, disMinH, disMaxH);
|
}
|
else
|
{
|
CalcCoordinateH(minH, maxH, validGridNumH, ref coordinateParas, out disMinH, out disMaxH);
|
}
|
}
|
|
/// <summary>
|
/// 计算扬程坐标
|
/// </summary>
|
/// <param name="minH">最小扬程</param>
|
/// <param name="maxH">最大扬程</param>
|
/// <param name="validGridNumH">有效扬程刻度数</param>
|
/// <param name="coordinateParas">坐标Model</param>
|
/// <param name="disMinH">最小显示扬程</param>
|
/// <param name="disMaxH">最大显示扬程</param>
|
public static void CalcCoordinateH(double minH, double maxH, int validGridNumH, ref CurveCoordinate coordinateParas, out double disMinH, out double disMaxH)
|
{
|
var coordSpaceH = GetOptimalSpaceMax(minH, maxH, validGridNumH, out disMinH, out disMaxH);
|
int endLineNoH = coordinateParas.GridNumberY;
|
int stratLineNoH = endLineNoH;
|
|
double max_h = disMaxH;//判断条件
|
while (max_h > minH * 0.98)
|
{
|
max_h -= coordSpaceH;
|
if (max_h < 0.0)
|
break;
|
stratLineNoH--;
|
}
|
|
coordinateParas.CoordSpaceH = coordSpaceH;
|
coordinateParas.EndLineNoH = endLineNoH;
|
coordinateParas.StartLineNoH = stratLineNoH;
|
coordinateParas.CoordMinH = disMaxH - (double)endLineNoH * coordSpaceH;
|
}
|
|
/// <summary>
|
/// 计算功率坐标
|
/// </summary>
|
/// <param name="minP">最小功率</param>
|
/// <param name="maxP">最大功率</param>
|
/// <param name="disMaxH">最大显示扬程</param>
|
/// <param name="downGridNum">最低点刻度</param>
|
/// <param name="coordinateParas">坐标Model</param>
|
public static void CalcCoordinateP(double minP, double maxP, double disMaxH, int downGridNum, ref CurveCoordinate coordinateParas)
|
{
|
int default_num = 5;
|
int spaceNum = coordinateParas.StartLineNoH - default_num - downGridNum;
|
if (spaceNum < 3)
|
spaceNum = 3;
|
|
var coordSpaceP = GetOptimalSpaceMax(minP, maxP, spaceNum, out double disMinP, out double disMaxP);
|
int endLineNoP = coordinateParas.StartLineNoH - default_num;
|
int stratLineNoP = endLineNoP;
|
|
double max_p = disMaxP;
|
while (max_p > minP * 0.98)
|
{
|
max_p -= coordSpaceP;
|
if (max_p < 0.0)
|
break;
|
stratLineNoP--;
|
}
|
|
coordinateParas.CoordSpaceP = coordSpaceP;
|
coordinateParas.EndLineNoP = endLineNoP;
|
coordinateParas.StartLineNoP = stratLineNoP;
|
|
//如果开始刻度低于最低点刻度 都往上加差值
|
if (coordinateParas.StartLineNoP < downGridNum)
|
{
|
int diff_num = downGridNum - coordinateParas.StartLineNoP;
|
|
coordinateParas.EndLineNoP += diff_num;
|
coordinateParas.StartLineNoP += diff_num;
|
}
|
|
coordinateParas.CoordMinH = GetByPlacesLength(disMaxH - (double)coordinateParas.EndLineNoH * coordinateParas.CoordSpaceH, 3);
|
coordinateParas.CoordMinP = GetByPlacesLength(disMaxP - (double)coordinateParas.EndLineNoP * coordinateParas.CoordSpaceP, 3);
|
}
|
|
/// <summary>
|
/// 计算效率坐标
|
/// </summary>
|
/// <param name="minE">最小效率</param>
|
/// <param name="maxE">最大效率</param>
|
/// <param name="coordinateParas">坐标Model</param>
|
public static void CalcCoordinateE(double minE, double maxE, ref CurveCoordinate coordinateParas)
|
{
|
int startLineNoE = coordinateParas.StartLineNoH - 6;
|
if (maxE <= 40.0)
|
{
|
coordinateParas.StartLineNoE = startLineNoE;
|
coordinateParas.EndLineNoE = coordinateParas.StartLineNoE + 6;
|
coordinateParas.CoordSpaceE = 5.0;
|
}
|
else if (maxE <= 50.0)
|
{
|
coordinateParas.StartLineNoE = startLineNoE - 5;
|
coordinateParas.EndLineNoE = coordinateParas.StartLineNoE + 10;
|
coordinateParas.CoordSpaceE = 5.0;
|
}
|
else if (maxE <= 60)
|
{
|
coordinateParas.StartLineNoE = startLineNoE;
|
coordinateParas.EndLineNoE = coordinateParas.StartLineNoE + 6;
|
coordinateParas.CoordSpaceE = 10.0;
|
}
|
else
|
{
|
coordinateParas.StartLineNoE = startLineNoE;
|
coordinateParas.EndLineNoE = coordinateParas.StartLineNoE + 5;
|
coordinateParas.CoordSpaceE = 20.0;
|
}
|
coordinateParas.CoordMinE = (double)(-coordinateParas.StartLineNoE) * coordinateParas.CoordSpaceE;
|
}
|
|
#endregion
|
|
#region Space 间隔
|
/// <summary>
|
/// 获取最小的间隔
|
/// </summary>
|
/// <param name="minValue">最小值</param>
|
/// <param name="maxValue">最大值</param>
|
/// <param name="spaceNum">间隔数量</param>
|
/// <param name="minDisplay">最小显示参数</param>
|
/// <param name="maxDisplay">最大显示参数</param>
|
/// <returns></returns>
|
public static double GetOptimalSpaceMin(double minValue, double maxValue, int spaceNum, out double minDisplay, out double maxDisplay)
|
{
|
minDisplay = minValue;
|
maxDisplay = maxValue;
|
double num = maxValue - minValue;
|
if (num < 0.0 || spaceNum < 1)
|
{
|
return (maxValue - minValue) / 10.0;
|
}
|
|
double optimalSpace = GetOptimalSpace((maxValue - minValue) / (double)spaceNum);
|
if (optimalSpace < 2.0)
|
{
|
minDisplay = Math.Floor(minValue / optimalSpace) * optimalSpace;
|
maxDisplay = minDisplay + (double)spaceNum * optimalSpace;
|
}
|
else
|
{
|
minDisplay = Math.Floor(minValue / optimalSpace) * optimalSpace;
|
maxDisplay = minDisplay + (double)spaceNum * optimalSpace;
|
}
|
|
return optimalSpace;
|
}
|
|
/// <summary>
|
/// 获取最大的间隔
|
/// </summary>
|
/// <param name="minValue">最小值</param>
|
/// <param name="maxValue">最大值</param>
|
/// <param name="spaceNum">间隔数量</param>
|
/// <param name="minDisplay">最小显示参数</param>
|
/// <param name="maxDisplay">最大显示参数</param>
|
/// <returns></returns>
|
public static double GetOptimalSpaceMax(double minValue, double maxValue, int spaceNum, out double minDisplay, out double maxDisplay)
|
{
|
minDisplay = minValue;
|
maxDisplay = maxValue;
|
double num = maxValue - minValue;
|
|
if (maxValue > 20)
|
{
|
if (num < 0.0 || spaceNum < 1)
|
{
|
return (maxValue - minValue) / 5.0;
|
}
|
}
|
else
|
{
|
if (num < 0.0 || spaceNum < 1)
|
{
|
return (maxValue - minValue) / 10.0;
|
}
|
}
|
|
double optimalSpace = GetOptimalSpace((maxValue - minValue) / (double)spaceNum, true);
|
maxDisplay = Math.Ceiling(maxValue / optimalSpace) * optimalSpace;
|
minDisplay = maxDisplay - (double)spaceNum * optimalSpace;
|
|
if (minDisplay > minValue)
|
{
|
var diff = minDisplay - minValue;
|
if (diff < optimalSpace)
|
{
|
minDisplay -= optimalSpace;
|
}
|
|
}
|
|
return optimalSpace;
|
}
|
|
/// <summary>
|
/// 获取最佳间隔 (精细取整)
|
/// </summary>
|
/// <param name="refSpace"> 间隔</param>
|
/// <returns></returns>
|
public static double GetOptimalSpace(double refSpace, bool IsAccurate = false)
|
{
|
if (refSpace < 1E-06)
|
{
|
return 1.0;
|
}
|
|
if (refSpace < 0.01)
|
{
|
double refSpace2 = refSpace * 100.0;
|
return GetOptimalSpace(refSpace2) / 100.0;
|
}
|
|
if (refSpace < 0.1)
|
{
|
double refSpace3 = refSpace * 10.0;
|
return GetOptimalSpace(refSpace3) / 10.0;
|
}
|
|
if (IsAccurate)
|
{
|
if (refSpace < 11.0)
|
{
|
if (refSpace < 1.35)
|
{
|
return 1.0;
|
}
|
|
if (refSpace < 2.2)
|
{
|
return 2.0;
|
}
|
|
if (refSpace < 5.5)
|
{
|
return 5.0;
|
}
|
|
if (refSpace < 8.5)
|
{
|
return 8.0;
|
}
|
|
return 10.0;
|
}
|
}
|
|
if (refSpace < 1.0)
|
{
|
if (refSpace < 0.15)
|
{
|
return 0.1;
|
}
|
|
if (refSpace < 0.22)
|
{
|
return 0.2;
|
}
|
|
if (refSpace < 0.6)
|
{
|
return 0.5;
|
}
|
|
return 1.0;
|
}
|
|
if (refSpace < 1.2)
|
{
|
return 1.0;
|
}
|
|
if (refSpace < 3.0)
|
{
|
if (refSpace < 1.2)
|
{
|
return 1.0;
|
}
|
|
if (refSpace < 2.3)
|
{
|
return 2.0;
|
}
|
|
return 3.0;
|
}
|
|
if (refSpace < 11.0)
|
{
|
if (refSpace < 1.35)
|
{
|
return 1.0;
|
}
|
|
if (refSpace < 2.2)
|
{
|
return 2.0;
|
}
|
|
if (refSpace < 5.5)
|
{
|
return 5.0;
|
}
|
|
if (refSpace < 8.5)
|
{
|
return 8.0;
|
}
|
|
return 10.0;
|
}
|
|
if (refSpace < 16.0)
|
{
|
return 15.0;
|
}
|
|
if (refSpace < 22.0)
|
{
|
return 20.0;
|
}
|
|
if (refSpace < 35.0)
|
{
|
return 25.0;
|
}
|
|
if (refSpace < 41.0)
|
{
|
return 40.0;
|
}
|
|
if (refSpace < 51.0)
|
{
|
return 50.0;
|
}
|
|
if (refSpace < 61.0)
|
{
|
return 60.0;
|
}
|
|
if (refSpace < 71.0)
|
{
|
return 70.0;
|
}
|
|
if (refSpace < 78.0)
|
{
|
return 75.0;
|
}
|
|
if (refSpace < 150.0)
|
{
|
return 100.0;
|
}
|
|
if (refSpace < 230.0)
|
{
|
return 200.0;
|
}
|
|
if (refSpace < 270.0)
|
{
|
return 250.0;
|
}
|
|
if (refSpace < 1500.0)
|
{
|
int num = (int)(refSpace / 100.0);
|
return num * 100;
|
}
|
|
int num2 = (int)(refSpace / 1000.0);
|
return num2 * 1000;
|
}
|
|
#endregion
|
|
#region 数字辅助方法
|
/// <summary>
|
/// 按指定长度获取
|
/// </summary>
|
public static double GetByPlacesLength(double value, int length)
|
{
|
int decimalPlacesLength = GetDecimalPlacesLength(value);
|
if (decimalPlacesLength > length)
|
{
|
return Math.Round(value, length);
|
}
|
return value;
|
}
|
|
/// <summary>
|
/// 获取小数点长度
|
/// </summary>
|
private static int GetDecimalPlacesLength(double value)
|
{
|
string text = value.ToString();
|
int num = text.IndexOf('.');
|
if (num >= 0)
|
{
|
return text.Length - num - 1;
|
}
|
return 0;
|
}
|
#endregion
|
|
}
|
}
|