using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace IStation.Model { //抛物线 Parabola : H=K*Q^2 + S (流量扬程线) public class ParabolaCurveHelper_H { //通过点simularPoint和点(0,0)的抛物线,与曲线Curve的交点(没有,返回Point(0,0)) //曲线公式:H=K*Q^2+S (S就是equipCurveZeroH装置曲线静扬程) //equipCurveZeroH是装置曲线的静扬程,当Q=0时的扬程 public static IStation.Model.CurvePoint GetSectPoint(IStation.Model.CurveExpress curveExpress, IStation.Model.CurvePoint simularPoint, double equipCurveZeroH) { var points = IStation.Model.FitCurveHelper.GetFitPointsByExtend(curveExpress, 1.2, 50); return GetSectPoint(points, simularPoint, equipCurveZeroH); } public static IStation.Model.CurvePoint GetSectPoint(IStation.Model.CurveExpress curveExpress, IStation.Model.CurvePoint simularPoint, double equipCurveZeroH, double ratioExtend) { var points = IStation.Model.FitCurveHelper.GetFitPointsByExtend(curveExpress, ratioExtend, 50); return GetSectPoint(points, simularPoint, equipCurveZeroH); } //通过点simularPoint和点(0,0)的抛物线,与曲线Curve的交点(没有,返回Point(0,0)) //曲线公式:H=K*Q^2+S (S就是equipCurveZeroH装置曲线静扬程) //S是装置曲线的静扬程,当Q=0时的扬程 public static IStation.Model.CurvePoint GetSectPoint(List CurvePoints, IStation.Model.CurvePoint simularPoint, double equipCurveZeroH) { IStation.Model.CurvePoint sectPoint = new IStation.Model.CurvePoint(0, 0); if (CurvePoints == null || CurvePoints.Count < 2) return sectPoint; if (simularPoint.X < CurvePoints.First().X) return sectPoint; //if (DesignPoint.X > CurvePoints.Last().X) // return sectPoint; //计算抛物线的K (a) if (simularPoint.X < 0.1) return sectPoint; double a = (simularPoint.Y - equipCurveZeroH) / (simularPoint.X * simularPoint.X); if (a < 0.0001) GetSectPointLn(CurvePoints, simularPoint); //2点连成直线与抛物线的交点,判断交点是否在2点之间,即可是曲线的交点 double b, c; double delta = 0; double j1, j2; for (int i = 0; i < CurvePoints.Count - 1; i++) { IStation.Model.CurveLineHelper.GetKandB(CurvePoints[i], CurvePoints[i + 1], out b, out c, 0.0000000001); c = c - equipCurveZeroH; //解方程 ax2-bx-c=0 delta = b * b + 4 * a * c; if (delta < 0) continue; j1 = (b + Math.Sqrt(delta)) / (2 * a); if (IStation.Common.PointHelper.IsMiddlePt(CurvePoints[i].X, CurvePoints[i + 1].X, j1)) { sectPoint.X = j1; sectPoint.Y = b * j1 + c + equipCurveZeroH; return sectPoint; } j2 = (b - Math.Sqrt(delta)) / (2 * a); if (IStation.Common.PointHelper.IsMiddlePt(CurvePoints[i].X, CurvePoints[i + 1].X, j2)) { sectPoint.X = j2; sectPoint.Y = b * j2 + c + equipCurveZeroH; return sectPoint; } } return sectPoint; } //通过点simularPoint和点(0,0)的抛物线,与曲线Curve的交点(没有,返回Point(0,0)):当流量特别大,H比较小时用 //曲线公式:H=K*Q^2,然后两边取对数 protected static IStation.Model.CurvePoint GetSectPointLn(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 double a = Math.Log10(simularPoint.Y) / Math.Log10(simularPoint.X); if (a < 0.0001) return sectPoint; //所有的线上的点取对数 List CurvePointsLn = new List(); for (int i = 0; i < CurvePoints.Count; i++) { if (CurvePoints[i].X > 1)//防止第一个点:X=0 CurvePointsLn.Add(new IStation.Model.CurvePoint(Math.Log10(CurvePoints[i].X), Math.Log10(CurvePoints[i].Y))); } //与2点连成直线的交点,判断交点是否在2点之间,即可是曲线的交点 double b, c; double x; for (int i = 0; i < CurvePointsLn.Count - 1; i++) { IStation.Model.CurveLineHelper.GetKandB(CurvePointsLn[i], CurvePointsLn[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(CurvePointsLn[i].X, CurvePointsLn[i + 1].X, x)) { sectPoint.X = Math.Pow(10, x); sectPoint.Y = Math.Pow(10, a * x); return sectPoint; } } return sectPoint; } } /// /// 抛物线 Parabola : y = K * Q^2 + B * Q; /// public class ParabolaCurveHelper_E { /// /// 任意两点 /// /// /// /// /// /// public static bool GetCurvePara(IStation.Model.CurvePoint pt1, IStation.Model.CurvePoint pt2,out double K ,out double B) { //抛物线拟合 y=ax2+bx; double y1 = pt1.Y ; double x1 = pt1.X; double y2 = pt2.Y; double x2 = pt2.X; K = (y1 * x2 - y2 * x1) / (x1 * x1 * x2 - x2 * x2 * x1); B = (y1 * x2 * x2 - y2 * x1 * x1) / (x1 * x2 * x2 - x2 * x1 * x1); return true; } //工作点和高效点 public static bool GetCurveParaByBEP(IStation.Model.CurvePoint wrkPt, double bep_q,out double bep_eta, out double K, out double B) { //抛物线拟合 //思路 Y=0时, X=0或 -B/K //所以 bep_q = -B/K * 0.5 K = wrkPt.Y / (wrkPt.X * wrkPt.X - 2 * bep_q * wrkPt.X); B = -2 * K * bep_q; bep_eta = K * bep_q * bep_q + B * bep_q; //if (bep_eta > 0.95) //{ //} return true; } } //抛物线 Parabola : H = K * Q^2 (装置曲线) public class ParabolaCurveHelper_Z { private double _k = 0; public double GetK() { return _k; } public ParabolaCurveHelper_Z(IStation.Model.CurvePoint pt) { this._k = pt.Y / pt.X / pt.X; } public ParabolaCurveHelper_Z(double x, double y) { this._k = y / x / x ; } public double GetY(double x) { return x * x * this._k; } public double GetX(double y) { return Math.Sqrt(y * this._k); } //计算从x1到x2的弧长 public double CalcCurveLengthByX(double pt1_x, double pt2_x) { //思路是从按直线叠加 double x1 = pt1_x; double x2 = pt2_x; if (pt1_x > pt2_x) { x1 = pt2_x; x2 = pt1_x; } double space = (x2 - x1) / 1200; double x_last = x1; double y_last = GetY(x1); double total_length = 0; for (int i = 1; i <= 1200; i++ ) { double x = x1 + space * i; double y = GetY(x); double sub_length = Math.Sqrt((x - x_last) * (x - x_last) + (y - y_last) * (y - y_last)); x_last = x; y_last = y; total_length += sub_length; } return total_length; } //计算点的位置, x1到x2弧长的摆放路 public IStation.Model.CurvePoint CalcPointPosiByX(double x1, double x2, double length_ratio) { if (length_ratio < 0.001) { return new IStation.Model.CurvePoint(x1, GetY(x1)); } //思路是从按直线叠加 int point_number = 1800; double space = (x2 - x1) / point_number; double x_last = x1; double y_last = GetY(x1); double total_length = 0; for (int i = 1; i <= point_number; i++) { double x = x1 + space * i; double y = GetY(x); double len = Math.Sqrt((x - x_last) * (x - x_last) + (y - y_last) * (y - y_last)); x_last = x; y_last = y; total_length += len; } double calc_length = total_length * length_ratio; double len2 = 0; x_last = x1; y_last = GetY(x1); for (int i = 1; i <= point_number; i++) { double x = x1 + space * i; double y = GetY(x); double len = Math.Sqrt((x - x_last) * (x - x_last) + (y - y_last) * (y - y_last)); x_last = x; y_last = y; len2 += len; if (len2 > calc_length) { return new IStation.Model.CurvePoint(x, y); } } return new IStation.Model.CurvePoint(x2,GetY(x2)); } public IStation.Model.CurvePoint CalcPointPosi(IStation.Model.CurvePoint pt1, IStation.Model.CurvePoint pt2, double length_ratio) { return CalcPointPosiByX(pt1.X, pt2.X, length_ratio); } //计算点x在弧长(x1->x2)中的百分率 public double CalcPointRatioByX(double x1, double x2, double x_center ) { double length1 = CalcCurveLengthByX(x1, x2); double length2 = CalcCurveLengthByX(x1, x_center); return length2 / length1; } public double CalcPointRatio(IStation.Model.CurvePoint pt1, IStation.Model.CurvePoint pt2, double x_center) { double length1 = CalcCurveLengthByX(pt1.X, pt2.X); double length2 = CalcCurveLengthByX(pt1.X, x_center); return length2 / length1; } } }