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 } }