using Yw.Pump;
|
using Yw.WinFrmUI.Phart;
|
|
namespace HStation.WinFrmUI
|
{
|
//等效线辅助类
|
public class EqualParaCurveEListHelper
|
{
|
#region 最大曲线
|
/// <summary>
|
/// 等效线与最大曲线的交点(注意 只适合最大的扬程线,其余流量扬程线要用切割找交点的方法)
|
/// </summary>
|
/// <param name="equalCurveListE"></param>
|
/// <param name="maxCurveQH"></param>
|
/// <param name="igonre_h"></param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> GetSectPoints2MaxFeatCurve(
|
List<EqualEViewModel> equalCurveListE,
|
Yw.Pump.CurveQH maxCurveQH,
|
double igonre_h)//保证靠的太近可以认为相交)
|
{
|
return GetSectPoints2MaxFeatCurve4QH(equalCurveListE, maxCurveQH, igonre_h);
|
}
|
|
/// <summary>
|
/// 返回QH点 (注意 只适合最大的扬程线)
|
/// </summary>
|
/// <param name="equalCurveListE"></param>
|
/// <param name="maxCurveQH"></param>
|
/// <param name="igonre_h"></param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> GetSectPoints2MaxFeatCurve4QH(
|
List<EqualEViewModel> equalCurveListE,
|
Yw.Pump.CurveQH maxCurveQH,
|
double igonre_h)//保证靠的太近可以认为相交)
|
{
|
List<Yw.Geometry.Point2d> define_points = null;
|
if (equalCurveListE == null || equalCurveListE.Count < 3 || maxCurveQH == null)
|
{
|
return null;
|
}
|
|
//
|
define_points = new List<Yw.Geometry.Point2d>();
|
|
//
|
foreach (var curve in equalCurveListE)
|
{
|
if (curve.DefinePoints == null || curve.DefinePoints.Count == 0)
|
continue;
|
if (curve.DefinePoints.Count == 1)
|
{ //添加单点
|
define_points.Add(new Yw.Geometry.Point2d(curve.DefinePoints.First().X, curve.DefinePoints.First().Y));
|
}
|
else
|
{
|
//注意两端都可能有交点
|
var firstPointY = maxCurveQH.FeatCurve.GetPointY(curve.DefinePoints.First().X);
|
if ((Math.Abs(firstPointY - curve.DefinePoints.First().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.DefinePoints.First().X, curve.DefinePoints.First().Y));
|
}
|
|
var lastPointY = maxCurveQH.FeatCurve.GetPointY(curve.DefinePoints.Last().X);
|
if ((Math.Abs(lastPointY - curve.DefinePoints.Last().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.DefinePoints.Last().X, curve.DefinePoints.Last().Y));
|
}
|
}
|
}
|
|
return define_points;
|
}
|
|
/// <summary>
|
/// 返回QE点 (注意 只适合最大的扬程线)
|
/// </summary>
|
/// <param name="equalCurveListE"></param>
|
/// <param name="maxCurveQH"></param>
|
/// <param name="igonre_h"></param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> GetSectPoints2MaxFeatCurve4QE(
|
List<EqualEViewModel> equalCurveListE,
|
Yw.Pump.CurveQH maxCurveQH,
|
double igonre_h)//保证靠的太近可以认为相交)
|
{
|
List<Yw.Geometry.Point2d> define_points = null;
|
if (equalCurveListE == null || equalCurveListE.Count < 3 || maxCurveQH == null)
|
{
|
return null;
|
}
|
|
//
|
define_points = new List<Yw.Geometry.Point2d>();
|
|
//
|
foreach (EqualEViewModel curve in equalCurveListE)
|
{
|
if (curve.DefinePoints == null || curve.DefinePoints.Count == 0)
|
continue;
|
if (curve.DefinePoints.Count == 1)
|
{ //添加单点
|
define_points.Add(new Yw.Geometry.Point2d(curve.DefinePoints.First().X, curve.Eff));
|
}
|
else
|
{
|
//注意两端都可能有交点
|
var firstPointY = maxCurveQH.FeatCurve.GetPointY(curve.DefinePoints.First().X);
|
if ((Math.Abs(firstPointY - curve.DefinePoints.First().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.DefinePoints.First().X, curve.Eff));
|
}
|
|
var lastPointY = maxCurveQH.FeatCurve.GetPointY(curve.DefinePoints.Last().X);
|
if ((Math.Abs(lastPointY - curve.DefinePoints.Last().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.DefinePoints.Last().X, curve.Eff));
|
}
|
}
|
}
|
|
return define_points;
|
}
|
|
///// <summary>
|
///// 将等效线换算成效率性能曲线:只能针对离心泵 (注意 只适合最大的扬程线,其余流量扬程线要用切割找交点的方法)
|
///// </summary>
|
///// <param name="equalCurveListE"></param>
|
///// <param name="maxCurveQH"></param>
|
///// <param name="maxCurveQE_Origin"></param>
|
///// <param name="igonre_h"></param>
|
///// <param name="define_points_qe"></param>
|
///// <returns></returns>
|
//public static Yw.Pump.CurveQE CalcCurveQE4Max(
|
// List<EqualEViewModel> equalCurveListE,
|
// Yw.Pump.CurveQH maxCurveQH,
|
// Yw.Pump.CurveQE maxCurveQE_Origin,//原来的
|
// double igonre_h,//保证靠的太近可以认为相交
|
// out List<Yw.Geometry.Point2d> define_points_qe)
|
//{
|
// define_points_qe = null;
|
// if (equalCurveListE == null || equalCurveListE.Count < 3)
|
// {
|
// return null;
|
// }
|
// if (igonre_h < 0.01)
|
// {
|
// igonre_h = 0.01;
|
// }
|
// //
|
// define_points_qe = new List<Yw.Geometry.Point2d>();
|
|
// //
|
// foreach (EqualEViewModel curve in equalCurveListE)
|
// {
|
// if (curve.DefinePoints == null || curve.DefinePoints.Count == 0)
|
// continue;
|
// if (curve.DefinePoints.Count == 1)
|
// { //添加单点
|
// define_points_qe.Add(new Yw.Geometry.Point2d(curve.DefinePoints .First().X, curve.Eff));
|
// }
|
// else
|
// {
|
// //注意两端都可能有交点
|
// var firstPointY = maxCurveQH.FeatCurve.GetPointY(curve.DefinePoints.First().X);
|
// if ((Math.Abs(firstPointY - curve.DefinePoints.First().Y) < igonre_h))
|
// {
|
// define_points_qe.Add(new Yw.Geometry.Point2d(curve.DefinePoints.First().X, curve.Eff));
|
// }
|
|
// var lastPointY = maxCurveQH.FeatCurve.GetPointY(curve.DefinePoints.Last().X);
|
// if ((Math.Abs(lastPointY - curve.DefinePoints.Last().Y) < igonre_h))
|
// {
|
// define_points_qe.Add(new Yw.Geometry.Point2d(curve.DefinePoints.Last().X, curve.Eff));
|
// }
|
// }
|
// }
|
// if (define_points_qe.Count < 3)
|
// return null;
|
|
// //插入最大流量点
|
// var maxQ = maxCurveQH.FeatCurve.GetXRange().MaxX;
|
// var maxQ2 = (from x in define_points_qe select x.X).Max();
|
// if (maxQ2 < maxQ * 0.99)
|
// {
|
// //var maxQ_E = define_points_qe.ge.GetPointY(define_points_qe, maxQ);
|
// //define_points_qe.Add(new Yw.Geometry.Point2d(maxQ, maxQ_E));
|
// }
|
|
|
// //排序
|
// define_points_qe.Sort(new Yw.Geometry.Point2d.Comparer(Yw.Geometry.Point2d.eSortType.X));
|
|
|
// var fitTypeQE = Eventech.Model.eCurveFitType.CubicCurve;
|
// //跨度有点大, 中间插入原来的曲线值的点
|
// if (maxCurveQE_Origin != null)
|
// {
|
// fitTypeQE = maxCurveQE_Origin.CurveFitType;
|
// if (define_points_qe[0].X > maxCurveQH.RangeMax / 10)
|
// {
|
// var insert_x = define_points_qe[0].X / 2;
|
// define_points_qe.Insert(0, new Yw.Geometry.Point2d(insert_x, Eventech.Common.FitCurveHelper.GetPointY(maxCurveQE_Origin, insert_x)));
|
// }
|
// }
|
|
// //插入最小点
|
// if (maxCurveQH.RangeMin < maxCurveQH.RangeMax / 20)
|
// {
|
// define_points_qe.Insert(0, new Yw.Geometry.Point2d(0, 0));
|
// }
|
|
|
// //处理高效点
|
// Yw.Geometry.Point2d eta_pt = new Yw.Geometry.Point2d();
|
// foreach (var pt in define_points_qe)
|
// {
|
// if (pt.Y > eta_pt.Y)
|
// {
|
// eta_pt.X = pt.X;
|
// eta_pt.Y = pt.Y;
|
// }
|
// }
|
|
// var points2 = Eventech.Common.AmendCurveHelper.ByOnePointY1(define_points_qe, eta_pt, fitTypeQE);
|
|
// return new Model.CurveExpress(points2, fitTypeQE);
|
//}
|
|
#endregion
|
|
#region 中间的线
|
//根据等效线产生流量效率线(注意 此方法不适合最大的流量扬程线)
|
public static List<Yw.Geometry.Point2d> GetSectPoints2MiddleFeatCurve(
|
List<EqualEViewModel> EqualParaCurvesE,
|
Yw.Pump.CurveQH ExpressCurveQH,
|
Yw.Pump.CurveQE ExpressCurveQE_origin,
|
double igonre_h//保证靠的太近可以认为相交
|
)
|
{
|
List<Yw.Geometry.Point2d> points_qh_效率 = null;
|
List<Yw.Geometry.Point2d> points_qe = null;
|
CalcCurveQE4Middle(EqualParaCurvesE, ExpressCurveQH, ExpressCurveQE_origin, igonre_h, out points_qh_效率, out points_qe);
|
return points_qh_效率;
|
}
|
public static List<Yw.Geometry.Point2d> GetSectPoints2MiddleFeatCurveQH(
|
List<EqualEViewModel> EqualParaCurvesE,
|
Yw.Pump.CurveQH ExpressCurveQH,
|
Yw.Pump.CurveQE ExpressCurveQE_origin,
|
double igonre_h//保证靠的太近可以认为相交
|
)
|
{
|
List<Yw.Geometry.Point2d> points_qh_效率 = null;
|
List<Yw.Geometry.Point2d> points_qe = null;
|
CalcCurveQE4Middle(EqualParaCurvesE, ExpressCurveQH, ExpressCurveQE_origin, igonre_h, out points_qh_效率, out points_qe);
|
return points_qh_效率;
|
}
|
|
|
//根据等效线产生流量效率线(注意 此方法不适合最大的流量扬程线)
|
public static Yw.Pump.CurveQE CalcCurveQE4Middle(
|
List<EqualEViewModel> EqualParaCurvesE,
|
Yw.Pump.CurveQH ExpressCurveQH,
|
Yw.Pump.CurveQE ExpressCurveQE_origin,
|
double igonre_h,
|
out List<Yw.Geometry.Point2d> points_qe)
|
{
|
List<Yw.Geometry.Point2d> points_qh_效率 = null;
|
return CalcCurveQE4Middle(EqualParaCurvesE, ExpressCurveQH, ExpressCurveQE_origin, igonre_h, out points_qh_效率, out points_qe);
|
}
|
|
|
//根据等效线产生流量效率线(注意 此方法不适合最大的流量扬程线)
|
public static Yw.Pump.CurveQE CalcCurveQE4Middle(
|
List<EqualEViewModel> EqualParaCurvesE,
|
Yw.Pump.CurveQH ExpressCurveQH,
|
Yw.Pump.CurveQE ExpressCurveQE_origin,
|
double igonre_h,//保证靠的太近可以认为相交
|
out List<Yw.Geometry.Point2d> points_qh_效率,//EqualParaCurvesE 与 ExpressCurveQH 的相交线
|
out List<Yw.Geometry.Point2d> points_qe)//定义的流量效率线上的点
|
{
|
return CalcCurveQESimu(EqualParaCurvesE, ExpressCurveQH, ExpressCurveQE_origin, igonre_h, false, out points_qh_效率, out points_qe);
|
}
|
|
/// <summary>
|
/// 不会延长到首尾, 仅仅求交点
|
/// </summary>
|
/// <param name="EqualParaCurvesE"></param>
|
/// <param name="ExpressCurveQH"></param>
|
/// <param name="ExpressCurveQE_origin"></param>
|
/// <param name="igonre_h"></param>
|
/// <param name="isCheckEndPt"></param>
|
/// <param name="points_qh_效率"></param>
|
/// <param name="points_qh"></param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> GetSectPoints2MiddleFeatCurveQE(
|
List<EqualEViewModel> EqualParaCurvesE,
|
Yw.Pump.CurveQH ExpressCurveQH,
|
double igonre_h,//保证靠的太近可以认为相交
|
bool isCheckEndPt,
|
out List<Yw.Geometry.Point2d> points_head)//定义的流量QH线上的点
|
{
|
double max_eta_flow = 0;
|
return GetSectPoints2MiddleFeatCurveQE(EqualParaCurvesE, ExpressCurveQH, igonre_h, isCheckEndPt, out points_head, out max_eta_flow);
|
}
|
|
/// <summary>
|
/// 不会延长到首尾, 仅仅求交点
|
/// </summary>
|
/// <param name="EqualParaCurvesE"></param>
|
/// <param name="ExpressCurveQH"></param>
|
/// <param name="ExpressCurveQE_origin"></param>
|
/// <param name="igonre_h"></param>
|
/// <param name="isCheckEndPt"></param>
|
/// <param name="points_qh_效率"></param>
|
/// <param name="points_qh"></param>
|
/// <returns></returns>
|
private static List<Yw.Geometry.Point2d> GetSectPoints2MiddleFeatCurveQE(
|
List<EqualEViewModel> EqualParaCurvesE,
|
Yw.Pump.CurveQH ExpressCurveQH,
|
double igonre_h,//保证靠的太近可以认为相交
|
bool isCheckEndPt,
|
out List<Yw.Geometry.Point2d> points_head,
|
out double max_eta_flow)//定义的流量QH线上的点
|
{
|
max_eta_flow = 0;
|
points_head = null;
|
if (EqualParaCurvesE == null || EqualParaCurvesE.Count < 3)
|
return null;
|
|
|
points_head = new List<Yw.Geometry.Point2d>();
|
var points_eta = new List<Yw.Geometry.Point2d>();
|
|
//等效线集合循环
|
|
double max_eta = 0;
|
for (int kk = 0; kk < EqualParaCurvesE.Count; kk++)
|
{
|
var curveE = EqualParaCurvesE[kk];
|
if (curveE.DefinePoints == null || curveE.DefinePoints.Count == 0)
|
continue;
|
|
if (curveE.Eff > max_eta)
|
{
|
max_eta = curveE.Eff;
|
max_eta_flow = curveE.DefinePoints[0].X;
|
}
|
|
|
|
|
if (curveE.DefinePoints.Count == 1)
|
{// 点
|
var pt = curveE.DefinePoints[0];
|
|
if (igonre_h < 0.01)//保证靠的太近可以认为相交
|
igonre_h = pt.Y / 100;
|
|
var fit_y1 = ExpressCurveQH.FeatCurve.GetPointY(pt.X);
|
//
|
if (Math.Abs(fit_y1 - pt.Y) < igonre_h)
|
{
|
points_head.Add(pt);
|
points_eta.Add(new Yw.Geometry.Point2d(pt.X, curveE.Eff));
|
}
|
continue;
|
}
|
|
if (igonre_h < 0.01)//保证靠的太近可以认为相交
|
{
|
var yyy = from x in curveE.DefinePoints select x.Y;
|
igonre_h = Math.Abs(yyy.Max() - yyy.Min()) / 10;
|
}
|
|
//判断是否就是等效线的端点
|
if (isCheckEndPt)
|
{
|
var min_y_pt = curveE.DefinePoints.OrderBy(x => x.Y).FirstOrDefault();
|
var fit_y_2 = ExpressCurveQH.FeatCurve.GetPointY(min_y_pt.X);
|
//
|
if (Math.Abs(fit_y_2 - min_y_pt.Y) < igonre_h)
|
{
|
points_head.Add(min_y_pt);
|
points_eta.Add(new Yw.Geometry.Point2d(min_y_pt.X, curveE.Eff));
|
|
continue;
|
}
|
}
|
|
|
|
if (curveE.DefinePoints.Count == 2)
|
{
|
#region Line
|
var start0_p = curveE.DefinePoints[0];
|
var end0_p = curveE.DefinePoints[1];
|
|
var start0_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(start0_p.X);
|
var end0_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(end0_p.X);
|
//直线于曲线相交
|
if ((start0_p_y_1 <= start0_p.Y && end0_p_y_1 >= end0_p.Y) || (start0_p_y_1 >= start0_p.Y && end0_p_y_1 <= end0_p.Y))
|
{
|
var x = (start0_p.X + end0_p.X) / 2;
|
var y = ExpressCurveQH.FeatCurve.GetPointY(x);
|
var p = new Yw.Geometry.Point2d(x, y);
|
points_head.Add(p);
|
points_eta.Add(new Yw.Geometry.Point2d(x, curveE.Eff));
|
}
|
else
|
{
|
double min_dis_y = double.MaxValue;
|
var min_pt = new Yw.Geometry.Point2d();
|
|
var startY_1 = ExpressCurveQH.FeatCurve.GetPointY(curveE.DefinePoints[0].X);
|
if (Math.Abs(startY_1 - curveE.DefinePoints[0].Y) < min_dis_y)
|
{
|
min_dis_y = Math.Abs(startY_1 - curveE.DefinePoints[0].Y);
|
min_pt.X = curveE.DefinePoints[0].X;
|
min_pt.Y = startY_1;
|
}
|
|
var endY_1 = ExpressCurveQH.FeatCurve.GetPointY(curveE.DefinePoints[1].X);
|
if (Math.Abs(endY_1 - curveE.DefinePoints[1].Y) < min_dis_y)
|
{
|
min_dis_y = Math.Abs(endY_1 - curveE.DefinePoints[1].Y);
|
min_pt.X = curveE.DefinePoints[1].X;
|
min_pt.Y = startY_1;
|
}
|
|
if (min_dis_y < igonre_h)
|
{//很近就认为相交了
|
points_head.Add(min_pt);
|
points_eta.Add(new Yw.Geometry.Point2d(min_pt.X, curveE.Eff));
|
}
|
}
|
continue;
|
|
#endregion
|
}
|
|
|
|
|
|
|
|
|
if (curveE.DefinePoints.Count == 3)
|
{//
|
#region 三个点只能用二次贝塞尔曲线
|
List<Yw.Geometry.Point2d> current_sect_pts_qh = new List<Yw.Geometry.Point2d>();
|
List<Yw.Geometry.Point2d> current_sect_pts_qe = new List<Yw.Geometry.Point2d>();
|
|
Yw.Geometry.BezierCurve2 bezeir = new Yw.Geometry.BezierCurve2();
|
bezeir.Point0 = curveE.DefinePoints[0];
|
bezeir.Point1 = curveE.DefinePoints[1];
|
bezeir.Point2 = curveE.DefinePoints[2];
|
|
if (igonre_h < 0.01)//保证靠的太近可以认为相交
|
{
|
var yyy = from x in curveE.DefinePoints select x.Y;
|
igonre_h = Math.Abs(yyy.Max() - yyy.Min()) / 15;
|
}
|
|
#region 贝塞尔曲线集合循环
|
var startY_1 = ExpressCurveQH.FeatCurve.GetPointY(bezeir.Point0.X);
|
var endY_1 = ExpressCurveQH.FeatCurve.GetPointY(bezeir.Point2.X);
|
//贝塞尔曲线与性能曲线有交点
|
if ((startY_1 <= bezeir.Point0.Y && endY_1 >= bezeir.Point2.Y) || (startY_1 >= bezeir.Point0.Y && endY_1 <= bezeir.Point2.Y))
|
{
|
//第一次循环
|
for (int i = 0; i < 10; i++)
|
{
|
var start0_uu = i * 0.1;
|
var end0_uu = start0_uu + 0.1;
|
var start0_p_x = bezeir.GetX(start0_uu);
|
var start0_p_y = bezeir.GetY(start0_uu);
|
var end0_p_x = bezeir.GetX(end0_uu);
|
var end0_p_y = bezeir.GetY(end0_uu);
|
var start0_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(start0_p_x);
|
var end0_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(end0_p_x);
|
if ((start0_p_y_1 <= start0_p_y && end0_p_y_1 >= end0_p_y) || (start0_p_y_1 >= start0_p_y && end0_p_y_1 <= end0_p_y))
|
{
|
//第二次循环
|
for (int j = 0; j < 10; j++)
|
{
|
var start1_uu = start0_uu + j * 0.01;
|
var end1_uu = start1_uu + 0.01;
|
var start1_p_x = bezeir.GetX(start1_uu);
|
var start1_p_y = bezeir.GetY(start1_uu);
|
var end1_p_x = bezeir.GetX(end1_uu);
|
var end1_p_y = bezeir.GetY(end1_uu);
|
var start1_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(start1_p_x);
|
var end1_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(end1_p_x);
|
if ((start1_p_y_1 <= start1_p_y && end1_p_y_1 >= end1_p_y) || (start1_p_y_1 >= start1_p_y && end1_p_y_1 <= end1_p_y))
|
{
|
//第三次循环
|
for (int k = 0; k < 10; k++)
|
{
|
var start2_uu = start1_uu + k * 0.001;
|
var end2_uu = start2_uu + 0.001;
|
var start2_p_x = bezeir.GetX(start2_uu);
|
var start2_p_y = bezeir.GetY(start2_uu);
|
var end2_p_x = bezeir.GetX(end2_uu);
|
var end2_p_y = bezeir.GetY(end2_uu);
|
var start2_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(start2_p_x);
|
var end2_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(end2_p_x);
|
if ((start2_p_y_1 <= start2_p_y && end2_p_y_1 >= end2_p_y) || (start2_p_y_1 >= start2_p_y && end2_p_y_1 <= end2_p_y))
|
{
|
var x = (start2_p_x + end2_p_x) / 2;
|
var y = ExpressCurveQH.FeatCurve.GetPointY(x);
|
var p = new Yw.Geometry.Point2d(x, y);
|
current_sect_pts_qh.Add(p);
|
current_sect_pts_qe.Add(new Yw.Geometry.Point2d(x, curveE.Eff));
|
break;
|
}
|
}
|
break;
|
}
|
}
|
break;
|
}
|
|
}
|
}
|
#endregion
|
|
|
|
#region 没有交点,但可能和曲线弯曲有交点, 用离散点求最小距离
|
|
double min_dis_y = double.MaxValue;
|
var min_pt = new Yw.Geometry.Point2d();
|
|
for (int i = 0; i < 30; i++)
|
{
|
var bsr_uu = i * 1.0 / 29.0;
|
var bsr_pt_x = bezeir.GetX(bsr_uu);
|
var bsr_pt_y = bezeir.GetY(bsr_uu);
|
|
var fit_pt_y = ExpressCurveQH.FeatCurve.GetPointY(bsr_pt_x);
|
|
if (Math.Abs(fit_pt_y - bsr_pt_y) < min_dis_y)
|
{
|
min_dis_y = Math.Abs(fit_pt_y - bsr_pt_y);
|
min_pt.X = bsr_pt_x;
|
min_pt.Y = fit_pt_y;
|
}
|
}
|
|
if (min_dis_y < igonre_h)
|
{//很近就认为相交了
|
current_sect_pts_qh.Add(min_pt);
|
current_sect_pts_qe.Add(new Yw.Geometry.Point2d(min_pt.X, curveE.Eff));
|
}
|
#endregion
|
|
if (current_sect_pts_qe.Count == 1)
|
{
|
points_head.Add(current_sect_pts_qh.First());
|
points_eta.Add(current_sect_pts_qe.First());
|
}
|
else if (current_sect_pts_qe.Count > 1)
|
{
|
points_head.Add(current_sect_pts_qh.First());
|
points_eta.Add(current_sect_pts_qe.First());
|
|
if (current_sect_pts_qe.Count > 1)
|
{
|
var xxx = (from x in curveE.DefinePoints select x.X);
|
var min_x = xxx.Min();
|
var max_x = xxx.Max();
|
//防制 靠的太近, 重复点
|
for (int k = 1; k < current_sect_pts_qe.Count; k++)
|
{
|
if (Math.Abs(current_sect_pts_qe[k].X - current_sect_pts_qe[0].X) < (max_x - min_x) / 30)
|
continue;
|
points_head.Add(current_sect_pts_qh[k]);
|
points_eta.Add(current_sect_pts_qe[k]);
|
}
|
}
|
}
|
#endregion
|
}
|
else if (curveE.DefinePoints.Count > 3)
|
{
|
List<Yw.Geometry.Point2d> current_sect_pts_qh = new List<Yw.Geometry.Point2d>();
|
List<Yw.Geometry.Point2d> current_sect_pts_qe = new List<Yw.Geometry.Point2d>();
|
|
List<Yw.Geometry.BezierSpline> allBeziers = null;
|
//获取所有的贝塞尔曲线
|
if (curveE.IsClosed)
|
{
|
allBeziers = Yw.Geometry.BezierCurveHelper.CreateCloseCurves(curveE.DefinePoints.ToArray());
|
}
|
else
|
{
|
allBeziers = Yw.Geometry.BezierCurveHelper.CreateOpenCurves(curveE.DefinePoints.ToArray());
|
}
|
if (allBeziers == null)
|
continue;
|
|
if (igonre_h < 0.01)//保证靠的太近可以认为相交
|
{
|
var yyy = from x in curveE.DefinePoints select x.Y;
|
igonre_h = Math.Abs(yyy.Max() - yyy.Min()) / 5;
|
}
|
|
foreach (var bezeir in allBeziers)
|
{
|
var startY_1 = ExpressCurveQH.FeatCurve.GetPointY(bezeir.Point0.X);
|
var endY_1 = ExpressCurveQH.FeatCurve.GetPointY(bezeir.Point3.X);
|
//贝塞尔曲线与性能曲线有交点
|
if ((startY_1 <= bezeir.Point0.Y && endY_1 >= bezeir.Point3.Y) || (startY_1 >= bezeir.Point0.Y && endY_1 <= bezeir.Point3.Y))
|
{
|
#region 贝塞尔曲线集合循环
|
//第一次循环
|
for (int i = 0; i < 10; i++)
|
{
|
var start0_uu = i * 0.1;
|
var end0_uu = start0_uu + 0.1;
|
var start0_p_x = bezeir.GetX(start0_uu);
|
var start0_p_y = bezeir.GetY(start0_uu);
|
var end0_p_x = bezeir.GetX(end0_uu);
|
var end0_p_y = bezeir.GetY(end0_uu);
|
var start0_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(start0_p_x);
|
var end0_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(end0_p_x);
|
if ((start0_p_y_1 <= start0_p_y && end0_p_y_1 >= end0_p_y) || (start0_p_y_1 >= start0_p_y && end0_p_y_1 <= end0_p_y))
|
{
|
//第二次循环
|
for (int j = 0; j < 10; j++)
|
{
|
var start1_uu = start0_uu + j * 0.01;
|
var end1_uu = start1_uu + 0.01;
|
var start1_p_x = bezeir.GetX(start1_uu);
|
var start1_p_y = bezeir.GetY(start1_uu);
|
var end1_p_x = bezeir.GetX(end1_uu);
|
var end1_p_y = bezeir.GetY(end1_uu);
|
var start1_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(start1_p_x);
|
var end1_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(end1_p_x);
|
if ((start1_p_y_1 <= start1_p_y && end1_p_y_1 >= end1_p_y) || (start1_p_y_1 >= start1_p_y && end1_p_y_1 <= end1_p_y))
|
{
|
//第三次循环
|
for (int k = 0; k < 10; k++)
|
{
|
var start2_uu = start1_uu + k * 0.001;
|
var end2_uu = start2_uu + 0.001;
|
var start2_p_x = bezeir.GetX(start2_uu);
|
var start2_p_y = bezeir.GetY(start2_uu);
|
var end2_p_x = bezeir.GetX(end2_uu);
|
var end2_p_y = bezeir.GetY(end2_uu);
|
var start2_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(start2_p_x);
|
var end2_p_y_1 = ExpressCurveQH.FeatCurve.GetPointY(end2_p_x);
|
if ((start2_p_y_1 <= start2_p_y && end2_p_y_1 >= end2_p_y) || (start2_p_y_1 >= start2_p_y && end2_p_y_1 <= end2_p_y))
|
{
|
var x = (start2_p_x + end2_p_x) / 2;
|
var y = ExpressCurveQH.FeatCurve.GetPointY(x);
|
var p = new Yw.Geometry.Point2d(x, y);
|
current_sect_pts_qh.Add(p);
|
current_sect_pts_qe.Add(new Yw.Geometry.Point2d(x, curveE.Eff));
|
break;
|
}
|
}
|
break;
|
}
|
}
|
break;
|
}
|
}
|
#endregion
|
}
|
}
|
|
#region 没有交点 ,但可能和曲线弯曲有交点, 用离散点求最小距离
|
double min_dis_y = double.MaxValue;
|
var min_pt = new Yw.Geometry.Point2d();
|
foreach (var bezeir in allBeziers)
|
{
|
for (int i = 0; i < 30; i++)
|
{
|
var bsr_uu = i * 1.0 / 29.0;
|
var bsr_pt_x = bezeir.GetX(bsr_uu);
|
var bsr_pt_y = bezeir.GetY(bsr_uu);
|
|
var fit_pt_y = ExpressCurveQH.FeatCurve.GetPointY(bsr_pt_x);
|
|
if (Math.Abs(fit_pt_y - bsr_pt_y) < min_dis_y)
|
{
|
min_dis_y = Math.Abs(fit_pt_y - bsr_pt_y);
|
min_pt.X = bsr_pt_x;
|
min_pt.Y = fit_pt_y;
|
}
|
}
|
}
|
if (min_dis_y < igonre_h)
|
{//很近就认为相交了
|
current_sect_pts_qh.Add(min_pt);
|
current_sect_pts_qe.Add(new Yw.Geometry.Point2d(min_pt.X, curveE.Eff));
|
}
|
#endregion
|
|
|
if (current_sect_pts_qe.Count == 0)
|
{
|
}
|
else if (current_sect_pts_qe.Count == 1)
|
{
|
points_head.Add(current_sect_pts_qh.First());
|
points_eta.Add(current_sect_pts_qe.First());
|
}
|
else if (current_sect_pts_qe.Count == 2)
|
{
|
var chk_dis = (ExpressCurveQH.FeatCurve.GetXRange().MaxX - ExpressCurveQH.FeatCurve.GetXRange().MinX) / 120;
|
|
points_head.Add(current_sect_pts_qh.First());
|
points_eta.Add(current_sect_pts_qe.First());
|
if (Math.Abs(current_sect_pts_qe[1].X - current_sect_pts_qe[0].X) > chk_dis)
|
{
|
points_head.Add(current_sect_pts_qh[1]);
|
points_eta.Add(current_sect_pts_qe[1]);
|
}
|
}
|
else
|
{
|
points_head.Add(current_sect_pts_qh.First());
|
points_eta.Add(current_sect_pts_qe.First());
|
|
var chk_dis = (ExpressCurveQH.FeatCurve.GetXRange().MaxX - ExpressCurveQH.FeatCurve.GetXRange().MinX) / 120;
|
|
//防制 靠的太近, 重复点
|
for (int k = 1; k < current_sect_pts_qe.Count; k++)
|
{
|
bool isOk = true;
|
if (Math.Abs(current_sect_pts_qe[k].X - current_sect_pts_qe[0].X) < chk_dis)
|
{
|
isOk = false;
|
}
|
|
for (int m = k + 1; m < current_sect_pts_qe.Count; m++)
|
{
|
if (Math.Abs(current_sect_pts_qe[m].X - current_sect_pts_qe[k].X) < chk_dis)
|
{
|
isOk = false;
|
}
|
}
|
|
if (isOk)
|
{
|
points_head.Add(current_sect_pts_qh[k]);
|
points_eta.Add(current_sect_pts_qe[k]);
|
}
|
|
}
|
|
}
|
}
|
|
}
|
|
|
return points_eta = (from x in points_eta orderby x.X select x).ToList();
|
}
|
|
#endregion
|
|
#region 最小曲线
|
public static List<Yw.Geometry.Point2d> GetSectPoints2MinFeatCurve(
|
List<EqualEViewModel> EqualParaCurvesE,
|
Yw.Pump.CurveQH ExpressCurveQH,
|
Yw.Pump.CurveQE ExpressCurveQE_origin,
|
double igonre_h//保证靠的太近可以认为相交
|
)
|
{
|
List<Yw.Geometry.Point2d> points_qh_效率 = null;
|
List<Yw.Geometry.Point2d> points_qe = null;
|
CalcCurveQE4Min(EqualParaCurvesE, ExpressCurveQH, ExpressCurveQE_origin, igonre_h, out points_qh_效率, out points_qe);
|
return points_qh_效率;
|
}
|
/// <summary>
|
/// 返回QE点 (注意 只适合最小的扬程线)
|
/// </summary>
|
/// <param name="equalCurveListE"></param>
|
/// <param name="maxCurveQH"></param>
|
/// <param name="igonre_h"></param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> GetSectPoints2MinFeatCurve4QE(
|
List<EqualEViewModel> equalCurveListE,
|
Yw.Pump.CurveQH maxCurveQH,
|
double igonre_h)//保证靠的太近可以认为相交)
|
{
|
List<Yw.Geometry.Point2d> define_points = null;
|
if (equalCurveListE == null || equalCurveListE.Count < 3 || maxCurveQH == null)
|
{
|
return null;
|
}
|
|
//
|
define_points = new List<Yw.Geometry.Point2d>();
|
|
//
|
foreach (EqualEViewModel curve in equalCurveListE)
|
{
|
if (curve.DefinePoints == null || curve.DefinePoints.Count == 0)
|
continue;
|
if (curve.DefinePoints.Count == 1)
|
{ //添加单点
|
continue;
|
}
|
else
|
{
|
//注意两端都可能有交点
|
var firstPointY = maxCurveQH.FeatCurve.GetPointY(curve.DefinePoints.First().X);
|
if ((Math.Abs(firstPointY - curve.DefinePoints.First().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.DefinePoints.First().X, curve.Eff));
|
}
|
|
var lastPointY = maxCurveQH.FeatCurve.GetPointY(curve.DefinePoints.Last().X);
|
if ((Math.Abs(lastPointY - curve.DefinePoints.Last().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.DefinePoints.Last().X, curve.Eff));
|
}
|
}
|
}
|
|
return define_points;
|
}
|
|
/// <summary>
|
/// 只针对离心泵 最后一条切割线, 最后一条可能是等效线的端点, 不用相交判断,所以需要特殊处理
|
/// </summary>
|
/// <param name="EqualParaCurvesE"></param>
|
/// <param name="ExpressCurveQH"></param>
|
/// <param name="ExpressCurveQE_origin"></param>
|
/// <param name="igonre_h"></param>
|
/// <param name="points_qh_效率"></param>
|
/// <param name="points_qe"></param>
|
/// <returns></returns>
|
public static Yw.Pump.CurveQE CalcCurveQE4Min(
|
List<EqualEViewModel> EqualParaCurvesE,
|
Yw.Pump.CurveQH ExpressCurveQH,
|
Yw.Pump.CurveQE ExpressCurveQE_origin,
|
double igonre_h,//保证靠的太近可以认为相交
|
out List<Yw.Geometry.Point2d> points_qh_效率,//EqualParaCurvesE 与 ExpressCurveQH 的相交线
|
out List<Yw.Geometry.Point2d> points_qe)//定义的流量效率线上的点
|
{
|
return CalcCurveQESimu(EqualParaCurvesE, ExpressCurveQH, ExpressCurveQE_origin, igonre_h, true, out points_qh_效率, out points_qe);
|
}
|
|
|
|
|
#endregion
|
|
|
/// <summary>
|
/// 只针对离心泵
|
/// </summary>
|
/// <param name="EqualParaCurvesE"></param>
|
/// <param name="ExpressCurveQH"></param>
|
/// <param name="ExpressCurveQE_origin"></param>
|
/// <param name="igonre_h"></param>
|
/// <param name="isCheckEndPt"></param>
|
/// <param name="points_qh_效率"></param>
|
/// <param name="points_qe"></param>
|
/// <returns></returns>
|
public static Yw.Pump.CurveQE CalcCurveQESimu(
|
List<EqualEViewModel> EqualParaCurvesE,
|
Yw.Pump.CurveQH ExpressCurveQH,
|
Yw.Pump.CurveQE ExpressCurveQE_origin,
|
double igonre_h,//保证靠的太近可以认为相交
|
bool isCheckEndPt,
|
out List<Yw.Geometry.Point2d> points_qh_效率,//EqualParaCurvesE 与 ExpressCurveQH 的相交线
|
out List<Yw.Geometry.Point2d> points_qe)//定义的流量效率线上的点
|
{
|
points_qh_效率 = null;
|
points_qe = null;
|
if (EqualParaCurvesE == null || EqualParaCurvesE.Count < 3)
|
return null;
|
points_qh_效率 = new List<Yw.Geometry.Point2d>();
|
double max_eta_flow = 0;
|
points_qe = GetSectPoints2MiddleFeatCurveQE(EqualParaCurvesE, ExpressCurveQH, igonre_h, isCheckEndPt, out points_qh_效率, out max_eta_flow);
|
if (points_qe == null || points_qe.Count < 4)
|
return null;
|
points_qe = (from x in points_qe orderby x.X select x).ToList();
|
var min_flow = points_qe.First().X;
|
|
var fitTypeQE = Yw.Ahart.eFeatType.Cubic;
|
//跨度有点大, 中间插入原来的曲线值的点
|
if (points_qe.Count < 6)
|
{
|
if (ExpressCurveQE_origin != null)
|
{
|
fitTypeQE = ExpressCurveQE_origin.FeatType;
|
if (points_qe[0].X > ExpressCurveQH.FeatCurve.GetXRange().MaxX / 10)
|
{
|
var insert_x = points_qe[0].X / 2;
|
points_qe.Insert(0, new Yw.Geometry.Point2d(insert_x, ExpressCurveQE_origin.FeatCurve.GetPointY(insert_x)));
|
}
|
}
|
}
|
|
|
//插入最小点
|
if (ExpressCurveQH.FeatCurve.GetXRange().MaxX < ExpressCurveQH.FeatCurve.GetXRange().MaxX / 20)
|
{
|
points_qe.Insert(0, new Yw.Geometry.Point2d(0, 0));
|
}
|
|
|
|
|
|
var last_pt_in_qh = ExpressCurveQH.FeatCurve.GetPointList().LastOrDefault();
|
if (points_qe.Last().X < last_pt_in_qh.X && ExpressCurveQE_origin != null)
|
{//延长到最后一个点
|
// 效率线再加一个点 , 最后一个点的效率
|
var last_pt_eta = ExpressCurveQE_origin.FeatCurve.GetPointY(last_pt_in_qh.X);
|
|
if (last_pt_eta > points_qe.Last().Y)
|
{
|
var temp = new Yw.Pump.CurveQE(fitTypeQE, points_qe);
|
points_qe.Add(new Yw.Geometry.Point2d(last_pt_in_qh.X, temp.FeatCurve.GetPointY(last_pt_in_qh.X)));
|
}
|
else
|
{
|
points_qe.Add(new Yw.Geometry.Point2d(last_pt_in_qh.X, last_pt_eta));
|
}
|
}
|
|
|
var curve_qe = Yw.Pump.CalculationHelper.AmendByZeroPointY(fitTypeQE, points_qe, (min_flow + max_eta_flow) / 2, 0);
|
var curve_qe2 = new Yw.Pump.CurveQE(fitTypeQE, points_qe);
|
|
|
|
//高效点
|
//var curve_para_list = (from x in EqualParaCurvesE orderby x.Eff select x.Eff).ToList();
|
//var gao_xiao_can_shu = curve_para_list[curve_para_list.Count() - 2];
|
//foreach (var pt in points_qe)
|
//{
|
// if (pt.Y < gao_xiao_can_shu)
|
// continue;
|
// var fit_pt_y = Eventech.Common.FitCurveHelper.GetPointY(curve_qh, pt.X);
|
// if (Math.Abs(fit_pt_y - pt.Y) < 0.2)
|
// continue;
|
|
// Yw.Geometry.Point2d eta_pt = new Yw.Geometry.Point2d(pt.X, fit_pt_y);
|
|
// var points2 = Eventech.Common.AmendCurveHelper.ByOnePointY1(points_qe, eta_pt, fitTypeQE);
|
// curve_qh = new Model.CurveExpress(points2);
|
//}
|
|
return curve_qe2;
|
}
|
|
|
////计算效率(现有等效线插值计算):必须用GetBoudaryCurveIndex获取
|
//public static EqualEViewModel CalcEta(
|
// PumpCurveViewModel curveGroupMax,//最大曲线
|
// PumpCurveViewModel curveGroupMin,//最小曲线
|
// List<EqualEViewModel> equalCurveListE,
|
// Yw.Geometry.Point2d designPt)
|
//{
|
// try
|
// {
|
// if (equalCurveListE == null || equalCurveListE.Count < 2)
|
// return null;
|
|
// var boundary = GetBoundaryPoint(equalCurveListE);
|
|
// var small_curve_index = GetBoudaryCurveIndex(curveGroupMax, curveGroupMin, equalCurveListE, designPt);
|
// if (small_curve_index < 0)
|
// return null;
|
// var small_paras_curve = equalCurveListE[small_curve_index];
|
// var large_paras_curve = GetLastLargeCurve(equalCurveListE, small_paras_curve);//上一条
|
// return CalcEta(boundary, curveGroupMax, curveGroupMin, large_paras_curve, small_paras_curve, designPt);
|
// }
|
// catch
|
// {
|
// return null;
|
// }
|
|
//}
|
|
////计算效率(现有等效线插值计算):必须用GetBoudaryCurveIndex获取
|
//public static EqualEViewModel CalcEta(
|
// Yw.Geometry.Boundary2d boundary,
|
// PumpCurveViewModel curveGroupMax,//最大曲线
|
// PumpCurveViewModel curveGroupMin,//最小曲线
|
// EqualEViewModel equalCurveListE_large,
|
// EqualEViewModel equalCurveListE_small,
|
// Yw.Geometry.Point2d designPt)
|
//{
|
// var smallCurve = equalCurveListE_small.DefinePoints;
|
// var largeCurve = equalCurveListE_large.DefinePoints;
|
|
// var small_Eff = equalCurveListE_small.Eff;
|
// var large_Eff = equalCurveListE_large.Eff;
|
|
// EqualEViewModel result_curve = null;
|
// double result_dis = 0;
|
// for (int i = 0; i <= 10; i++)
|
// {
|
// double currentEta = small_Eff + (large_Eff - small_Eff) * i / 10;
|
// EqualEViewModel curve = null;
|
// if (currentEta == small_Eff)
|
// {
|
// curve = new EqualEViewModel() { IsClosed = equalCurveListE_small.IsClosed, Eff = equalCurveListE_small.Eff, Tension = 0.5f, DefinePoints = equalCurveListE_small.DefinePoints };
|
// }
|
// else if (currentEta == large_Eff)
|
// {
|
// curve = new EqualEViewModel() { IsClosed = equalCurveListE_large.IsClosed, Eff = equalCurveListE_large.Eff, Tension = 0.5f, DefinePoints = equalCurveListE_large.DefinePoints };
|
// }
|
// else
|
// {
|
// curve = CalcEqualParaCurveE2(boundary, curveGroupMax, curveGroupMin, largeCurve, equalCurveListE_large.Eff, smallCurve, equalCurveListE_small.Eff, currentEta);
|
// }
|
|
// if (result_curve == null)
|
// {
|
// result_curve = curve;
|
// result_dis = Yw.Geometry.BezierCurveHelper.GetDistance(boundary, result_curve.DefinePoints, designPt);
|
// }
|
// else
|
// {
|
// var dis2 = Yw.Geometry.BezierCurveHelper.GetDistance(boundary, curve.DefinePoints, designPt);
|
// if (dis2 < result_dis)
|
// {//谁近用谁
|
// result_dis = dis2;
|
// result_curve = curve;
|
// }
|
// }
|
// }
|
|
// return result_curve;
|
|
//}
|
|
|
////获取在哪个等效线里面(注意获取的是designPt外围的CombineCurve序号)
|
//public static int GetBoudaryCurveIndex(
|
// PumpCurveViewModel curveGroupMax,//最大曲线
|
// PumpCurveViewModel curveGroupMin,//最小曲线
|
// List<EqualEViewModel> equalCurveListE,
|
// Yw.Geometry.Point2d designPt)
|
//{
|
// if (designPt == null)
|
// return -1;
|
// if (equalCurveListE == null || equalCurveListE.Count < 2)
|
// return -1;
|
|
|
// Dictionary<int, Yw.Geometry.Point2d> dict_sect = new Dictionary<int, Yw.Geometry.Point2d>();//交点 注意是chart上的点
|
// Dictionary<int, double> dict_dictance = new Dictionary<int, double>();
|
|
// for (int i = equalCurveListE.Count - 1; i >= 0; i--)//equalCurveListE是从小到大排序
|
// {
|
// var current_curve = equalCurveListE[i];
|
// if (current_curve.DefinePoints == null)
|
// {
|
// continue;
|
// }
|
// if (current_curve.DefinePoints.Count <= 1)
|
// {// 点
|
// continue;
|
// }
|
// if (current_curve.DefinePoints.Count == 2)
|
// {//直线
|
// continue;
|
// }
|
|
// if (current_curve.IsClosed)
|
// {//封闭
|
// List<Yw.Geometry.BezierSpline> allBeziers = Yw.Geometry.BezierCurveHelper.CreateCloseCurves(current_curve.DefinePoints.ToArray());
|
// var apexPoints = Yw.Geometry.BezierCurveHelper.GetApexPoints(allBeziers, 30);
|
// if (Eventech.Common.PolygonHelper.IsInner_Chart(designPt, apexPoints))
|
// {//在封闭区域内部
|
// return i;
|
// }
|
// continue;
|
// }
|
|
// var last_curve = GetLastLargeCurve(equalCurveListE, current_curve);//上一条
|
// if (last_curve == null)
|
// {//上一条是空
|
// continue;
|
// }
|
// var boudaryPoints = GetBondaryPoints(last_curve.DefinePoints, current_curve.DefinePoints, 30);
|
// if (Eventech.Common.PolygonHelper.IsInner_Chart(designPt, boudaryPoints))
|
// {//在封闭区域内部
|
// return i;
|
// }
|
// }
|
|
// return -1;
|
//}
|
|
//得到比current_eta大的最近的等效线,如果上一条有两个,会返回最近的那条
|
public static EqualEViewModel GetLastLargeCurve(
|
List<EqualEViewModel> equalCurveListE,
|
EqualEViewModel current_curve)
|
{
|
var current_eta = current_curve.Eff;
|
EqualEViewModel last_curve = null;
|
for (int i = 0; i < equalCurveListE.Count; i++)
|
{
|
var curve = equalCurveListE[i];
|
if (curve.Eff <= current_eta + 0.010)
|
continue;
|
if (last_curve == null)
|
{
|
last_curve = curve;
|
continue;
|
}
|
if (curve.Eff < last_curve.Eff)
|
{
|
last_curve = curve;
|
continue;
|
}
|
else if (Math.Abs(curve.Eff - last_curve.Eff) < 0.1)
|
{//相同就看谁靠的近一点
|
if (Math.Abs(current_curve.DefinePoints.First().X - curve.DefinePoints.First().X) < Math.Abs(current_curve.DefinePoints.First().X - last_curve.DefinePoints.First().X))
|
last_curve = curve;
|
continue;
|
}
|
}
|
|
return last_curve;
|
}
|
|
//两个等效线围城的区域
|
public static List<Yw.Geometry.Point2d> GetBondaryPoints(
|
List<Yw.Geometry.Point2d> largeCurve,
|
List<Yw.Geometry.Point2d> smallCurve,
|
int insertPointNumber = 8)
|
{
|
if (largeCurve.Count <= 2)
|
{
|
var cur1 = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, insertPointNumber);
|
List<Yw.Geometry.Point2d> bondaryPoints = new List<Yw.Geometry.Point2d>();
|
//放一点余量
|
var yl_y = Math.Max(cur1.First().Y, cur1.Last().Y) * 1.05;
|
bondaryPoints.Add(new Yw.Geometry.Point2d(cur1.First().X, yl_y));
|
bondaryPoints.AddRange(cur1);
|
bondaryPoints.Add(new Yw.Geometry.Point2d(cur1.Last().X, yl_y));
|
return bondaryPoints;
|
}
|
|
var small_monitonicity = IsShapeC(smallCurve);
|
if (small_monitonicity)
|
{//小效率是C型曲线
|
#region 小效率是C型曲线
|
var large_monitonicity = IsShapeC(largeCurve);
|
if (large_monitonicity)
|
{//小效率也是C型曲线
|
var points_large = Yw.Geometry.BezierCurveHelper.GetApexPoints(largeCurve, insertPointNumber);
|
if (points_large.First().X > points_large.Last().X)
|
{//保证从左到右
|
points_large.Reverse();
|
}
|
|
var points_small = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, insertPointNumber);
|
if (points_small.First().X > points_small.Last().X)
|
{//保证从左到右
|
points_small.Reverse();
|
}
|
List<Yw.Geometry.Point2d> bondaryPoints = new List<Yw.Geometry.Point2d>();
|
//放一点余量
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_small.First().X, points_small.First().Y * 1.1));
|
bondaryPoints.AddRange(points_small);
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_small.Last().X, points_small.Last().Y * 1.1));
|
points_large.Reverse();//反过来
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_large.First().X, points_large.First().Y * 1.1));
|
bondaryPoints.AddRange(points_large);
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_large.Last().X, points_large.Last().Y * 1.1));
|
|
return bondaryPoints;
|
}
|
else
|
{
|
return smallCurve;
|
}
|
#endregion
|
}
|
else
|
{//小效率是L型曲线
|
var large_monitonicity = IsShapeC(largeCurve);
|
if (large_monitonicity)
|
{//小效率是L型曲线, 大效率线是C型
|
//小效率是L型曲线, 大效率线是C型
|
#region 大效率线 是 C型
|
var points_large_all = Yw.Geometry.BezierCurveHelper.GetApexPoints(largeCurve, insertPointNumber);
|
if (points_large_all.First().X > points_large_all.First().X)
|
{//保证从左到右
|
points_large_all.Reverse();
|
}
|
int index_end = points_large_all.GetPointIndexOfMinY();
|
|
var points_small = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, insertPointNumber);
|
if (points_small.First().Y < points_small.First().Y)
|
{//保证从上到下
|
points_small.Reverse();
|
}
|
|
|
//
|
List<Yw.Geometry.Point2d> points_large = new List<Yw.Geometry.Point2d>();//切割后
|
if (smallCurve.First().X < largeCurve.First().X)
|
{//小效率线在大效率线左边
|
for (int i = 0; i <= index_end; i++)
|
{
|
points_large.Add(points_large_all[i]);
|
}
|
}
|
else
|
{//小效率线在大效率线右边
|
for (int i = index_end; i < points_large_all.Count; i++)
|
{
|
points_large.Add(points_large_all[i]);
|
}
|
points_large.Reverse();//要反一下, 保证从上到小
|
}
|
|
List<Yw.Geometry.Point2d> bondaryPoints = new List<Yw.Geometry.Point2d>();
|
//放一点余量
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_small.First().X, points_small.First().Y * 1.1));
|
bondaryPoints.AddRange(points_small);
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_small.Last().X, points_small.Last().Y * 0.9));
|
points_large.Reverse();//反过来
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_large.First().X, points_large.First().Y * 0.9));
|
bondaryPoints.AddRange(points_large);
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_large.Last().X, points_large.Last().Y * 1.1));
|
return bondaryPoints;
|
#endregion
|
}
|
else
|
{
|
var points_large = Yw.Geometry.BezierCurveHelper.GetApexPoints(largeCurve, insertPointNumber);
|
if (points_large.First().Y < points_large.First().Y)
|
{//保证从上到下
|
points_large.Reverse();
|
}
|
|
var points_small = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, insertPointNumber);
|
if (points_small.First().Y < points_small.First().Y)
|
{//保证从上到下
|
points_small.Reverse();
|
}
|
List<Yw.Geometry.Point2d> bondaryPoints = new List<Yw.Geometry.Point2d>();
|
//放一点余量
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_small.First().X, points_small.First().Y * 1.1));
|
bondaryPoints.AddRange(points_small);
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_small.Last().X, points_small.Last().Y * 0.9));
|
points_large.Reverse();//反过来
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_large.First().X, points_large.First().Y * 0.9));
|
bondaryPoints.AddRange(points_large);
|
bondaryPoints.Add(new Yw.Geometry.Point2d(points_large.Last().X, points_large.Last().Y * 1.1));
|
return bondaryPoints;
|
}
|
|
}
|
}
|
|
|
|
|
//生成等效线(理论相似换算计算)
|
public static List<EqualEViewModel> CalcEqualParaCurveE(
|
Yw.Pump.CurveQH CurveQH, Yw.Pump.CurveQE CurveQE,
|
double maxValueD2,
|
double minValueD2,
|
double currentEta)
|
{
|
if (maxValueD2 <= minValueD2 || CurveQH == null || CurveQE == null)
|
return null;
|
|
List<Yw.Geometry.Point2d> curveSmall = new List<Yw.Geometry.Point2d>();
|
List<Yw.Geometry.Point2d> curveLarge = new List<Yw.Geometry.Point2d>();
|
int firstSplitNum = 5;
|
bool isCurveU = false;//是否是U型曲线
|
bool isMergeCurve = false;//是否把两条曲线合并成一条,注意不是U型曲线的合并,是但在curveGroupExpress上的2个点距离过小时,就只考虑其中一条
|
double firstSplitSpace = (maxValueD2 - minValueD2) / (firstSplitNum - 1);
|
|
|
for (int i = 0; i < firstSplitNum; i++)
|
{
|
double simuValue1 = maxValueD2 - firstSplitSpace * i;//一定要从大到小
|
|
Yw.Pump.CurveQH simuCurveQH = null;
|
Yw.Pump.CurveQE simuCurveQE = null;
|
|
if (i == 0)
|
{
|
simuCurveQH = CurveQH;
|
simuCurveQE = CurveQE;
|
}
|
else
|
{
|
simuCurveQH = (Yw.Pump.CurveQH)CurveQH.ToNewByN(maxValueD2, simuValue1);
|
simuCurveQE = (Yw.Pump.CurveQE)CurveQE.ToNewByN(maxValueD2, simuValue1);
|
}
|
|
//获取等效率下的流量值:由于点可能在最高点附件所以多打些点
|
var equalEffPoints1 = simuCurveQE.FeatCurve.GetPointsX(currentEta, 200);
|
if (equalEffPoints1 == null || equalEffPoints1.Count() == 0)
|
{//已没有:说明是U线等效线
|
//如果最大曲线都没有交点,说明全部没有交点,直接返回
|
if (i == 0)
|
return null;
|
//
|
isCurveU = true;
|
|
#region 再次逼近
|
int secondSplitNum = 6;
|
double secondSplitSpace = firstSplitSpace / (secondSplitNum - 1);
|
double lastSplitValue = simuValue1 + firstSplitSpace;
|
for (int j = 1; j < secondSplitNum; j++)//从1开始,因为0是上次逼近时就保存了
|
{
|
double simuValue2 = lastSplitValue - secondSplitSpace * j;
|
|
simuCurveQH = (Yw.Pump.CurveQH)CurveQH.ToNewByN(maxValueD2, simuValue2);
|
simuCurveQE = (Yw.Pump.CurveQE)CurveQE.ToNewByN(maxValueD2, simuValue2);
|
var equalEffPoints2 = simuCurveQE.FeatCurve.GetPointsX(currentEta);
|
if (equalEffPoints2 == null || equalEffPoints2.Count() == 0)
|
{//
|
break;
|
}
|
|
double smallPtQ2 = equalEffPoints2.First();
|
var smallPtH2 = simuCurveQH.FeatCurve.GetPointY(smallPtQ2);
|
curveSmall.Add(new Yw.Geometry.Point2d(smallPtQ2, smallPtH2));
|
|
if (equalEffPoints2.Count() == 2 && !isMergeCurve)
|
{
|
double largePtQ2 = equalEffPoints2.Last();
|
var largePtH2 = simuCurveQH.FeatCurve.GetPointY(largePtQ2);
|
curveLarge.Add(new Yw.Geometry.Point2d(largePtQ2, largePtH2));
|
}
|
}
|
#endregion
|
|
break;
|
}
|
|
double smallPtQ1 = equalEffPoints1.First();
|
var smallPtH1 = simuCurveQH.FeatCurve.GetPointY(smallPtQ1);
|
curveSmall.Add(new Yw.Geometry.Point2d(smallPtQ1, smallPtH1));
|
|
if (equalEffPoints1.Count() == 2)
|
{
|
double largePtQ1 = equalEffPoints1.Last();
|
|
if (i == 0)
|
{//判断2个点距离是否过小,如过小,就只考虑其中一条
|
if (Math.Abs(smallPtQ1 - largePtQ1) < 2)
|
{
|
isMergeCurve = true;
|
}
|
}
|
if (!isMergeCurve)
|
{
|
var largePtH1 = simuCurveQH.FeatCurve.GetPointY(largePtQ1);
|
curveLarge.Add(new Yw.Geometry.Point2d(largePtQ1, largePtH1));
|
}
|
}
|
}//end for(i...
|
List<EqualEViewModel> equalCurves = new List<EqualEViewModel>();
|
if (isCurveU)
|
{//U型线,就把曲线连接起来
|
if (!isMergeCurve)
|
{
|
double smallLastPtX = curveSmall.Last().X;
|
for (int i = 0; i < curveLarge.Count; i++)
|
{
|
var largePt = curveLarge[curveLarge.Count - 1 - i];
|
if (largePt.X > (smallLastPtX + 1))//由于可能两个点叠加在一起,所以进行一下判断
|
curveSmall.Add(largePt);
|
}
|
}
|
EqualEViewModel equalCurve = new EqualEViewModel();
|
equalCurve.IsClosed = false;
|
equalCurve.DefinePoints = curveSmall;
|
equalCurve.Eff = currentEta;
|
equalCurve.IsUShaped = true;
|
equalCurves.Add(equalCurve);
|
}
|
else
|
{
|
if (curveSmall.Count > 0)
|
{
|
EqualEViewModel equalCurve = new EqualEViewModel();
|
equalCurve.IsClosed = false;
|
equalCurve.DefinePoints = curveSmall;
|
equalCurve.Eff = currentEta;
|
equalCurve.IsUShaped = false;
|
equalCurves.Add(equalCurve);
|
}
|
if (!isMergeCurve)
|
{
|
if (curveLarge.Count > 0)
|
{
|
EqualEViewModel equalCurve = new EqualEViewModel();
|
equalCurve.IsClosed = false;
|
equalCurve.DefinePoints = curveLarge;
|
equalCurve.Eff = currentEta;
|
equalCurve.IsUShaped = false;
|
equalCurves.Add(equalCurve);
|
}
|
}
|
}
|
return equalCurves;
|
|
}
|
|
//知道原始速度和改变后的速度,求原始效率originE对应改变后的效率
|
public static double GetE(double originE, double originN, double changeN, bool correct)
|
{
|
//变速度公式(P65页)
|
if (correct)
|
{
|
if (changeN >= originN)
|
return originE;//不能处理转速变大的情况,不然效率可能超过100
|
double ratio = originN / changeN;
|
double bilv = Math.Pow(ratio, 0.17);
|
return originE * 100 / (originE + (100 - originE) * bilv);
|
|
}
|
else
|
{
|
return originE;
|
}
|
}
|
|
|
////生成等效线(现有等效线插值计算)
|
//public static EqualEViewModel CalcEqualParaCurveE2(
|
// Yw.Geometry.Boundary2d boundary,//为空即可
|
// PumpCurveViewModel curveGroupMax,//最大曲线
|
// PumpCurveViewModel curveGroupMin,//最小曲线
|
// List<Yw.Geometry.Point2d> largeCurve, double largeValue,
|
// List<Yw.Geometry.Point2d> smallCurve, double smallValue,
|
// double currentEta)
|
//{
|
// if (largeValue <= smallValue)
|
// return null;
|
// if (currentEta >= largeValue)
|
// {
|
// return new EqualEViewModel() { IsClosed = false, Eff = currentEta, Tension = 0.5f, DefinePoints = largeCurve };
|
// }
|
|
// if (currentEta <= smallValue)
|
// {
|
// return new EqualEViewModel() { IsClosed = false, Eff = currentEta, Tension = 0.5f, DefinePoints = smallCurve };
|
// }
|
// //由于流量扬程数量差别特别大, 所以假设他们在一个100*100的方格内
|
// if (boundary == null)
|
// {
|
// boundary = new Yw.Geometry.Boundary2d();
|
// boundary.MinX = Math.Min((from p in largeCurve select p.X).Min(), (from p in smallCurve select p.X).Min());
|
// boundary.MaxX = Math.Max((from p in largeCurve select p.X).Max(), (from p in smallCurve select p.X).Max());
|
// boundary.MinY = Math.Min((from p in largeCurve select p.Y).Min(), (from p in smallCurve select p.Y).Min());
|
// boundary.MaxY = Math.Max((from p in largeCurve select p.Y).Max(), (from p in smallCurve select p.Y).Max());
|
// }
|
|
|
// double ratio_x = 0;
|
// if (boundary.MinX == boundary.MaxX)
|
// {
|
// ratio_x = 100 / (boundary.MaxX);
|
// }
|
// else
|
// {
|
// ratio_x = 100 / (boundary.MaxX - boundary.MinX);
|
// }
|
|
|
// double ratio_y = 0;
|
// if (boundary.MinY == boundary.MaxY)
|
// {
|
// ratio_y = 100 / (boundary.MaxY);
|
// }
|
// else
|
// {
|
// ratio_y = 100 / (boundary.MaxY - boundary.MinY);
|
// }
|
|
// if (largeCurve.Count == 1)
|
// {
|
// #region 大效率线 是 点
|
// Yw.Geometry.Point2d max_eta_pt = largeCurve.OrderBy(x=>x.Y).LastOrDefault();
|
|
// Yw.Geometry.Point2d max_eta_pt_chart = new Yw.Geometry.Point2d() { X = (max_eta_pt.X - boundary.MinX) * ratio_x, Y = (max_eta_pt.Y - boundary.MinY) * ratio_y };
|
|
// var points_small = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
// List<Yw.Geometry.Point2d> points_small_chart = new List<Yw.Geometry.Point2d>();
|
// foreach (var pt in points_small)
|
// {
|
// points_small_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
|
|
// var total_small_large_chart = points_small_chart.TotalLength();
|
// List<Yw.Geometry.Point2d> center_curve = new();
|
// int sectPointNumber = 8;
|
// for (int i = 0; i <= sectPointNumber; i++)
|
// {
|
// var pt_in_small_chart = points_small_chart.GetPosiByLength(i * total_small_large_chart / sectPointNumber);
|
|
// var pt_chart_x = pt_in_small_chart.X + (currentEta - smallValue) * (max_eta_pt_chart.X - pt_in_small_chart.X) / (largeValue - smallValue);
|
// var pt_chart_y = pt_in_small_chart.Y + (currentEta - smallValue) * (max_eta_pt_chart.Y - pt_in_small_chart.Y) / (largeValue - smallValue);
|
|
// center_curve.Add(new Yw.Geometry.Point2d() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
// }
|
|
// return new EqualEViewModel() { IsClosed = false, Eff = currentEta, Tension = 0.5f, DefinePoints = center_curve };
|
|
// #endregion
|
// }
|
|
// var small_monitonicity = IsShapeC(smallCurve);
|
// if (small_monitonicity)
|
// {//小效率是C型曲线
|
// if (smallCurve.First().X > smallCurve.Last().X)
|
// {
|
// smallCurve.Reverse();
|
// }
|
|
// if (largeCurve.Count == 3 || largeCurve.Count == 2)
|
// {
|
// #region 大效率线 是 直线
|
|
|
// Yw.Geometry.Point2d max_eta_pt_largeCurve = largeCurve.OrderBy(x => x.Y).LastOrDefault();
|
// Yw.Geometry.Point2d min_eta_pt_largeCurve = largeCurve.OrderBy(x => x.Y).FirstOrDefault();
|
|
// Yw.Geometry.Point2d max_eta_pt_chart_largeCurve = new Yw.Geometry.Point2d() { X = (max_eta_pt_largeCurve.X - boundary.MinX) * ratio_x, Y = (max_eta_pt_largeCurve.Y - boundary.MinY) * ratio_y };
|
// Yw.Geometry.Point2d min_eta_pt_chart_largeCurve = new Yw.Geometry.Point2d() { X = (min_eta_pt_largeCurve.X - boundary.MinX) * ratio_x, Y = (min_eta_pt_largeCurve.Y - boundary.MinY) * ratio_y };
|
|
// //暂时只能针对开放曲线
|
// var points_small = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
// List<Yw.Geometry.Point2d> points_small_chart = new List<Yw.Geometry.Point2d>();
|
// foreach (var pt in points_small)
|
// {
|
// points_small_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
// Yw.Geometry.Point2d max_eta_pt_chart_smallCurve = points_small_chart.OrderBy(x => x.Y).LastOrDefault();
|
// Yw.Geometry.Point2d min_eta_pt_chart_smallCurve = points_small_chart.OrderBy(x => x.Y).FirstOrDefault();
|
|
|
// var total_small_large_chart = points_small_chart.TotalLength();
|
// List<Yw.Geometry.Point2d> center_curve = new List<Yw.Geometry.Point2d>();
|
// int sectPointNumber = 8;
|
// for (int i = 0; i <= sectPointNumber; i++)
|
// {
|
// var pt_in_small_chart = points_small_chart.GetPosiByLength(i * total_small_large_chart / sectPointNumber);
|
// //计算Y在小效率线上的比率, 根据此比率计算大效率上的点位置
|
// var y_ratio = (pt_in_small_chart.Y - min_eta_pt_chart_smallCurve.Y) / (max_eta_pt_chart_smallCurve.Y - min_eta_pt_chart_smallCurve.Y);
|
|
// var max_eta_pt_chart_x = y_ratio * (max_eta_pt_chart_largeCurve.X - min_eta_pt_chart_largeCurve.X) + min_eta_pt_chart_largeCurve.X;
|
// var max_eta_pt_chart_y = y_ratio * (max_eta_pt_chart_largeCurve.Y - min_eta_pt_chart_largeCurve.Y) + min_eta_pt_chart_largeCurve.Y;
|
|
// var pt_chart_x = pt_in_small_chart.X + (currentEta - smallValue) * (max_eta_pt_chart_x - pt_in_small_chart.X) / (largeValue - smallValue);
|
// var pt_chart_y = pt_in_small_chart.Y + (currentEta - smallValue) * (max_eta_pt_chart_y - pt_in_small_chart.Y) / (largeValue - smallValue);
|
|
// center_curve.Add(new Yw.Geometry.Point2d() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
// }
|
|
// return new EqualEViewModel() { IsClosed = false, Eff = currentEta, Tension = 0.5f, DefinePoints = center_curve };
|
|
// #endregion
|
// }
|
// else
|
// {
|
// #region 大效率线 是 曲线
|
// //大效率线 点处理, 暂时只能针对开放曲线
|
// var points_large = Yw.Geometry.BezierCurveHelper.GetApexPoints(largeCurve, 5);
|
// List<Yw.Geometry.Point2d> points_large_chart = new List<Yw.Geometry.Point2d>();
|
// foreach (var pt in points_large)
|
// {
|
// points_large_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
// var total_length_large_chart = points_large_chart.TotalLength();//总长
|
|
|
// //小效率线
|
// var points_small = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
// List<Yw.Geometry.Point2d> points_small_chart = new List<Yw.Geometry.Point2d>();
|
// foreach (var pt in points_small)
|
// {
|
// points_small_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
|
|
// var total_length_small_chart = points_small_chart.TotalLength();//总长
|
|
// List<Yw.Geometry.Point2d> center_curve = new List<Yw.Geometry.Point2d>();
|
// int sectPointNumber = 8;
|
// for (int i = 0; i <= sectPointNumber; i++)
|
// {
|
// var pt_in_large_chart = points_large_chart.GetPosiByLength(i * total_length_large_chart / sectPointNumber);
|
// var pt_in_small_chart = points_small_chart.GetPosiByLength(i * total_length_small_chart / sectPointNumber);
|
|
// var pt_chart_x = pt_in_small_chart.X + (currentEta - smallValue) * (pt_in_large_chart.X - pt_in_small_chart.X) / (largeValue - smallValue);
|
// var pt_chart_y = pt_in_small_chart.Y + (currentEta - smallValue) * (pt_in_large_chart.Y - pt_in_small_chart.Y) / (largeValue - smallValue);
|
|
// center_curve.Add(new Yw.Geometry.Point2d() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
// }
|
// return new EqualEViewModel() { IsClosed = false, Eff = currentEta, Tension = 0.5f, DefinePoints = center_curve };
|
|
// #endregion
|
// }
|
// }
|
// else
|
// {//小效率是L型曲线
|
// if (smallCurve.First().Y < smallCurve.Last().Y)
|
// {//保证Y从大到小, 即从上到下
|
// smallCurve.Reverse();
|
// }
|
|
// if (largeCurve.Count == 3 || largeCurve.Count == 2)
|
// {//小效率是L型曲线, 大效率线是直型线
|
// #region 大效率线 是 直线
|
// Yw.Geometry.Point2d max_eta_pt_largeCurve = largeCurve.OrderBy(x => x.Y).LastOrDefault();
|
// Yw.Geometry.Point2d min_eta_pt_largeCurve = largeCurve.OrderBy(x => x.Y).FirstOrDefault();
|
|
// Yw.Geometry.Point2d max_eta_pt_chart_largeCurve = new Yw.Geometry.Point2d() { X = (max_eta_pt_largeCurve.X - boundary.MinX) * ratio_x, Y = (max_eta_pt_largeCurve.Y - boundary.MinY) * ratio_y };
|
// Yw.Geometry.Point2d min_eta_pt_chart_largeCurve = new Yw.Geometry.Point2d() { X = (min_eta_pt_largeCurve.X - boundary.MinX) * ratio_x, Y = (min_eta_pt_largeCurve.Y - boundary.MinY) * ratio_y };
|
|
// //暂时只能针对开放曲线
|
// var points_small = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
// List<Yw.Geometry.Point2d> points_small_chart = new List<Yw.Geometry.Point2d>();
|
// foreach (var pt in points_small)
|
// {
|
// points_small_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
// Yw.Geometry.Point2d max_eta_pt_chart_smallCurve = points_small_chart.OrderBy(x => x.Y).LastOrDefault();
|
// Yw.Geometry.Point2d min_eta_pt_chart_smallCurve = points_small_chart.OrderBy(x => x.Y).FirstOrDefault();
|
// var total_length_small_chart = points_small_chart.TotalLength();//总长
|
|
// List<Yw.Geometry.Point2d> center_curve = new List<Yw.Geometry.Point2d>();
|
// int sectPointNumber = 8;
|
// for (int i = 0; i <= sectPointNumber; i++)
|
// {
|
// var pt_in_small_chart = points_small_chart.GetPosiByLength(i * total_length_small_chart / sectPointNumber);
|
// //计算Y在小效率线上的比率, 根据此比率计算大效率上的点位置
|
// var y_ratio = (pt_in_small_chart.Y - min_eta_pt_chart_smallCurve.Y) / (max_eta_pt_chart_smallCurve.Y - min_eta_pt_chart_smallCurve.Y);
|
|
// var max_eta_pt_chart_x = y_ratio * (max_eta_pt_chart_largeCurve.X - min_eta_pt_chart_largeCurve.X) + min_eta_pt_chart_largeCurve.X;
|
// var max_eta_pt_chart_y = y_ratio * (max_eta_pt_chart_largeCurve.Y - min_eta_pt_chart_largeCurve.Y) + min_eta_pt_chart_largeCurve.Y;
|
|
// var pt_chart_x = pt_in_small_chart.X + (currentEta - smallValue) * (max_eta_pt_chart_x - pt_in_small_chart.X) / (largeValue - smallValue);
|
// var pt_chart_y = pt_in_small_chart.Y + (currentEta - smallValue) * (max_eta_pt_chart_y - pt_in_small_chart.Y) / (largeValue - smallValue);
|
|
// center_curve.Add(new Yw.Geometry.Point2d() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
// }
|
|
// return new EqualEViewModel() { IsClosed = false, Eff = currentEta, Tension = 0.5f, DefinePoints = center_curve };
|
|
// #endregion
|
// }
|
// else
|
// {
|
// var large_monitonicity = IsShapeC(largeCurve);
|
// if (large_monitonicity)
|
// {//小效率是L型曲线, 大效率线是C型
|
// #region 大效率线 是 C型
|
// //大效率线 点处理, 暂时只能针对开放曲线
|
// var points_large = Yw.Geometry.BezierCurveHelper.GetApexPoints(largeCurve, 5);
|
// if (points_large.First().X > points_large.Last().X)
|
// {
|
// points_large.Reverse();
|
// }
|
|
// //小效率线 点处理, 暂时只能针对开放曲线
|
// var points_small = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
|
// List<Yw.Geometry.Point2d> points_small_chart = new List<Yw.Geometry.Point2d>();
|
// foreach (var pt in points_small)
|
// { //换算到图像点
|
// points_small_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
// var total_length_small_chart = points_small_chart.TotalLength();//总长
|
|
// //
|
// if (smallCurve.First().X < largeCurve.First().X)
|
// {//小效率线在大效率线左边
|
// List<Yw.Geometry.Point2d> points_large_chart = new List<Yw.Geometry.Point2d>();
|
// //切断大效率线
|
// if (curveGroupMin != null)
|
// {
|
// int min_y_index_smallCurve = points_large.GetPointIndexOfMinY();
|
// for (int i = 0; i <= min_y_index_smallCurve; i++)
|
// {
|
// var pt = points_large[i];
|
// //判断是否超过最小切割线
|
// var pt_in_minFeatCurve_y = curveGroupMin.CurveQH.FeatCurve.GetPointY(pt.X);
|
// if (pt_in_minFeatCurve_y <= pt.Y)
|
// {//换算到图像点
|
// points_large_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
// else
|
// {//只要一出现小的就马上退出
|
// break;
|
// }
|
// }
|
// }
|
// else
|
// {
|
|
|
// int index_end = points_large_chart.GetPointIndexOfMinY();
|
// for (int i = 0; i <= index_end; i++)
|
// {//换算到图像点
|
// var pt = points_large[i];
|
// points_large_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
// }
|
// var total_length_large_chart = points_large_chart.TotalLength();//长度
|
|
// List<Yw.Geometry.Point2d> center_curve = new List<Yw.Geometry.Point2d>();
|
// int sectPointNumber = 8;
|
// for (int i = 0; i <= sectPointNumber; i++)
|
// {
|
// var pt_in_large_chart = points_large_chart.GetPosiByLength(i * total_length_large_chart / sectPointNumber);
|
// var pt_in_small_chart = points_small_chart.GetPosiByLength(i * total_length_small_chart / sectPointNumber);
|
|
// var pt_chart_x = pt_in_small_chart.X + (currentEta - smallValue) * (pt_in_large_chart.X - pt_in_small_chart.X) / (largeValue - smallValue);
|
// var pt_chart_y = pt_in_small_chart.Y + (currentEta - smallValue) * (pt_in_large_chart.Y - pt_in_small_chart.Y) / (largeValue - smallValue);
|
|
// center_curve.Add(new Yw.Geometry.Point2d() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
// }
|
// return new EqualEViewModel() { IsClosed = false, Eff = currentEta, Tension = 0.5f, DefinePoints = center_curve };
|
// }
|
// else
|
// {//小效率线在大效率线右边
|
// //暂时不考虑
|
// return null;
|
// }
|
// #endregion
|
// }
|
// else
|
// {//小效率是L型曲线, 大效率线是L直型线
|
// #region 大效率线 是 L型
|
// //大效率线 点处理, 暂时只能针对开放曲线
|
// var points_large = Yw.Geometry.BezierCurveHelper.GetApexPoints(largeCurve, 5);
|
// if (points_large.First().Y < points_large.Last().Y)
|
// {
|
// points_large.Reverse();
|
// }
|
|
// List<Yw.Geometry.Point2d> points_large_chart = new List<Yw.Geometry.Point2d>();
|
// foreach (var pt in points_large)
|
// {
|
// points_large_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
// //换算到图像点
|
// //Yw.Geometry.Point2d max_eta_pt_chart_largeCurve = points_large_chart.GetPointOfMaxY();
|
// //int min_eta_pt_chart_largeCurve_index = points_large_chart.GetPointIndexOfMinY();
|
// var total_length_large_chart = points_large_chart.TotalLength();//总长
|
|
// //小效率线 点处理, 暂时只能针对开放曲线
|
// var points_small = Yw.Geometry.BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
// if (points_small.First().Y < points_small.Last().Y)
|
// {
|
// points_small.Reverse();
|
// }
|
// List<Yw.Geometry.Point2d> points_small_chart = new List<Yw.Geometry.Point2d>();
|
// foreach (var pt in points_small)
|
// {
|
// points_small_chart.Add(new Yw.Geometry.Point2d() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
// }
|
// var total_length_small_chart = points_small_chart.TotalLength();//总长
|
|
// //小效率线在大效率线左边
|
// List<Yw.Geometry.Point2d> center_curve = new List<Yw.Geometry.Point2d>();
|
// int sectPointNumber = 8;
|
// for (int i = 0; i <= sectPointNumber; i++)
|
// {
|
// var pt_in_large_chart = points_large_chart.GetPosiByLength(i * total_length_large_chart / sectPointNumber);
|
// var pt_in_small_chart = points_small_chart.GetPosiByLength(i * total_length_small_chart / sectPointNumber);
|
|
// var pt_chart_x = pt_in_small_chart.X + (currentEta - smallValue) * (pt_in_large_chart.X - pt_in_small_chart.X) / (largeValue - smallValue);
|
// var pt_chart_y = pt_in_small_chart.Y + (currentEta - smallValue) * (pt_in_large_chart.Y - pt_in_small_chart.Y) / (largeValue - smallValue);
|
|
// center_curve.Add(new Yw.Geometry.Point2d() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
// }
|
|
// return new EqualEViewModel() { IsClosed = false, Eff = currentEta, Tension = 0.5f, DefinePoints = center_curve };
|
|
// #endregion
|
// }
|
// }
|
// }
|
//}
|
|
//区分QE曲线
|
//LargeHcurve为高扬程处的L型曲线,middleHcurve中扬程处的C型曲线,smallHcurve为低扬程处的L型曲线
|
//而且返回的曲线参数从小到大排列好了
|
public static bool DevideCurveShape(
|
List<EqualEViewModel> curveInfoQE,
|
//Eventech.Model.CurveExpress ZeroCurveQH,//0角度的QH线
|
out List<EqualEViewModel> largeHcurve,
|
out List<EqualEViewModel> middleHcurve,
|
out List<EqualEViewModel> smallHcurve)
|
{
|
largeHcurve = middleHcurve = smallHcurve = null;
|
if (curveInfoQE == null || curveInfoQE.Count == 0)
|
return false;
|
List<EqualEViewModel> caosCurve = new List<EqualEViewModel>();
|
List<EqualEViewModel> nonCaosCurve = new List<EqualEViewModel>();
|
var sort_qe = from x in curveInfoQE orderby x.Eff select x;//从小到大排序
|
for (int i = 0; i < sort_qe.Count(); i++)
|
{
|
var curve = sort_qe.ElementAt(i);
|
if (curve.DefinePoints == null || curve.DefinePoints.Count < 3)
|
continue;
|
//判断是否是C型曲线:注意严格判断X的增减性来判断是否为C型线,有时有问题,因为有时可能有1个点故意偏移一点
|
//所以忽略一个点
|
if (IsShapeC(curve.DefinePoints))
|
{//如果小的都是, 效率更高的也是
|
for (int j = i; j < sort_qe.Count(); j++)
|
{
|
caosCurve.Add(sort_qe.ElementAt(j));
|
}
|
|
break;
|
}
|
else
|
{
|
nonCaosCurve.Add(curve);
|
}
|
}
|
|
|
|
|
double middleH = 0;//用于比较的中间H值
|
if (caosCurve.Count > 0)
|
{
|
//有C型曲线
|
//有C型曲线
|
caosCurve.Sort(new Comparer());//从小到大排序
|
middleHcurve = caosCurve;
|
|
//没有非C型曲线
|
if (nonCaosCurve.Count == 0)
|
return true;
|
|
//用效率最高的曲线的Y平均值作为用于比较的中间H值
|
List<Yw.Geometry.Point2d> curveMaxE = middleHcurve.Last().DefinePoints;
|
for (int i = 0; i < curveMaxE.Count; i++)
|
{
|
middleH += curveMaxE[i].Y;
|
}
|
middleH = middleH / curveMaxE.Count;
|
}
|
else
|
{//没有C型曲线
|
if (nonCaosCurve.Count == 0)
|
return false;//也没有非C型曲线
|
|
|
//
|
var max_eta = (from x in curveInfoQE select x.Eff).Max();
|
var max_eta_curve = (from x in curveInfoQE where x.Eff == max_eta select x).ToList();
|
|
middleH = 0;
|
foreach (var curve in max_eta_curve)
|
{
|
//求平均值
|
double averH = 0;
|
for (int i = 0; i < curve.DefinePoints.Count; i++)
|
{
|
averH += curve.DefinePoints[i].Y;
|
}
|
|
middleH += averH / curve.DefinePoints.Count;
|
}
|
|
middleH = middleH / max_eta_curve.Count;
|
}
|
|
//
|
largeHcurve = new List<EqualEViewModel>();
|
smallHcurve = new List<EqualEViewModel>();
|
foreach (EqualEViewModel curve in nonCaosCurve)
|
{
|
//求平均值
|
double averH = 0;
|
for (int i = 0; i < curve.DefinePoints.Count; i++)
|
{
|
averH += curve.DefinePoints[i].Y;
|
}
|
averH = averH / curve.DefinePoints.Count;
|
|
//比较平均值
|
if (averH > middleH)
|
{
|
largeHcurve.Add(curve);
|
}
|
else
|
{
|
smallHcurve.Add(curve);
|
}
|
}
|
|
if (largeHcurve.Count > 0)
|
largeHcurve.Sort(new Comparer());//从小到大排序
|
else
|
largeHcurve = null;
|
|
if (smallHcurve.Count > 0)
|
smallHcurve.Sort(new Comparer());//从小到大排序
|
else
|
smallHcurve = null;
|
|
return true;
|
}
|
|
//规整等效线曲线
|
//C型圈:保证曲线Y值从大到小 ,开始Y值大,结束Y值小
|
//一型圈:保证流量值从小到大
|
public static void StandardCurve(ref EqualEViewModel curve)
|
{
|
Standard4EqualCurveE(ref curve);
|
}
|
public static void StandardCurve(ref List<EqualEViewModel> curves)
|
{
|
if (curves == null || curves.Count() == 0)
|
return;
|
|
//单条线,流量从小到大排序
|
for (int i = 0; i < curves.Count; i++)
|
{
|
var curve = curves[i];
|
StandardCurve(ref curve);
|
}
|
//根据参数从小到排序,参数一样 就H从小到大
|
curves.Sort(new Comparer());
|
}
|
|
/// <summary>
|
/// 是否是C型的曲线
|
/// </summary>
|
/// <param name="points"></param>
|
/// <returns></returns>
|
public static bool IsShapeC(List<Yw.Geometry.Point2d> points)
|
{
|
if (points == null || points.Count() <= 2)
|
return false;
|
if (points.Count() == 3)
|
{
|
if (points[1].X < points[0].X && points[1].X < points[2].X)
|
return true;
|
if (points[1].X > points[0].X && points[1].X > points[2].X)
|
return true;
|
|
return false;
|
}
|
var b_curve = Yw.Geometry.BezierCurveHelper.CreateOpenCurves(points.ToArray());
|
|
var xxx = from x in points select x.X;
|
|
var x_max = xxx.Max();
|
var x_min = xxx.Min();
|
|
var pt_num = 20;
|
var x_space = (x_max - x_min) / (pt_num - 1);
|
|
int sect_pt_num = 0;
|
for (int i = 0; i < pt_num; i++)
|
{
|
var x = x_min + x_space * i;
|
|
var y_list = Yw.Geometry.BezierCurveHelper.GetSectPointsByX(b_curve, x);
|
if (y_list != null && y_list.Count > 1)
|
{
|
sect_pt_num++;
|
}
|
}
|
|
if (sect_pt_num >= 3)
|
return true;
|
else
|
return false;
|
}
|
|
//等效线曲线
|
//C型圈:保证曲线Y值从大到小 ,开始Y值大,结束Y值小
|
//一型圈:保证流量值从小到大
|
public static void Standard4EqualCurveE(ref EqualEViewModel curve)
|
{
|
if (curve == null)
|
return;
|
if (curve.FeatCurve.IsInvalid())
|
return;
|
if (curve.IsClosed)
|
return; //封闭就保证原始状态即可
|
|
List<Yw.Geometry.Point2d> pt_list;
|
if (curve.FeatType == Yw.Ahart.eFeatType.Through)
|
{
|
//判断各种情况
|
var fit_pt_list = curve.FeatCurve.GetPointList();
|
if (IsShapeC(fit_pt_list))
|
{
|
//C型圈:保证曲线X值从小到大, 即开始X值小, 结束X值大
|
if (fit_pt_list.First().X > fit_pt_list.Last().X)
|
{
|
fit_pt_list.Reverse();
|
}
|
}
|
else
|
{ //保证Y值从大到小(即从上到下)
|
if (fit_pt_list.First().Y < fit_pt_list.Last().Y)
|
{
|
fit_pt_list.Reverse();
|
}
|
}
|
|
pt_list = fit_pt_list;
|
}
|
else
|
{
|
//拟合的方法不需要排序 只要保证流量从小到大即可
|
pt_list = curve.FeatCurve.GetPointList(6);
|
}
|
curve.DefinePoints = pt_list;
|
}
|
|
|
public static Yw.Geometry.Boundary2d GetBoundaryPoint(List<EqualEViewModel> list)
|
{
|
double boudary_min_x = double.MaxValue;
|
double boudary_max_x = double.MinValue;
|
double boudary_min_y = double.MaxValue;
|
double boudary_max_y = double.MinValue;
|
|
foreach (var curve in list)
|
{
|
boudary_min_x = Math.Min(boudary_min_x, (from x in curve.DefinePoints select x.X).Min());
|
boudary_max_x = Math.Max(boudary_max_x, (from x in curve.DefinePoints select x.X).Max());
|
boudary_min_y = Math.Min(boudary_min_y, (from x in curve.DefinePoints select x.Y).Min());
|
boudary_max_y = Math.Max(boudary_min_y, (from x in curve.DefinePoints select x.Y).Max());
|
}
|
return new Yw.Geometry.Boundary2d(boudary_min_x, boudary_max_x, boudary_min_y, boudary_max_y);
|
}
|
|
}
|
|
|
public class Comparer : IComparer<EqualEViewModel>
|
{
|
public Comparer()
|
{
|
}
|
|
#region IComparer<Eventech.Model.FeatPoint> 成员
|
private double ignoreDis = 0.001;
|
int IComparer<EqualEViewModel>.Compare(EqualEViewModel obj1, EqualEViewModel obj2)
|
{
|
if (Math.Abs(obj1.Eff - obj2.Eff) < ignoreDis)
|
{//参数一样 就比较Y的平均值
|
double y1_arv = (from x in obj1.DefinePoints select x.Y).Average();
|
double y2_arv = (from x in obj2.DefinePoints select x.Y).Average();
|
if (Math.Abs(y1_arv - y2_arv) < 0.01)
|
return 0;
|
else if (y1_arv > y2_arv)
|
return 1;
|
else
|
return -1;
|
}
|
else if (obj1.Eff > obj2.Eff)
|
{
|
return 1;
|
}
|
else
|
{
|
return -1;
|
}
|
}
|
|
#endregion
|
}
|
|
//比较相同:主要用与LIST的Contains方法和Distinct
|
public class EqualComparer : IEqualityComparer<EqualEViewModel>
|
{
|
private double ignoreDis = 0.001;
|
public EqualComparer()
|
{
|
ignoreDis = 0.001;
|
}
|
public EqualComparer(double dis)
|
{
|
ignoreDis = dis;
|
}
|
|
public bool Equals(EqualEViewModel lhs, EqualEViewModel rhs)
|
{
|
if (Math.Abs(lhs.Eff - rhs.Eff) < ignoreDis)
|
return true;
|
else
|
return false;
|
}
|
|
public int GetHashCode(EqualEViewModel obj)
|
{
|
//return obj.X.GetHashCode() + obj.Y.GetHashCode();
|
return 0;
|
}
|
}
|
|
}
|