lixiaojun
2024-11-27 4a5989c23c468d376a8abe72abe1a534708dbfe2
WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/01-calculate/PumpCalcHelper.cs
@@ -1,11 +1,12 @@
using NPOI.Util;
using Yw.Geometry;
namespace Yw.WinFrmUI.Phart
{
    /// <summary>
    /// 性能计算辅助类
    /// </summary>
    public class PumpCalcHelper
    public static class PumpCalcHelper
    {
        #region 常规计算 
@@ -699,6 +700,8 @@
            return similar_point;
        }
        #endregion
        #region 计算推荐参数
@@ -981,43 +984,43 @@
        /// <summary>
        /// 计算功率
        /// </summary>
        /// <param name="pt_qh_list">流量扬程点</param>
        /// <param name="pt_qe_list">流量效率点</param>
        /// <param name="qh_pt_list">流量扬程点</param>
        /// <param name="qe_pt_list">流量效率点</param>
        /// <returns>流量功率点</returns>
        public static List<Yw.Geometry.Point2d> CalculateP(List<Yw.Geometry.Point2d> pt_qh_list, List<Yw.Geometry.Point2d> pt_qe_list)
        public static List<Yw.Geometry.Point2d> CalculateP(List<Yw.Geometry.Point2d> qh_pt_list, List<Yw.Geometry.Point2d> qe_pt_list)
        {
            if (pt_qh_list == null || pt_qh_list.Count() <= 2)
            if (qh_pt_list == null || qh_pt_list.Count() <= 2)
                return null;
            bool is_x_start_0 = pt_qh_list.First().X > 500 || pt_qh_list.First().X > pt_qh_list.Last().X * 0.2;
            return CalculateP(pt_qh_list, pt_qe_list, Constant.WaterDensity, -1, is_x_start_0);
            bool is_x_start_0 = qh_pt_list.First().X > 500 || qh_pt_list.First().X > qh_pt_list.Last().X * 0.2;
            return CalculateP(qh_pt_list, qe_pt_list, Constant.WaterDensity, -1, is_x_start_0);
        }
        /// <summary>
        /// 计算功率
        /// </summary> 
        /// <param name="pt_qh_list">流量扬程点</param>
        /// <param name="pt_qe_list">流量效率点</param>
        /// <param name="qh_pt_list">流量扬程点</param>
        /// <param name="qe_pt_list">流量效率点</param>
        /// <param name="midu">水的密度</param>
        /// <param name="zeroPower">流量为0时的功率</param>
        /// <param name="is_x_start_0">流量是否为0</param>
        /// <returns></returns> 
        public static List<Yw.Geometry.Point2d> CalculateP(
            List<Yw.Geometry.Point2d> pt_qh_list,
            List<Yw.Geometry.Point2d> pt_qe_list,
            List<Yw.Geometry.Point2d> qh_pt_list,
            List<Yw.Geometry.Point2d> qe_pt_list,
            double midu,
            double zeroPower,
            bool is_x_start_0)
        {
            if (pt_qh_list == null || pt_qh_list.Count < 3)
            if (qh_pt_list == null || qh_pt_list.Count < 3)
                return null;
            if (pt_qe_list == null || pt_qe_list.Count < 3)
            if (qe_pt_list == null || qe_pt_list.Count < 3)
                return null;
            var curve_qh = new Yw.Geometry.CubicSpline2d(pt_qh_list);
            var curve_qe = new Yw.Geometry.CubicSpline2d(pt_qe_list);
            var curve_qh = new Yw.Geometry.CubicSpline2d(qh_pt_list);
            var curve_qe = new Yw.Geometry.CubicSpline2d(qe_pt_list);
            var cubic_spline_qp = CalculateP(curve_qh, curve_qe, midu, zeroPower, is_x_start_0);
            return cubic_spline_qp.GetPointList(pt_qe_list.Count());
            var qp = CalculateP(curve_qh, curve_qe, midu, zeroPower, is_x_start_0);
            return qp.GetPointList(qe_pt_list.Count());
        }
        /// <summary>
@@ -1035,17 +1038,17 @@
            if (curve_qh == null || curve_qe == null)
                return null;
            int point_count = 16;//点不能太多
            var pt_qh_list = curve_qh.GetPointList(point_count);
            if (pt_qh_list == null || pt_qh_list.Count < 3)
            var qh_pt_list = curve_qh.GetPointList(point_count);
            if (qh_pt_list == null || qh_pt_list.Count < 3)
                return null;
            var pt_qe_list = curve_qe.GetPointList(point_count);
            if (pt_qe_list == null || pt_qe_list.Count < 3)
            var qe_pt_list = curve_qe.GetPointList(point_count);
            if (qe_pt_list == null || qe_pt_list.Count < 3)
                return null;
            List<Yw.Geometry.Point2d> pt_qp_list = new List<Yw.Geometry.Point2d>();
            List<Yw.Geometry.Point2d> qp_pt_list = new List<Yw.Geometry.Point2d>();
            //间距
            double minQ = Math.Max(pt_qh_list.First().X, pt_qe_list.First().X);
            double maxQ = Math.Min(pt_qh_list.Last().X, pt_qe_list.Last().X);
            double minQ = Math.Max(qh_pt_list.First().X, qe_pt_list.First().X);
            double maxQ = Math.Min(qh_pt_list.Last().X, qe_pt_list.Last().X);
            //
            double Q, H, E, P;
@@ -1056,7 +1059,7 @@
            {
                for (int i = 5; i < point_count; i++)//前面几个点不要
                {
                    Q = pt_qe_list.First().X + space * i;
                    Q = qe_pt_list.First().X + space * i;
                    E = curve_qe.GetPointY(Q);
                    H = curve_qh.GetPointY(Q);
                    if (H < 0.1 || E < 0.5)
@@ -1079,28 +1082,28 @@
                    {
                        P = Math.Round(P, 0);
                    }
                    pt_qp_list.Add(new Yw.Geometry.Point2d(Q, P));
                    qp_pt_list.Add(new Yw.Geometry.Point2d(Q, P));
                }
                pt_qp_list = pt_qp_list.GetFitPointList(point_count);
                if (pt_qp_list == null)
                qp_pt_list = qp_pt_list.GetFitPointList(point_count);
                if (qp_pt_list == null)
                    return null;
                if (zeroPower > 0.1)
                {
                    pt_qp_list.Insert(0, new Yw.Geometry.Point2d(0, zeroPower));
                    qp_pt_list.Insert(0, new Yw.Geometry.Point2d(0, zeroPower));
                }
                else
                {
                    if (pt_qp_list[0].Y >= pt_qp_list[1].Y)
                    if (qp_pt_list[0].Y >= qp_pt_list[1].Y)
                    {
                        pt_qp_list[0].Y = pt_qp_list[1].Y * 0.95;
                        qp_pt_list[0].Y = qp_pt_list[1].Y * 0.95;
                    }
                    double startP = Yw.Geometry.LineHelper.GetYbyX(pt_qp_list[0].X, pt_qp_list[0].Y, pt_qp_list[1].X, pt_qp_list[1].Y, 0);
                    double startP = Yw.Geometry.LineHelper.GetYbyX(qp_pt_list[0].X, qp_pt_list[0].Y, qp_pt_list[1].X, qp_pt_list[1].Y, 0);
                    if (startP < 0.001)
                        startP = pt_qp_list[0].Y;
                        startP = qp_pt_list[0].Y;
                    if (startP < 2)
                    {
@@ -1119,17 +1122,17 @@
                        startP = Math.Round(startP, 0);
                    }
                    pt_qp_list.Insert(0, new Yw.Geometry.Point2d(0, startP));
                    qp_pt_list.Insert(0, new Yw.Geometry.Point2d(0, startP));
                }
                return new Yw.Geometry.CubicSpline2d(pt_qp_list);
                return new Yw.Geometry.CubicSpline2d(qp_pt_list);
            }
            else
            {
                for (int i = 0; i < point_count; i++)//前面几个点不要
                {
                    Q = pt_qe_list.First().X + space * i;
                    Q = qe_pt_list.First().X + space * i;
                    E = curve_qe.GetPointY(Q);
                    H = curve_qh.GetPointY(Q);
                    if (H < 0.1 || E < 0.5)
@@ -1152,14 +1155,14 @@
                    {
                        P = Math.Round(P, 0);
                    }
                    pt_qp_list.Add(new Yw.Geometry.Point2d(Q, P));
                    qp_pt_list.Add(new Yw.Geometry.Point2d(Q, P));
                }
                pt_qp_list = pt_qp_list.GetFitPointList(point_count);
                if (pt_qp_list == null)
                qp_pt_list = qp_pt_list.GetFitPointList(point_count);
                if (qp_pt_list == null)
                    return null;
                return new Yw.Geometry.CubicSpline2d(pt_qp_list);
                return new Yw.Geometry.CubicSpline2d(qp_pt_list);
            }
        }
@@ -1168,23 +1171,23 @@
        #region 计算效率
        public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d cubic_spline_qh, Yw.Geometry.CubicSpline2d cubic_spline_qp)
        public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qp)
        {
            return CalculateE(cubic_spline_qh, cubic_spline_qp, Constant.WaterDensity);
            return CalculateE(qh, qp, Constant.WaterDensity);
        }
        public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d cubic_spline_qh, Yw.Geometry.CubicSpline2d cubic_spline_qp, bool is_x_start_0)
        public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qp, bool is_x_start_0)
        {
            return CalculateE(cubic_spline_qh, cubic_spline_qp, Constant.WaterDensity, is_x_start_0);
            return CalculateE(qh, qp, Constant.WaterDensity, is_x_start_0);
        }
        public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d cubic_spline_qh, Yw.Geometry.CubicSpline2d cubic_spline_qp, double midu)
        public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qp, double midu)
        {
            if (cubic_spline_qh == null)
            if (qh == null)
                return null;
            bool is_x_start_0 = true;
            if (cubic_spline_qh.MinX > 500 || cubic_spline_qh.MinX > cubic_spline_qh.MaxX * 0.1)
            if (qh.MinX > 500 || qh.MinX > qh.MaxX * 0.1)
            {
                is_x_start_0 = false;
            }
@@ -1193,73 +1196,73 @@
                is_x_start_0 = true;
            }
            return CalculateE(cubic_spline_qh, cubic_spline_qp, midu, is_x_start_0);
            return CalculateE(qh, qp, midu, is_x_start_0);
        }
        public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d cubic_spline_qh, Yw.Geometry.CubicSpline2d cubic_spline_qp, double midu, bool is_x_start_0)
        public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qp, double midu, bool is_x_start_0)
        {
            if (cubic_spline_qh == null)
            if (qh == null)
                return null;
            if (cubic_spline_qp == null)
            if (qp == null)
                return null;
            int point_count = 12;
            List<Yw.Geometry.Point2d> pt_qe_list = new List<Yw.Geometry.Point2d>();
            List<Yw.Geometry.Point2d> pt_qp_list = cubic_spline_qp.GetPointList(point_count);
            List<Yw.Geometry.Point2d> qe_pt_list = new List<Yw.Geometry.Point2d>();
            List<Yw.Geometry.Point2d> qp_pt_list = qp.GetPointList(point_count);
            double Q, H, Eff, Power;
            var fitCurve = new Yw.Geometry.CubicSpline2d(cubic_spline_qh);
            for (int i = 0; i < pt_qp_list.Count; i++)
            var fitCurve = new Yw.Geometry.CubicSpline2d(qh);
            for (int i = 0; i < qp_pt_list.Count; i++)
            {
                Q = pt_qp_list[i].X;
                Power = pt_qp_list[i].Y;
                Q = qp_pt_list[i].X;
                Power = qp_pt_list[i].Y;
                H = fitCurve.GetPointY(Q);
                Eff = CalculateE(Q, H, Power, midu);
                pt_qe_list.Add(new Yw.Geometry.Point2d(Q, Eff));
                qe_pt_list.Add(new Yw.Geometry.Point2d(Q, Eff));
            }
            //保证Q=0时,Eff=0;
            if (is_x_start_0)
            {
                pt_qe_list[0] = new Yw.Geometry.Point2d(0, 0);
                pt_qe_list = pt_qe_list.GetFitPointList();
                pt_qe_list = pt_qe_list.AmendByZeroPointY(pt_qe_list[3].X, 0);
                return new Yw.Geometry.CubicSpline2d(pt_qe_list);
                qe_pt_list[0] = new Yw.Geometry.Point2d(0, 0);
                qe_pt_list = qe_pt_list.GetFitPointList();
                qe_pt_list = qe_pt_list.AmendByZeroPointY(qe_pt_list[3].X, 0);
                return new Yw.Geometry.CubicSpline2d(qe_pt_list);
            }
            else
            {
                return new Yw.Geometry.CubicSpline2d(pt_qe_list);
                return new Yw.Geometry.CubicSpline2d(qe_pt_list);
            }
        }
        public static List<Yw.Geometry.Point2d> CalculateEpoint(
            Yw.Geometry.CubicSpline2d cubic_spline_qh,
            Yw.Geometry.CubicSpline2d cubic_spline_qp,
            Yw.Geometry.CubicSpline2d qh,
            Yw.Geometry.CubicSpline2d qp,
            int point_count,
            double midu)
        {
            if (cubic_spline_qh == null)
            if (qh == null)
                return null;
            if (cubic_spline_qp == null)
            if (qp == null)
                return null;
            List<Yw.Geometry.Point2d> pt_qe_list = new List<Yw.Geometry.Point2d>();
            List<Yw.Geometry.Point2d> pt_qp_list = cubic_spline_qp.GetPointList(point_count);
            List<Yw.Geometry.Point2d> qe_pt_list = new List<Yw.Geometry.Point2d>();
            List<Yw.Geometry.Point2d> qp_pt_list = qp.GetPointList(point_count);
            double Q, H, Eff, Power;
            var fitCurve = cubic_spline_qh.Copy();
            for (int i = 0; i < pt_qp_list.Count; i++)
            var fitCurve = qh.Copy();
            for (int i = 0; i < qp_pt_list.Count; i++)
            {
                Q = pt_qp_list[i].X;
                Power = pt_qp_list[i].Y;
                Q = qp_pt_list[i].X;
                Power = qp_pt_list[i].Y;
                H = fitCurve.GetPointY(Q);
                Eff = CalculateE(Q, H, Power, midu);
                pt_qe_list.Add(new Yw.Geometry.Point2d(Q, Eff));
                qe_pt_list.Add(new Yw.Geometry.Point2d(Q, Eff));
            }
            bool is_x_start_0 = true;
            if (pt_qe_list.First().X > 500 || pt_qe_list.First().X > pt_qe_list.Last().X * 0.1)
            if (qe_pt_list.First().X > 500 || qe_pt_list.First().X > qe_pt_list.Last().X * 0.1)
            {
                is_x_start_0 = false;
            }
@@ -1271,73 +1274,73 @@
            //保证Q=0时,Eff=0;
            if (is_x_start_0)
            {
                pt_qe_list[0] = new Yw.Geometry.Point2d(0, 0);
                pt_qe_list = pt_qe_list.GetFitPointList();
                return pt_qe_list.AmendByZeroPointY(pt_qe_list[3].X, 0);
                qe_pt_list[0] = new Yw.Geometry.Point2d(0, 0);
                qe_pt_list = qe_pt_list.GetFitPointList();
                return qe_pt_list.AmendByZeroPointY(qe_pt_list[3].X, 0);
            }
            else
            {
                return pt_qe_list.GetFitPointList();
                return qe_pt_list.GetFitPointList();
            }
        }
        /// <summary>
        /// 注意此方法 返回的点没有拟合
        /// </summary>
        /// <param name="pt_qh_list"></param>
        /// <param name="pt_qp_list"></param>
        /// <param name="qh_pt_list"></param>
        /// <param name="qp_pt_list"></param>
        /// <param name="midu"></param>
        /// <param name="is_x_start_0"></param>
        /// <returns></returns>
        public static List<Yw.Geometry.Point2d> CalculateE_AlignPointP(
            List<Yw.Geometry.Point2d> pt_qh_list,
            List<Yw.Geometry.Point2d> pt_qp_list,
            List<Yw.Geometry.Point2d> qh_pt_list,
            List<Yw.Geometry.Point2d> qp_pt_list,
            double midu, bool is_x_start_0)
        {
            if (pt_qh_list == null || pt_qh_list.Count < 3)
            if (qh_pt_list == null || qh_pt_list.Count < 3)
                return null;
            if (pt_qp_list == null || pt_qp_list.Count < 3)
            if (qp_pt_list == null || qp_pt_list.Count < 3)
                return null;
            List<Yw.Geometry.Point2d> pt_qe_list = new List<Yw.Geometry.Point2d>();
            List<Yw.Geometry.Point2d> qe_pt_list = new List<Yw.Geometry.Point2d>();
            if (pt_qh_list.IsEqualValueX(pt_qp_list))
            if (qh_pt_list.IsEqualValueX(qp_pt_list))
            {   //x都一致
                for (int i = 0; i < pt_qp_list.Count; i++)
                for (int i = 0; i < qp_pt_list.Count; i++)
                {
                    double Q, H, Eff, Power;
                    Q = pt_qp_list[i].X;
                    Power = pt_qp_list[i].Y;
                    H = pt_qh_list[i].Y;
                    Q = qp_pt_list[i].X;
                    Power = qp_pt_list[i].Y;
                    H = qh_pt_list[i].Y;
                    Eff = CalculateE(Q, H, Power, midu);
                    pt_qe_list.Add(new Yw.Geometry.Point2d(Q, Eff));
                    qe_pt_list.Add(new Yw.Geometry.Point2d(Q, Eff));
                }
            }
            else
            {
                var fitCurve_QP = new Yw.Geometry.CubicSpline2d(pt_qp_list);
                var fitCurve_QH = new Yw.Geometry.CubicSpline2d(pt_qh_list);
                for (int i = 0; i < pt_qp_list.Count; i++)
                var fitCurve_QP = new Yw.Geometry.CubicSpline2d(qp_pt_list);
                var fitCurve_QH = new Yw.Geometry.CubicSpline2d(qh_pt_list);
                for (int i = 0; i < qp_pt_list.Count; i++)
                {
                    double Q, H, Eff, Power;
                    Q = pt_qp_list[i].X;
                    Q = qp_pt_list[i].X;
                    Power = fitCurve_QP.GetPointY(Q);
                    H = fitCurve_QH.GetPointY(Q);
                    Eff = CalculateE(Q, H, Power, midu);
                    pt_qe_list.Add(new Yw.Geometry.Point2d(Q, Eff));
                    qe_pt_list.Add(new Yw.Geometry.Point2d(Q, Eff));
                }
            }
            //pt_qe_list = FitHelper.GetPointListByExtend(pt_qe_list);
            //qe_pt_list = FitHelper.GetPointListByExtend(qe_pt_list);
            //保证Q=0时,Eff=0;
            if (is_x_start_0)
            {
                pt_qe_list[0] = new Yw.Geometry.Point2d(0, 0);
                qe_pt_list[0] = new Yw.Geometry.Point2d(0, 0);
            }
            return pt_qe_list;
            return qe_pt_list;
        }
        #endregion
@@ -1348,39 +1351,39 @@
        /// <summary>
        /// 计算效率 对其功率
        /// </summary> 
        public static List<Yw.Geometry.Point2d> CalculateELineByP(List<Yw.Geometry.Point2d> pt_qh_list, List<Yw.Geometry.Point2d> pt_qp_list, bool is_x_start_0)
        public static List<Yw.Geometry.Point2d> CalculateELineByP(List<Yw.Geometry.Point2d> qh_pt_list, List<Yw.Geometry.Point2d> qp_pt_list, bool is_x_start_0)
        {
            if (pt_qh_list == null || pt_qh_list.Count < 3)
            if (qh_pt_list == null || qh_pt_list.Count < 3)
            {
                return null;
            }
            if (pt_qp_list == null || pt_qp_list.Count < 3)
            if (qp_pt_list == null || qp_pt_list.Count < 3)
            {
                return null;
            }
            List<Yw.Geometry.Point2d> list = new List<Yw.Geometry.Point2d>();
            if (pt_qh_list.IsEqualValueX(pt_qp_list))
            if (qh_pt_list.IsEqualValueX(qp_pt_list))
            {
                for (int i = 0; i < pt_qp_list.Count; i++)
                for (int i = 0; i < qp_pt_list.Count; i++)
                {
                    double x = pt_qp_list[i].X;
                    double y = pt_qp_list[i].Y;
                    double y2 = pt_qh_list[i].Y;
                    double x = qp_pt_list[i].X;
                    double y = qp_pt_list[i].Y;
                    double y2 = qh_pt_list[i].Y;
                    double y3 = CalculateE(x, y2, y, Constant.WaterDensity);
                    list.Add(new Yw.Geometry.Point2d(x, y3));
                }
            }
            else
            {
                var cubic_spline_qp = new Yw.Geometry.CubicSpline2d(pt_qp_list);
                var cubic_spline_qh = new Yw.Geometry.CubicSpline2d(pt_qh_list);
                for (int j = 0; j < pt_qp_list.Count; j++)
                var qp = new Yw.Geometry.CubicSpline2d(qp_pt_list);
                var qh = new Yw.Geometry.CubicSpline2d(qh_pt_list);
                for (int j = 0; j < qp_pt_list.Count; j++)
                {
                    double x2 = pt_qp_list[j].X;
                    double fit_pointY = cubic_spline_qp.GetPointY(x2);
                    double fit_pointY2 = cubic_spline_qh.GetPointY(x2);
                    double x2 = qp_pt_list[j].X;
                    double fit_pointY = qp.GetPointY(x2);
                    double fit_pointY2 = qh.GetPointY(x2);
                    double y4 = CalculateE(x2, fit_pointY2, fit_pointY, Constant.WaterDensity);
                    list.Add(new Yw.Geometry.Point2d(x2, y4));
                }
@@ -1398,26 +1401,26 @@
        /// <summary>
        /// 计算效率 对其效率
        /// </summary> 
        public static List<Yw.Geometry.Point2d> CalculateP_AlignPointE(List<Yw.Geometry.Point2d> pt_qh_list, List<Yw.Geometry.Point2d> pt_qe_list, double midu, double ref_zero_power, bool is_x_start_0)
        public static List<Yw.Geometry.Point2d> CalculateP_AlignPointE(List<Yw.Geometry.Point2d> qh_pt_list, List<Yw.Geometry.Point2d> qe_pt_list, double midu, double ref_zero_power, bool is_x_start_0)
        {
            if (pt_qh_list == null || pt_qh_list.Count < 3)
            if (qh_pt_list == null || qh_pt_list.Count < 3)
            {
                return null;
            }
            if (pt_qe_list == null || pt_qe_list.Count < 3)
            if (qe_pt_list == null || qe_pt_list.Count < 3)
            {
                return null;
            }
            List<Yw.Geometry.Point2d> list = new List<Yw.Geometry.Point2d>();
            if (pt_qh_list.IsEqualValueX(pt_qe_list))
            if (qh_pt_list.IsEqualValueX(qe_pt_list))
            {
                for (int i = 0; i < pt_qe_list.Count(); i++)
                for (int i = 0; i < qe_pt_list.Count(); i++)
                {
                    double x = pt_qe_list[i].X;
                    double y = pt_qe_list[i].Y;
                    double y2 = pt_qh_list[i].Y;
                    double x = qe_pt_list[i].X;
                    double y = qe_pt_list[i].Y;
                    double y2 = qh_pt_list[i].Y;
                    if (!(y2 < 0.1) && !(y < 0.5))
                    {
                        double num = CalculateP(x, y2, y, midu);
@@ -1428,13 +1431,13 @@
            }
            else
            {
                var cubic_spline_qe = new Yw.Geometry.CubicSpline2d(pt_qe_list);
                var cubic_spline_qh = new Yw.Geometry.CubicSpline2d(pt_qh_list);
                for (int j = 0; j < pt_qe_list.Count(); j++)
                var qe = new Yw.Geometry.CubicSpline2d(qe_pt_list);
                var qh = new Yw.Geometry.CubicSpline2d(qh_pt_list);
                for (int j = 0; j < qe_pt_list.Count(); j++)
                {
                    double x2 = pt_qe_list[j].X;
                    double fit_pointY = cubic_spline_qe.GetPointY(x2);
                    double fit_pointY2 = cubic_spline_qh.GetPointY(x2);
                    double x2 = qe_pt_list[j].X;
                    double fit_pointY = qe.GetPointY(x2);
                    double fit_pointY2 = qh.GetPointY(x2);
                    if (!(fit_pointY2 < 0.09) && !(fit_pointY < 0.5))
                    {
                        double num2 = CalculateP(x2, fit_pointY2, fit_pointY, midu);
@@ -1500,7 +1503,199 @@
        #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
    }
}