using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
|
|
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<IStation.Model.CurvePoint> 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 * 0.2)
|
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<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
|
double a = Math.Log10(simularPoint.Y) / Math.Log10(simularPoint.X);
|
if (a < 0.0001)
|
return sectPoint;
|
|
//所有的线上的点取对数
|
List<IStation.Model.CurvePoint> CurvePointsLn = new List<IStation.Model.CurvePoint>();
|
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;
|
}
|
|
}
|
|
}
|