| | |
| | | using NPOI.Util; |
| | | using Yw.Geometry; |
| | | |
| | | namespace Yw.WinFrmUI.Phart |
| | | { |
| | | /// <summary> |
| | | /// 性能计算辅助类 |
| | | /// </summary> |
| | | public class PumpCalcHelper |
| | | public static class PumpCalcHelper |
| | | { |
| | | #region 常规计算 |
| | | |
| | |
| | | |
| | | return similar_point; |
| | | } |
| | | |
| | | |
| | | #endregion |
| | | |
| | | #region 计算推荐参数 |
| | |
| | | |
| | | |
| | | #endregion |
| | | |
| | | |
| | | #endregion |
| | | } |
| | | |
| | | |
| | | #region 曲线与H=K*Q^i的交点 |
| | | |
| | | /// <summary> |
| | | /// 根据相似点设置相似曲线,相似点(选择点)的x:流量y:杨程 |
| | | /// </summary> |
| | | public static double GetSimuValue(Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt, double origin_value, double extend_ratio = 1) |
| | | { |
| | | if (cubic_spline == null) |
| | | return -3; |
| | | if (simular_pt.X < 0.1 || simular_pt.Y < 0.1) |
| | | return -2; |
| | | if (simular_pt.X > cubic_spline.MaxX * extend_ratio * 1.5) |
| | | return -4; |
| | | |
| | | Yw.Geometry.Point2d sect_pt = GetSectPoint(cubic_spline, simular_pt, extend_ratio); |
| | | if (sect_pt == null || sect_pt.IsZeroPoint()) |
| | | return -5; |
| | | |
| | | //计算相似点的转速/直径 |
| | | return CalculateSimuByH(origin_value, sect_pt.Y, simular_pt.Y); |
| | | } |
| | | |
| | | //ratioIgnore:作用 当simularPoint超出曲线范围时,曲线扩大的倍数 |
| | | public static Yw.Geometry.Point2d GetSectPoint(Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt, double ratioIgnore) |
| | | { |
| | | return GetSectPointGeneral(cubic_spline, simular_pt, 2, ratioIgnore); |
| | | } |
| | | |
| | | public static Yw.Geometry.Point2d GetSectPointParabola(Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt) |
| | | { |
| | | var sect_pt = new Yw.Geometry.Point2d(0, 0); |
| | | if (cubic_spline == null) |
| | | return sect_pt; |
| | | var pt_list = cubic_spline.GetPointListByXRatioRange(1,1.2, 50); |
| | | return GetSectPointParabola(pt_list, simular_pt); |
| | | } |
| | | |
| | | //通过点simular_pt和点(0,0)的直线,与曲线Curve的交点(没有,返回Point(0,0)) |
| | | public static Yw.Geometry.Point2d GetSectPointLine(List<Yw.Geometry.Point2d> CurvePoints, Yw.Geometry.Point2d simular_pt) |
| | | { |
| | | Yw.Geometry.Point2d sect_pt = new Yw.Geometry.Point2d(0, 0); |
| | | if (CurvePoints == null || CurvePoints.Count < 2) |
| | | return sect_pt; |
| | | |
| | | //计算直线的K |
| | | if (simular_pt.X < 1) |
| | | return sect_pt; |
| | | double a = simular_pt.Y / simular_pt.X; |
| | | if (a < 0.0001) |
| | | return sect_pt; |
| | | |
| | | //与2点连成直线的交点,判断交点是否在2点之间,即可是曲线的交点 |
| | | double b, c; |
| | | double x; |
| | | for (int i = 0; i < CurvePoints.Count - 1; i++) |
| | | { |
| | | LineHelper.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 (UtilsHelper.IsMiddle(CurvePoints[i].X, CurvePoints[i + 1].X, x)) |
| | | { |
| | | sect_pt.X = x; |
| | | sect_pt.Y = a * x; |
| | | return sect_pt; |
| | | } |
| | | } |
| | | |
| | | return sect_pt; |
| | | } |
| | | |
| | | //通过点simular_pt和点(0,0)的抛物线,与曲线Curve的交点(没有,返回Point(0,0)) |
| | | //曲线公式:H=K*Q^2 |
| | | public static Yw.Geometry.Point2d GetSectPointParabola(List<Yw.Geometry.Point2d> pt_list, Yw.Geometry.Point2d simular_pt) |
| | | { |
| | | return ParabolaCurveHelper.GetSectPoint(pt_list, simular_pt, 0); |
| | | } |
| | | |
| | | public static Yw.Geometry.Point2d GetSectPointLine(this Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt) |
| | | { |
| | | Yw.Geometry.Point2d sect_pt = new Yw.Geometry.Point2d(0, 0); |
| | | if (cubic_spline == null) |
| | | return sect_pt; |
| | | |
| | | //计算直线的K |
| | | if (simular_pt.X < 1) |
| | | return sect_pt; |
| | | double a = simular_pt.Y / simular_pt.X; |
| | | if (a < 0.0001) |
| | | return sect_pt; |
| | | |
| | | //点越多越精确 |
| | | return GetSectPointLine(cubic_spline.GetPointList(100), simular_pt); |
| | | } |
| | | |
| | | //曲线H=K*Q^i 与曲线Curve的交点(没有,返回Point(0,0)) |
| | | public static Yw.Geometry.Point2d GetSectPointGeneral(List<Yw.Geometry.Point2d> pt_list, Yw.Geometry.Point2d simular_pt, double index) |
| | | { |
| | | Yw.Geometry.Point2d sect_pt = new Yw.Geometry.Point2d(0, 0); |
| | | if (pt_list == null || pt_list.Count < 2) |
| | | return sect_pt; |
| | | |
| | | if (simular_pt.X < 0.1) |
| | | return sect_pt; |
| | | |
| | | if (Math.Abs(index - 1) < 0.01) |
| | | return GetSectPointLine(pt_list, simular_pt); |
| | | if (Math.Abs(index - 2) < 0.01) |
| | | return GetSectPointParabola(pt_list, simular_pt); |
| | | |
| | | //计算系数K |
| | | double fixK = simular_pt.Y / Math.Pow(simular_pt.X, index); |
| | | if (fixK < 0.000001) |
| | | return sect_pt; |
| | | |
| | | //思路是从simular_pt开始逐个增加0.1,直到k值最接近fixK |
| | | double space = (pt_list.Last().X - simular_pt.X) / 1200; |
| | | double x = simular_pt.X; |
| | | double y, k; |
| | | do |
| | | { |
| | | x = x + space; |
| | | y = 0; |
| | | var y_pt_list = pt_list.GetInterPointsY(x); |
| | | if (y_pt_list==null|| !y_pt_list.Any()) |
| | | { |
| | | break; |
| | | } |
| | | y = y_pt_list.Last(); |
| | | k = y / Math.Pow(x, index); |
| | | } while (k > fixK); |
| | | |
| | | sect_pt.X = x; |
| | | sect_pt.Y = y; |
| | | return sect_pt; |
| | | } |
| | | |
| | | |
| | | //ratioIgnore:作用 当simular_pt超出范围时,扩大的倍数 |
| | | public static Yw.Geometry.Point2d GetSectPointGeneral(this Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt, double index, double ratioIgnore) |
| | | { |
| | | Yw.Geometry.Point2d sect_pt = new Yw.Geometry.Point2d(0, 0); |
| | | if (cubic_spline == null) |
| | | return sect_pt; |
| | | |
| | | if (simular_pt.X < 1) |
| | | return sect_pt; |
| | | var cubic_spline_ex = cubic_spline.Copy(); |
| | | //检查是否在曲线的区域范围内 |
| | | double maxQ = cubic_spline_ex.MaxX; |
| | | double maxH = cubic_spline_ex.GetPointY(maxQ); |
| | | double k1 = maxH / Math.Pow(maxQ, index); |
| | | double k2 = simular_pt.Y / Math.Pow(simular_pt.X, index); |
| | | if (k1 > k2) |
| | | { |
| | | cubic_spline_ex.MaxX = cubic_spline_ex.MaxX * ratioIgnore;//放大1.2倍 |
| | | } |
| | | |
| | | if (Math.Abs(index - 1) < 0.01) |
| | | return GetSectPointLine(cubic_spline_ex, simular_pt); |
| | | if (Math.Abs(index - 2) < 0.01) |
| | | return GetSectPointParabola(cubic_spline_ex, simular_pt); |
| | | |
| | | //计算系数K |
| | | double fixK = simular_pt.Y / Math.Pow(simular_pt.X, index); |
| | | if (fixK < 0.000001) |
| | | return sect_pt; |
| | | |
| | | //思路是从simular_pt开始逐个增加0.1,直到k值最接近fixK |
| | | double space = (cubic_spline_ex.MaxX - simular_pt.X) / 1000; |
| | | double x = simular_pt.X; |
| | | double y, k; |
| | | do |
| | | { |
| | | x = x + space; |
| | | y = cubic_spline_ex.GetPointY(x); |
| | | k = y / Math.Pow(x, index); |
| | | } while (k > fixK); |
| | | |
| | | sect_pt.X = x; |
| | | sect_pt.Y = y; |
| | | return sect_pt; |
| | | } |
| | | |
| | | #endregion 曲线与H=K*Q^i的交点 protect类型,给子类调用,怎么覆盖GetSectPoint |
| | | } |
| | | } |