using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IStation.Model;
namespace IStation.Common
{
///
///
///
public class SpeedSimuCalculer
{
///
/// 知道原始速度,以及原始的杨程H以及对应的变速后的杨程,求变速后的速度
///
///
///
///
///
public static double GetSimuByH(double originSpeend, double originH, double changeH)
{
double ratio = Math.Pow(originH / changeH, 1.0 / 2.0);
return originSpeend / ratio;
}
///
/// 知道原始速度,以及原始的流量Q以及对应的变速后的杨程,求变速后的速度
///
///
///
///
///
public static double GetSimuByQ(double originSpeend, double originQ, double changeQ)
{
double ratio = originQ / changeQ ;
return originSpeend / ratio;
}
///
/// 获取变速(变频后的)的曲线
///
///
///
///
///
///
public static IStation.Model.CurveExpress GetSimuPointQH(IStation.Model.CurveExpress OriginExpress, double origin, double change, int pointNum = 12)
{//change可以大于origin,有时用于反求
if (OriginExpress == null)
return null;
if (change < 1)
return null;
var ratio = change / origin;
List simularPoints = new List();
foreach (IStation.Model.CurvePoint pt in IStation.Model.FitCurveHelper.GetFitPoints(OriginExpress, pointNum))
{
simularPoints.Add(new IStation.Model.CurvePoint(
pt.X * ratio,
pt.Y * ratio * ratio));
}
return new IStation.Model.CurveExpress(simularPoints, OriginExpress.FitType);
}
///
///
///
///
///
///
///
///
public static IStation.Model.CurveExpress GetSimuPointQP(IStation.Model.CurveExpress OriginExpress, double origin, double change, int pointNum = 12)
{//change可以大于origin,有时用于反求
if (OriginExpress == null)
return null;
if (change < 1)
return null;
var ratio = change / origin;
List simularPoints = new List();
foreach (IStation.Model.CurvePoint pt in IStation.Model.FitCurveHelper.GetFitPoints(OriginExpress, pointNum))
{
simularPoints.Add(new IStation.Model.CurvePoint(
pt.X * ratio,
pt.Y * ratio * ratio * ratio));
}
return new IStation.Model.CurveExpress(simularPoints, OriginExpress.FitType);
}
///
///
///
///
///
///
///
///
public static IStation.Model.CurveExpress GetSimuPointQE(IStation.Model.CurveExpress OriginExpress, double origin, double change, int pointNum = 12)
{//change可以大于origin,有时用于反求
if (OriginExpress == null)
return null;
if (change < 1)
return null;
var ratio = change / origin;
List simularPoints = new List();
foreach (IStation.Model.CurvePoint pt in IStation.Model.FitCurveHelper.GetFitPoints(OriginExpress, pointNum))
{
simularPoints.Add(new IStation.Model.CurvePoint(
pt.X * ratio,
pt.Y ));
}
return new IStation.Model.CurveExpress(simularPoints, OriginExpress.FitType);
}
///
/// 根据相似点设置相似曲线,相似点(选择点)的x:流量y:杨程
///
///
///
///
///
///
public static double GetSimuValue(IStation.Model.CurveExpress curveExpressQH, IStation.Model.CurvePoint simularPoint, double originValue, double extendRatio = 1)
{
if (curveExpressQH == null)
return -3;
if (simularPoint.X < 0.1 || simularPoint.Y < 0.1)
return -2;
if (simularPoint.X > curveExpressQH.Max * extendRatio * 1.5)
return -4;
//if (curveExpressQH.FitType == Model.eCurveFitType.ThroughPoint )
//{
//}
//计算交点位置参数
IStation.Model.CurvePoint sectPoint = GetSectPoint(curveExpressQH, simularPoint, extendRatio);
if (sectPoint == null || IStation.Model.CurvePoint.IsZeroPt(sectPoint))
return -5;
//计算相似点的转速/直径
return GetSimuByH(originValue, sectPoint.Y, simularPoint.Y);
}
#region 曲线与H=K*Q^i的交点 protect类型,
public static IStation.Model.CurvePoint GetSectPoint(CurveExpress CurveExpress, IStation.Model.CurvePoint simularPoint)
{
return GetSectPointParabola(CurveExpress, simularPoint);
}
public static IStation.Model.CurvePoint GetSectPoint(List CurvePoints, IStation.Model.CurvePoint simularPoint)
{
return GetSectPointParabola(CurvePoints, simularPoint);
}
//ratioIgnore:作用 当simularPoint超出曲线范围时,曲线扩大的倍数
public static IStation.Model.CurvePoint GetSectPoint(CurveExpress CurveExpress, IStation.Model.CurvePoint simularPoint, double ratioIgnore)
{
return GetSectPointGeneral(CurveExpress, simularPoint, 2, ratioIgnore);
}
//通过点simularPoint和点(0,0)的抛物线,与曲线Curve的交点(没有,返回Point(0,0))
//曲线公式:H=K*Q^2
public static IStation.Model.CurvePoint GetSectPointParabola(List CurvePoints, IStation.Model.CurvePoint simularPoint)
{
return IStation.Model.ParabolaCurveHelper_H.GetSectPoint(CurvePoints, simularPoint, 0);
}
public static IStation.Model.CurvePoint GetSectPointParabola(CurveExpress CurveExpress, IStation.Model.CurvePoint simularPoint)
{
IStation.Model.CurvePoint sectPoint = new IStation.Model.CurvePoint(0, 0);
if (CurveExpress == null)
return sectPoint;
return GetSectPointParabola(IStation.Model.FitCurveHelper.GetFitPointsByExtend(CurveExpress, 1.2, 50), simularPoint);
}
//通过点simularPoint和点(0,0)的直线,与曲线Curve的交点(没有,返回Point(0,0))
protected static IStation.Model.CurvePoint GetSectPointLine(List CurvePoints, IStation.Model.CurvePoint simularPoint)
{
IStation.Model.CurvePoint sectPoint = new IStation.Model.CurvePoint(0, 0);
if (CurvePoints == null || CurvePoints.Count < 2)
return sectPoint;
//计算直线的K
if (simularPoint.X < 1)
return sectPoint;
double a = simularPoint.Y / simularPoint.X;
if (a < 0.0001)
return sectPoint;
//与2点连成直线的交点,判断交点是否在2点之间,即可是曲线的交点
double b, c;
double x;
for (int i = 0; i < CurvePoints.Count - 1; i++)
{
IStation.Model.CurveLineHelper.GetKandB(CurvePoints[i], CurvePoints[i + 1], out b, out c);
/*解方程
* y=ax
* y=bx+c
*/
if (Math.Abs(a - b) < 0.001)
continue;
x = c / (a - b);
if (IStation.Common.PointHelper.IsMiddlePt(CurvePoints[i].X, CurvePoints[i + 1].X, x))
{
sectPoint.X = x;
sectPoint.Y = a * x;
return sectPoint;
}
}
return sectPoint;
}
protected static IStation.Model.CurvePoint GetSectPointLine(IStation.Model.CurveExpress CurveExpress, IStation.Model.CurvePoint simularPoint)
{
IStation.Model.CurvePoint sectPoint = new IStation.Model.CurvePoint(0, 0);
if (CurveExpress == null)
return sectPoint;
//计算直线的K
if (simularPoint.X < 1)
return sectPoint;
double a = simularPoint.Y / simularPoint.X;
if (a < 0.0001)
return sectPoint;
//点越多越精确
return GetSectPointLine(IStation.Model.FitCurveHelper.GetFitPoints(CurveExpress, 100), simularPoint);
}
//曲线H=K*Q^i 与曲线Curve的交点(没有,返回Point(0,0))
protected static IStation.Model.CurvePoint GetSectPointGeneral(List CurvePoints, IStation.Model.CurvePoint simularPoint, double index)
{
IStation.Model.CurvePoint sectPoint = new IStation.Model.CurvePoint(0, 0);
if (CurvePoints == null || CurvePoints.Count < 2)
return sectPoint;
if (simularPoint.X < 0.1)
return sectPoint;
if (Math.Abs(index - 1) < 0.01)
return GetSectPointLine(CurvePoints, simularPoint);
if (Math.Abs(index - 2) < 0.01)
return GetSectPointParabola(CurvePoints, simularPoint);
//计算系数K
double fixK = simularPoint.Y / Math.Pow(simularPoint.X, index);
if (fixK < 0.000001)
return sectPoint;
//思路是从simularPoint开始逐个增加0.1,直到k值最接近fixK
double space = (CurvePoints.Last().X - simularPoint.X) / 1200;
double x = simularPoint.X;
double y, k;
do
{
x = x + space;
y = 0;
if (!IStation.Model.FitCurveHelper.GetInterPointY(CurvePoints, x, out y))
{
break;
}
k = y / Math.Pow(x, index);
} while (k > fixK);
sectPoint.X = x;
sectPoint.Y = y;
return sectPoint;
}
//曲线H=K*Q^i 与曲线Curve的交点(没有,返回Point(0,0))
protected static IStation.Model.CurvePoint GetSectPointGeneral(IStation.Model.CurveExpress CurveExpress, IStation.Model.CurvePoint simularPoint, double index)
{
IStation.Model.CurvePoint sectPoint = new IStation.Model.CurvePoint(0, 0);
if (CurveExpress == null)
return sectPoint;
if (simularPoint.X < 1)
return sectPoint;
//检查是否在曲线的区域范围内
double maxQ = CurveExpress.Max;
double maxH = IStation.Model.FitCurveHelper.GetFitPointY(CurveExpress, maxQ);
double k1 = maxH / Math.Pow(maxQ, index);
double k2 = simularPoint.Y / Math.Pow(simularPoint.X, index);
if (k1 > k2)
{
return sectPoint;
}
if (Math.Abs(index - 1) < 0.01)
return GetSectPointLine(CurveExpress, simularPoint);
if (Math.Abs(index - 2) < 0.01)
return GetSectPointParabola(CurveExpress, simularPoint);
//计算系数K
double fixK = simularPoint.Y / Math.Pow(simularPoint.X, index);
if (fixK < 0.000001)
return sectPoint;
//思路是从simularPoint开始逐个增加0.1,直到k值最接近fixK
double space = (CurveExpress.Max - simularPoint.X) / 1000;
double x = simularPoint.X;
double y, k;
do
{
x = x + space;
y = IStation.Model. FitCurveHelper.GetFitPointY(CurveExpress, x);
k = y / Math.Pow(x, index);
} while (k > fixK);
sectPoint.X = x;
sectPoint.Y = y;
return sectPoint;
}
//ratioIgnore:作用 当simularPoint超出范围时,扩大的倍数
protected static IStation.Model.CurvePoint GetSectPointGeneral(IStation.Model.CurveExpress curveExpress, IStation.Model.CurvePoint simularPoint, double index, double ratioIgnore)
{
IStation.Model.CurvePoint sectPoint = new IStation.Model.CurvePoint(0, 0);
if (curveExpress == null)
return sectPoint;
if (simularPoint.X < 1)
return sectPoint;
var CurveExpressEx = new Model.CurveExpress(curveExpress);
//检查是否在曲线的区域范围内
double maxQ = CurveExpressEx.Max;
double maxH = IStation.Model.FitCurveHelper.GetFitPointY(CurveExpressEx, maxQ);
double k1 = maxH / Math.Pow(maxQ, index);
double k2 = simularPoint.Y / Math.Pow(simularPoint.X, index);
if (k1 > k2)
{
CurveExpressEx.Max = CurveExpressEx.Max * ratioIgnore;//放大1.2倍
}
if (Math.Abs(index - 1) < 0.01)
return GetSectPointLine(CurveExpressEx, simularPoint);
if (Math.Abs(index - 2) < 0.01)
return GetSectPointParabola(CurveExpressEx, simularPoint);
//计算系数K
double fixK = simularPoint.Y / Math.Pow(simularPoint.X, index);
if (fixK < 0.000001)
return sectPoint;
//思路是从simularPoint开始逐个增加0.1,直到k值最接近fixK
double space = (CurveExpressEx.Max - simularPoint.X) / 1000;
double x = simularPoint.X;
double y, k;
do
{
x = x + space;
y = IStation.Model.FitCurveHelper.GetFitPointY(CurveExpressEx, x);
k = y / Math.Pow(x, index);
} while (k > fixK);
sectPoint.X = x;
sectPoint.Y = y;
return sectPoint;
}
#endregion 曲线与H=K*Q^i的交点 protect类型,给子类调用,怎么覆盖GetSectPoint
}
}