using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using IStation.Model;
|
|
namespace IStation.Common
|
{
|
public class CutSimuCalculer
|
{
|
|
//知道原始速度,以及原始的杨程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<IStation.Model.CurvePoint> simularPoints = new List<IStation.Model.CurvePoint>();
|
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<IStation.Model.CurvePoint> simularPoints = new List<IStation.Model.CurvePoint>();
|
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<IStation.Model.CurvePoint> simularPoints = new List<IStation.Model.CurvePoint>();
|
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<IStation.Model.CurvePoint> 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<IStation.Model.CurvePoint> 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<IStation.Model.CurvePoint> 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<IStation.Model.CurvePoint> 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
|
|
}
|
}
|