using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
|
|
using Eventech.Model;
|
|
namespace Eventech.Common
|
{
|
//等效线辅助类
|
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(
|
Eventech.Model.CombineCurveList equalCurveListE,
|
Eventech.Model.CurveExpress 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(
|
Eventech.Model.CombineCurveList equalCurveListE,
|
Eventech.Model.CurveExpress 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 (Eventech.Model.CombineCurve curve in equalCurveListE)
|
{
|
if (curve.PointInfo == null || curve.PointInfo.Count == 0)
|
continue;
|
if (curve.PointInfo.Count == 1)
|
{ //添加单点
|
define_points.Add(new Yw.Geometry.Point2d(curve.PointInfo.First().X, curve.PointInfo.First().Y));
|
}
|
else
|
{
|
//注意两端都可能有交点
|
var firstPointY = Eventech.Common.FitCurveHelper.GetFitPointY(maxCurveQH, curve.PointInfo.First().X);
|
if ((Math.Abs(firstPointY - curve.PointInfo.First().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.PointInfo.First().X, curve.PointInfo.First().Y));
|
}
|
|
var lastPointY = Eventech.Common.FitCurveHelper.GetFitPointY(maxCurveQH, curve.PointInfo.Last().X);
|
if ((Math.Abs(lastPointY - curve.PointInfo.Last().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.PointInfo.Last().X, curve.PointInfo.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(
|
Eventech.Model.CombineCurveList equalCurveListE,
|
Eventech.Model.CurveExpress 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 (Eventech.Model.CombineCurve curve in equalCurveListE)
|
{
|
if (curve.PointInfo == null || curve.PointInfo.Count == 0)
|
continue;
|
if (curve.PointInfo.Count == 1)
|
{ //添加单点
|
define_points.Add(new Yw.Geometry.Point2d(curve.PointInfo.First().X, curve.CurvePara));
|
}
|
else
|
{
|
//注意两端都可能有交点
|
var firstPointY = Eventech.Common.FitCurveHelper.GetFitPointY(maxCurveQH, curve.PointInfo.First().X);
|
if ((Math.Abs(firstPointY - curve.PointInfo.First().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.PointInfo.First().X, curve.CurvePara));
|
}
|
|
var lastPointY = Eventech.Common.FitCurveHelper.GetFitPointY(maxCurveQH, curve.PointInfo.Last().X);
|
if ((Math.Abs(lastPointY - curve.PointInfo.Last().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.PointInfo.Last().X, curve.CurvePara));
|
}
|
}
|
}
|
|
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 Eventech.Model.CurveExpress CalcCurveQE4Max(
|
Eventech.Model.CombineCurveList equalCurveListE,
|
Eventech.Model.CurveExpress maxCurveQH,
|
Eventech.Model.CurveExpress 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 (Eventech.Model.CombineCurve curve in equalCurveListE)
|
{
|
if (curve.PointInfo == null || curve.PointInfo.Count == 0)
|
continue;
|
if (curve.PointInfo.Count == 1)
|
{ //添加单点
|
define_points_qe.Add(new Yw.Geometry.Point2d(curve.PointInfo.First().X, curve.CurvePara));
|
}
|
else
|
{
|
//注意两端都可能有交点
|
var firstPointY = Eventech.Common.FitCurveHelper.GetFitPointY(maxCurveQH, curve.PointInfo.First().X);
|
if ((Math.Abs(firstPointY - curve.PointInfo.First().Y) < igonre_h))
|
{
|
define_points_qe.Add(new Yw.Geometry.Point2d(curve.PointInfo.First().X, curve.CurvePara));
|
}
|
|
var lastPointY = Eventech.Common.FitCurveHelper.GetFitPointY(maxCurveQH, curve.PointInfo.Last().X);
|
if ((Math.Abs(lastPointY - curve.PointInfo.Last().Y) < igonre_h))
|
{
|
define_points_qe.Add(new Yw.Geometry.Point2d(curve.PointInfo.Last().X, curve.CurvePara));
|
}
|
}
|
}
|
if (define_points_qe.Count < 3)
|
return null;
|
|
//插入最大流量点
|
var maxQ = maxCurveQH.RangeMax;
|
var maxQ2 = (from x in define_points_qe select x.X).Max();
|
if (maxQ2 < maxQ * 0.99)
|
{
|
var maxQ_E = Eventech.Common.FitCurveHelper.GetFitPointY(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.GetFitPointY(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 Model.FeatPoint();
|
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(
|
Eventech.Model.CombineCurveList EqualParaCurvesE,
|
Eventech.Model.CurveExpress ExpressCurveQH,
|
Eventech.Model.CurveExpress 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(
|
Eventech.Model.CombineCurveList EqualParaCurvesE,
|
Eventech.Model.CurveExpress ExpressCurveQH,
|
Eventech.Model.CurveExpress 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 Eventech.Model.CurveExpress CalcCurveQE4Middle(
|
Eventech.Model.CombineCurveList EqualParaCurvesE,
|
Eventech.Model.CurveExpress ExpressCurveQH,
|
Eventech.Model.CurveExpress 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 Eventech.Model.CurveExpress CalcCurveQE4Middle(
|
Eventech.Model.CombineCurveList EqualParaCurvesE,
|
Eventech.Model.CurveExpress ExpressCurveQH,
|
Eventech.Model.CurveExpress 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(
|
Eventech.Model.CombineCurveList EqualParaCurvesE,
|
Eventech.Model.CurveExpress 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(
|
Eventech.Model.CombineCurveList EqualParaCurvesE,
|
Eventech.Model.CurveExpress 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.PointInfo == null || curveE.PointInfo.Count == 0)
|
continue;
|
|
if (curveE.CurvePara > max_eta)
|
{
|
max_eta = curveE.CurvePara;
|
max_eta_flow = curveE.PointInfo[0].X;
|
}
|
|
|
|
|
if (curveE.PointInfo.Count == 1)
|
{// 点
|
var pt = curveE.PointInfo[0];
|
|
if (igonre_h < 0.01)//保证靠的太近可以认为相交
|
igonre_h = pt.Y / 100;
|
|
var fit_y1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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.CurvePara));
|
}
|
continue;
|
}
|
|
if (igonre_h < 0.01)//保证靠的太近可以认为相交
|
{
|
var yyy = from x in curveE.PointInfo select x.Y;
|
igonre_h = Math.Abs(yyy.Max() - yyy.Min()) / 10;
|
}
|
|
//判断是否就是等效线的端点
|
if (isCheckEndPt)
|
{
|
var min_y_pt = curveE.PointInfo.GetPointOfMinY();
|
|
var fit_y_2 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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.CurvePara));
|
|
continue;
|
}
|
}
|
|
|
|
if (curveE.PointInfo.Count == 2)
|
{
|
#region Line
|
var start0_p = curveE.PointInfo[0];
|
var end0_p = curveE.PointInfo[1];
|
|
var start0_p_y_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, start0_p.X);
|
var end0_p_y_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, x);
|
var p = new Yw.Geometry.Point2d(x, y);
|
points_head.Add(p);
|
points_eta.Add(new Yw.Geometry.Point2d(x, curveE.CurvePara));
|
}
|
else
|
{
|
double min_dis_y = double.MaxValue;
|
var min_pt = new Yw.Geometry.Point2d();
|
|
var startY_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, curveE.PointInfo[0].X);
|
if (Math.Abs(startY_1 - curveE.PointInfo[0].Y) < min_dis_y)
|
{
|
min_dis_y = Math.Abs(startY_1 - curveE.PointInfo[0].Y);
|
min_pt.X = curveE.PointInfo[0].X;
|
min_pt.Y = startY_1;
|
}
|
|
var endY_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, curveE.PointInfo[1].X);
|
if (Math.Abs(endY_1 - curveE.PointInfo[1].Y) < min_dis_y)
|
{
|
min_dis_y = Math.Abs(endY_1 - curveE.PointInfo[1].Y);
|
min_pt.X = curveE.PointInfo[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.CurvePara));
|
}
|
}
|
continue;
|
|
#endregion
|
}
|
|
|
|
|
|
|
|
|
if (curveE.PointInfo.Count == 3)
|
{//
|
#region 三个点只能用二次贝塞尔曲线
|
List<Model.FeatPoint> current_sect_pts_qh = new List<FeatPoint>();
|
List<Model.FeatPoint> current_sect_pts_qe = new List<FeatPoint>();
|
|
Eventech.Model.BezierCurve2 bezeir = new Model.BezierCurve2();
|
bezeir.Point0 = curveE.PointInfo[0];
|
bezeir.Point1 = curveE.PointInfo[1];
|
bezeir.Point2 = curveE.PointInfo[2];
|
|
if (igonre_h < 0.01)//保证靠的太近可以认为相交
|
{
|
var yyy = from x in curveE.PointInfo select x.Y;
|
igonre_h = Math.Abs(yyy.Max() - yyy.Min()) / 15;
|
}
|
|
#region 贝塞尔曲线集合循环
|
var startY_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, bezeir.Point0.X);
|
var endY_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, start0_p_x);
|
var end0_p_y_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, start1_p_x);
|
var end1_p_y_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, start2_p_x);
|
var end2_p_y_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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.CurvePara));
|
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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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.CurvePara));
|
}
|
#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.PointInfo 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.PointInfo.Count > 3)
|
{
|
List<Model.FeatPoint> current_sect_pts_qh = new List<FeatPoint>();
|
List<Model.FeatPoint> current_sect_pts_qe = new List<FeatPoint>();
|
|
List<Eventech.Model.BezierCurve> allBeziers = null;
|
//获取所有的贝塞尔曲线
|
if (curveE.IsClosed)
|
{
|
allBeziers = Eventech.Common.BezierCurveHelper.CreateCloseCurves(curveE.PointInfo.ToArray());
|
}
|
else
|
{
|
allBeziers = Eventech.Common.BezierCurveHelper.CreateOpenCurves(curveE.PointInfo.ToArray());
|
}
|
if (allBeziers == null)
|
continue;
|
|
if (igonre_h < 0.01)//保证靠的太近可以认为相交
|
{
|
var yyy = from x in curveE.PointInfo select x.Y;
|
igonre_h = Math.Abs(yyy.Max() - yyy.Min()) / 5;
|
}
|
|
foreach (var bezeir in allBeziers)
|
{
|
var startY_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, bezeir.Point0.X);
|
var endY_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, start0_p_x);
|
var end0_p_y_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, start1_p_x);
|
var end1_p_y_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, start2_p_x);
|
var end2_p_y_1 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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.CurvePara));
|
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 = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQH, 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.CurvePara));
|
}
|
#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.RangeMax - ExpressCurveQH.RangeMin) / 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.RangeMax - ExpressCurveQH.RangeMin) / 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(
|
Eventech.Model.CombineCurveList EqualParaCurvesE,
|
Eventech.Model.CurveExpress ExpressCurveQH,
|
Eventech.Model.CurveExpress 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(
|
Eventech.Model.CombineCurveList equalCurveListE,
|
Eventech.Model.CurveExpress 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 (Eventech.Model.CombineCurve curve in equalCurveListE)
|
{
|
if (curve.PointInfo == null || curve.PointInfo.Count == 0)
|
continue;
|
if (curve.PointInfo.Count == 1)
|
{ //添加单点
|
continue;
|
}
|
else
|
{
|
//注意两端都可能有交点
|
var firstPointY = Eventech.Common.FitCurveHelper.GetFitPointY(maxCurveQH, curve.PointInfo.First().X);
|
if ((Math.Abs(firstPointY - curve.PointInfo.First().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.PointInfo.First().X, curve.CurvePara));
|
}
|
|
var lastPointY = Eventech.Common.FitCurveHelper.GetFitPointY(maxCurveQH, curve.PointInfo.Last().X);
|
if ((Math.Abs(lastPointY - curve.PointInfo.Last().Y) < igonre_h))
|
{
|
define_points.Add(new Yw.Geometry.Point2d(curve.PointInfo.Last().X, curve.CurvePara));
|
}
|
}
|
}
|
|
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 Eventech.Model.CurveExpress CalcCurveQE4Min(
|
Eventech.Model.CombineCurveList EqualParaCurvesE,
|
Eventech.Model.CurveExpress ExpressCurveQH,
|
Eventech.Model.CurveExpress 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 Eventech.Model.CurveExpress CalcCurveQESimu(
|
Eventech.Model.CombineCurveList EqualParaCurvesE,
|
Eventech.Model.CurveExpress ExpressCurveQH,
|
Eventech.Model.CurveExpress 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 = Eventech.Model.eCurveFitType.CubicCurve;
|
//跨度有点大, 中间插入原来的曲线值的点
|
if (points_qe.Count < 6)
|
{
|
if (ExpressCurveQE_origin != null)
|
{
|
fitTypeQE = ExpressCurveQE_origin.CurveFitType;
|
if (points_qe[0].X > ExpressCurveQH.RangeMax / 10)
|
{
|
var insert_x = points_qe[0].X / 2;
|
points_qe.Insert(0, new Yw.Geometry.Point2d(insert_x, Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQE_origin, insert_x)));
|
}
|
}
|
}
|
|
|
//插入最小点
|
if (ExpressCurveQH.RangeMin < ExpressCurveQH.RangeMax / 20)
|
{
|
points_qe.Insert(0, new Yw.Geometry.Point2d(0, 0));
|
}
|
|
|
|
|
|
var last_pt_in_qh = ExpressCurveQH.GetLastPoint();
|
if (points_qe.Last().X < last_pt_in_qh.X && ExpressCurveQE_origin != null)
|
{//延长到最后一个点
|
// 效率线再加一个点 , 最后一个点的效率
|
var last_pt_eta = Eventech.Common.FitCurveHelper.GetFitPointY(ExpressCurveQE_origin, last_pt_in_qh.X);
|
|
if (last_pt_eta > points_qe.Last().Y)
|
{
|
var temp = new Model.CurveExpress(points_qe, fitTypeQE);
|
points_qe.Add(new Yw.Geometry.Point2d(last_pt_in_qh.X, Eventech.Common.FitCurveHelper.GetFitPointY(
|
temp, last_pt_in_qh.X)));
|
}
|
else
|
{
|
points_qe.Add(new Yw.Geometry.Point2d(last_pt_in_qh.X, last_pt_eta));
|
}
|
}
|
|
var curve_qe = Eventech.Common.AmendCurveHelper.ByZeroPointY(points_qe, (min_flow + max_eta_flow) / 2, 0, fitTypeQE);
|
var curve_qe2 = new Model.CurveExpress(points_qe, fitTypeQE);
|
|
|
|
|
|
//高效点
|
//var curve_para_list = (from x in EqualParaCurvesE orderby x.CurvePara select x.CurvePara).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.GetFitPointY(curve_qh, pt.X);
|
// if (Math.Abs(fit_pt_y - pt.Y) < 0.2)
|
// continue;
|
|
// Yw.Geometry.Point2d eta_pt = new Model.FeatPoint(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 ThroughParaCurve CalcEta(
|
Eventech.Model.LxpCurveGroupExpress curveGroupMax,//最大曲线
|
Eventech.Model.LxpCurveGroupExpress curveGroupMin,//最小曲线
|
Eventech.Model.CombineCurveList equalCurveListE,
|
Yw.Geometry.Point2d designPt)
|
{
|
try
|
{
|
if (equalCurveListE == null || equalCurveListE.Count < 2)
|
return null;
|
|
var boundary = equalCurveListE.GetBoundaryPoint();
|
|
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 ThroughParaCurve CalcEta(
|
Boundary boundary,
|
Eventech.Model.LxpCurveGroupExpress curveGroupMax,//最大曲线
|
Eventech.Model.LxpCurveGroupExpress curveGroupMin,//最小曲线
|
Eventech.Model.CombineCurve equalCurveListE_large,
|
Eventech.Model.CombineCurve equalCurveListE_small,
|
Yw.Geometry.Point2d designPt)
|
{
|
var smallCurve = equalCurveListE_small.PointInfo;
|
var largeCurve = equalCurveListE_large.PointInfo;
|
|
var small_CurvePara = equalCurveListE_small.CurvePara;
|
var large_CurvePara = equalCurveListE_large.CurvePara;
|
|
ThroughParaCurve result_curve = null;
|
double result_dis = 0;
|
for (int i = 0; i <= 10; i++)
|
{
|
double currentEta = small_CurvePara + (large_CurvePara - small_CurvePara) * i / 10;
|
ThroughParaCurve curve = null;
|
if (currentEta == small_CurvePara)
|
{
|
curve = new ThroughParaCurve() { IsClosed = equalCurveListE_small.IsClosed, CurvePara = equalCurveListE_small.CurvePara, DispTension = 0.5f, PointInfo = equalCurveListE_small.PointInfo };
|
}
|
else if (currentEta == large_CurvePara)
|
{
|
curve = new ThroughParaCurve() { IsClosed = equalCurveListE_large.IsClosed, CurvePara = equalCurveListE_large.CurvePara, DispTension = 0.5f, PointInfo = equalCurveListE_large.PointInfo };
|
}
|
else
|
{
|
curve = CalcEqualParaCurveE2(boundary, curveGroupMax, curveGroupMin, largeCurve, equalCurveListE_large.CurvePara, smallCurve, equalCurveListE_small.CurvePara, currentEta);
|
}
|
|
if (result_curve == null)
|
{
|
result_curve = curve;
|
result_dis = BezierCurveHelper.GetDistance(boundary, result_curve.PointInfo, designPt);
|
}
|
else
|
{
|
var dis2 = BezierCurveHelper.GetDistance(boundary, curve.PointInfo, designPt);
|
if (dis2 < result_dis)
|
{//谁近用谁
|
result_dis = dis2;
|
result_curve = curve;
|
}
|
}
|
}
|
|
return result_curve;
|
|
}
|
|
|
//获取在哪个等效线里面(注意获取的是designPt外围的CombineCurve序号)
|
public static int GetBoudaryCurveIndex(
|
Eventech.Model.LxpCurveGroupExpress curveGroupMax,//最大曲线
|
Eventech.Model.LxpCurveGroupExpress curveGroupMin,//最小曲线
|
Eventech.Model.CombineCurveList 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.PointInfo == null)
|
{
|
continue;
|
}
|
if (current_curve.PointInfo.Count <= 1)
|
{// 点
|
continue;
|
}
|
if (current_curve.PointInfo.Count == 2)
|
{//直线
|
continue;
|
}
|
|
if (current_curve.IsClosed)
|
{//封闭
|
List<Eventech.Model.BezierCurve> allBeziers = Eventech.Common.BezierCurveHelper.CreateCloseCurves(current_curve.PointInfo.ToArray());
|
var apexPoints = Eventech.Common.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.PointInfo, current_curve.PointInfo, 30);
|
if (Eventech.Common.PolygonHelper.IsInner_Chart(designPt, boudaryPoints))
|
{//在封闭区域内部
|
return i;
|
}
|
}
|
|
return -1;
|
}
|
|
//得到比current_eta大的最近的等效线,如果上一条有两个,会返回最近的那条
|
public static Eventech.Model.CombineCurve GetLastLargeCurve(
|
Eventech.Model.CombineCurveList equalCurveListE,
|
Eventech.Model.CombineCurve current_curve)
|
{
|
var current_eta = current_curve.CurvePara;
|
Eventech.Model.CombineCurve last_curve = null;
|
for (int i = 0; i < equalCurveListE.Count; i++)
|
{
|
var curve = equalCurveListE[i];
|
if (curve.CurvePara <= current_eta + 0.010)
|
continue;
|
if (last_curve == null)
|
{
|
last_curve = curve;
|
continue;
|
}
|
if (curve.CurvePara < last_curve.CurvePara)
|
{
|
last_curve = curve;
|
continue;
|
}
|
else if (Math.Abs(curve.CurvePara - last_curve.CurvePara) < 0.1)
|
{//相同就看谁靠的近一点
|
if (Math.Abs(current_curve.PointInfo.First().X - curve.PointInfo.First().X) < Math.Abs(current_curve.PointInfo.First().X - last_curve.PointInfo.First().X))
|
last_curve = curve;
|
continue;
|
}
|
}
|
|
return last_curve;
|
}
|
|
//两个等效线围城的区域
|
public static Yw.Geometry.Point2dList GetBondaryPoints(
|
Yw.Geometry.Point2dList largeCurve,
|
Yw.Geometry.Point2dList smallCurve,
|
int insertPointNumber = 8)
|
{
|
if (largeCurve.Count <= 2)
|
{
|
var cur1 = BezierCurveHelper.GetApexPoints(smallCurve, insertPointNumber);
|
Yw.Geometry.Point2dList bondaryPoints = new FeatPointList();
|
//放一点余量
|
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 = BezierCurveHelper.GetApexPoints(largeCurve, insertPointNumber);
|
if (points_large.First().X > points_large.Last().X)
|
{//保证从左到右
|
points_large.Reverse();
|
}
|
|
var points_small = BezierCurveHelper.GetApexPoints(smallCurve, insertPointNumber);
|
if (points_small.First().X > points_small.Last().X)
|
{//保证从左到右
|
points_small.Reverse();
|
}
|
Yw.Geometry.Point2dList bondaryPoints = new FeatPointList();
|
//放一点余量
|
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 = 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 = BezierCurveHelper.GetApexPoints(smallCurve, insertPointNumber);
|
if (points_small.First().Y < points_small.First().Y)
|
{//保证从上到下
|
points_small.Reverse();
|
}
|
|
|
//
|
Yw.Geometry.Point2dList points_large = new FeatPointList();//切割后
|
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();//要反一下, 保证从上到小
|
}
|
|
Yw.Geometry.Point2dList bondaryPoints = new FeatPointList();
|
//放一点余量
|
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 = BezierCurveHelper.GetApexPoints(largeCurve, insertPointNumber);
|
if (points_large.First().Y < points_large.First().Y)
|
{//保证从上到下
|
points_large.Reverse();
|
}
|
|
var points_small = BezierCurveHelper.GetApexPoints(smallCurve, insertPointNumber);
|
if (points_small.First().Y < points_small.First().Y)
|
{//保证从上到下
|
points_small.Reverse();
|
}
|
Yw.Geometry.Point2dList bondaryPoints = new FeatPointList();
|
//放一点余量
|
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 ThroughParaCurveList CalcEqualParaCurveE(
|
Eventech.Model.LxpCurveGroupExpress curveGroupExpress,
|
Eventech.Model.LxpSpectrumParas spectrumParas,
|
Eventech.Model.SubSimuCurveParaGrpList allSimuCurves,
|
double maxValueD2,
|
double currentEta)
|
{
|
if (spectrumParas == null)
|
return null;
|
SimuBaseCalculater theSimularHelper = SimularHelper.GetCalculater(spectrumParas);
|
var minValue = spectrumParas.ChangeMin;
|
return CalcEqualParaCurveE(curveGroupExpress, allSimuCurves, maxValueD2, minValue, currentEta, theSimularHelper);
|
}
|
public static ThroughParaCurveList CalcEqualParaCurveE(
|
Eventech.Model.LxpCurveGroupExpress curveGroupExpress,
|
Eventech.Model.LxpSpectrumParas spectrumParas,
|
double maxValueD2,
|
double currentEta)
|
{
|
if (spectrumParas == null)
|
return null;
|
SimuBaseCalculater theSimularHelper = SimularHelper.GetCalculater(spectrumParas);
|
var minValue = spectrumParas.ChangeMin;
|
return CalcEqualParaCurveE(curveGroupExpress, maxValueD2, minValue, currentEta, theSimularHelper);
|
}
|
//生成等效线(理论相似换算计算)
|
public static ThroughParaCurveList CalcEqualParaCurveE(
|
Eventech.Model.LxpCurveGroupExpress curveGroupExpress,
|
double maxValueD2,
|
double minValueD2,
|
double currentEta,
|
SimuBaseCalculater theSimularHelper)
|
{
|
return CalcEqualParaCurveE(curveGroupExpress, null, maxValueD2, minValueD2, currentEta, theSimularHelper);
|
}
|
public static ThroughParaCurveList CalcEqualParaCurveE(
|
Eventech.Model.LxpCurveGroupExpress curveGroupExpress,
|
Eventech.Model.SubSimuCurveParaGrpList allSimuCurves,
|
double maxValueD2,
|
double minValueD2,
|
double currentEta,
|
SimuBaseCalculater theSimularHelper)
|
{
|
if (maxValueD2 <= minValueD2 || curveGroupExpress == null)
|
return null;
|
|
Yw.Geometry.Point2dList curveSmall = new Yw.Geometry.Point2dList();
|
Yw.Geometry.Point2dList curveLarge = new Yw.Geometry.Point2dList();
|
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;//一定要从大到小
|
|
Eventech.Model.CurveExpress simuCurveQH = null;
|
Eventech.Model.CurveExpress simuCurveQE = null;
|
|
if (i == 0)
|
{
|
simuCurveQH = curveGroupExpress.CurveExpressQH;
|
simuCurveQE = curveGroupExpress.CurveExpressQE;
|
}
|
else
|
{
|
simuCurveQH = GetSimuCurveQH(curveGroupExpress, allSimuCurves, maxValueD2, simuValue1, theSimularHelper);
|
simuCurveQE = theSimularHelper.GetSimuPointQE(curveGroupExpress.CurveExpressQE, maxValueD2, simuValue1);
|
}
|
|
//获取等效率下的流量值:由于点可能在最高点附件所以多打些点
|
var equalEffPoints1 = Eventech.Common.FitCurveHelper.GetInterPointX(simuCurveQE, 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 = GetSimuCurveQH(curveGroupExpress, allSimuCurves, maxValueD2, simuValue2, theSimularHelper);
|
//theSimularHelper.GetSimuPointQH(curveGroupExpress.CurveExpressQH, maxValueD2, simuValue2);
|
simuCurveQE = theSimularHelper.GetSimuPointQE(curveGroupExpress.CurveExpressQE, maxValueD2, simuValue2);
|
var equalEffPoints2 = Eventech.Common.FitCurveHelper.GetInterPointX(simuCurveQE, currentEta);
|
if (equalEffPoints2 == null || equalEffPoints2.Count == 0)
|
{//
|
break;
|
}
|
|
double smallPtQ2 = equalEffPoints2.First().X;
|
var smallPtH2 = Eventech.Common.FitCurveHelper.GetFitPointY(simuCurveQH, smallPtQ2);
|
curveSmall.Add(new Yw.Geometry.Point2d(smallPtQ2, smallPtH2));
|
|
if (equalEffPoints2.Count() == 2 && !isMergeCurve)
|
{
|
double largePtQ2 = equalEffPoints2.Last().X;
|
var largePtH2 = Eventech.Common.FitCurveHelper.GetFitPointY(simuCurveQH, largePtQ2);
|
curveLarge.Add(new Yw.Geometry.Point2d(largePtQ2, largePtH2));
|
}
|
}
|
#endregion
|
|
break;
|
}
|
|
double smallPtQ1 = equalEffPoints1.First().X;
|
var smallPtH1 = Eventech.Common.FitCurveHelper.GetFitPointY(simuCurveQH, smallPtQ1);
|
curveSmall.Add(new Yw.Geometry.Point2d(smallPtQ1, smallPtH1));
|
|
if (equalEffPoints1.Count() == 2)
|
{
|
double largePtQ1 = equalEffPoints1.Last().X;
|
|
if (i == 0)
|
{//判断2个点距离是否过小,如过小,就只考虑其中一条
|
if (Math.Abs(smallPtQ1 - largePtQ1) < 2)
|
{
|
isMergeCurve = true;
|
}
|
}
|
if (!isMergeCurve)
|
{
|
var largePtH1 = Eventech.Common.FitCurveHelper.GetFitPointY(simuCurveQH, largePtQ1);
|
curveLarge.Add(new Yw.Geometry.Point2d(largePtQ1, largePtH1));
|
}
|
}
|
}//end for(i...
|
ThroughParaCurveList equalCurves = new ThroughParaCurveList();
|
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);
|
}
|
}
|
ThroughParaCurve equalCurve = new ThroughParaCurve();
|
equalCurve.IsClosed = false;
|
equalCurve.PointInfo = curveSmall;
|
equalCurves.Add(equalCurve);
|
}
|
else
|
{
|
if (curveSmall.Count > 0)
|
{
|
ThroughParaCurve equalCurve = new ThroughParaCurve();
|
equalCurve.IsClosed = false;
|
equalCurve.PointInfo = curveSmall;
|
equalCurves.Add(equalCurve);
|
}
|
if (!isMergeCurve)
|
{
|
if (curveLarge.Count > 0)
|
{
|
ThroughParaCurve equalCurve = new ThroughParaCurve();
|
equalCurve.IsClosed = false;
|
equalCurve.PointInfo = curveLarge;
|
equalCurves.Add(equalCurve);
|
}
|
}
|
}
|
return equalCurves;
|
}
|
|
private static Eventech.Model.CurveExpress GetSimuCurveQH(
|
Eventech.Model.LxpCurveGroupExpress curveGroupExpress,
|
Eventech.Model.SubSimuCurveParaGrpList allSimuCurves,
|
double maxValueD2,
|
double currentValueD2,
|
SimuBaseCalculater theSimularHelper)
|
{
|
if (allSimuCurves == null || allSimuCurves.Count() == 0)
|
return theSimularHelper.GetSimuPointQH(curveGroupExpress.CurveExpressQH, maxValueD2, currentValueD2);
|
|
var sort_allSimuCurves = from x in allSimuCurves orderby x.CurvePara descending select x;
|
if (currentValueD2 > sort_allSimuCurves.First().CurvePara)
|
{
|
return theSimularHelper.GetSimuPointQH(curveGroupExpress.CurveExpressQH, maxValueD2, currentValueD2);
|
}
|
|
foreach (var curve in sort_allSimuCurves)
|
{
|
if (Math.Abs(currentValueD2 - curve.CurvePara) < 1)
|
return curve.CurveExpressQH;
|
if (curve.CurvePara > currentValueD2)
|
{
|
return theSimularHelper.GetSimuPointQH(curve.CurveExpressQH, curve.CurvePara, currentValueD2);
|
}
|
}
|
return theSimularHelper.GetSimuPointQH(sort_allSimuCurves.Last().CurveExpressQH, sort_allSimuCurves.Last().CurvePara, currentValueD2);
|
//return theSimularHelper.GetSimuPointQH(curveGroupExpress.CurveExpressQH, maxValueD2, currentValueD2);
|
}
|
private static Eventech.Model.CurveExpress GetSimuCurveQH(
|
Eventech.Model.CurveExpress curveExpress,
|
Eventech.Model.SubSimuCurveParaGrpList allSimuCurves,
|
double maxValueD2,
|
double currentValueD2,
|
SimuBaseCalculater theSimularHelper)
|
{
|
if (allSimuCurves == null || allSimuCurves.Count() == 0)
|
return theSimularHelper.GetSimuPointQH(curveExpress, maxValueD2, currentValueD2);
|
|
var sort_allSimuCurves = from x in allSimuCurves orderby x.CurvePara descending select x;
|
if (currentValueD2 > sort_allSimuCurves.First().CurvePara)
|
{
|
return theSimularHelper.GetSimuPointQH(curveExpress, maxValueD2, currentValueD2);
|
}
|
foreach (var curve in sort_allSimuCurves)
|
{
|
if (Math.Abs(currentValueD2 - curve.CurvePara) < 1)
|
return curve.CurveExpressQH;
|
if (curve.CurvePara > currentValueD2)
|
{
|
return theSimularHelper.GetSimuPointQH(curve.CurveExpressQH, curve.CurvePara, currentValueD2);
|
}
|
}
|
return theSimularHelper.GetSimuPointQH(sort_allSimuCurves.Last().CurveExpressQH, sort_allSimuCurves.Last().CurvePara, currentValueD2);
|
}
|
//生成等效线(现有等效线插值计算)
|
public static ThroughParaCurve CalcEqualParaCurveE2(
|
Boundary boundary,//为空即可
|
Eventech.Model.LxpCurveGroupExpress curveGroupMax,//最大曲线
|
Eventech.Model.LxpCurveGroupExpress curveGroupMin,//最小曲线
|
Yw.Geometry.Point2dList largeCurve, double largeValue,
|
Yw.Geometry.Point2dList smallCurve, double smallValue,
|
double currentEta)
|
{
|
if (largeValue <= smallValue)
|
return null;
|
if (currentEta >= largeValue)
|
{
|
return new ThroughParaCurve() { IsClosed = false, CurvePara = currentEta, DispTension = 0.5f, PointInfo = largeCurve };
|
}
|
|
if (currentEta <= smallValue)
|
{
|
return new ThroughParaCurve() { IsClosed = false, CurvePara = currentEta, DispTension = 0.5f, PointInfo = smallCurve };
|
}
|
//由于流量扬程数量差别特别大, 所以假设他们在一个100*100的方格内
|
if (boundary == null)
|
{
|
boundary = new Boundary();
|
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.GetPointOfMaxY();
|
|
Yw.Geometry.Point2d max_eta_pt_chart = new FeatPoint() { X = (max_eta_pt.X - boundary.MinX) * ratio_x, Y = (max_eta_pt.Y - boundary.MinY) * ratio_y };
|
|
var points_small = BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
Yw.Geometry.Point2dList points_small_chart = new FeatPointList();
|
foreach (var pt in points_small)
|
{
|
points_small_chart.Add(new FeatPoint() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
}
|
|
|
var total_small_large_chart = points_small_chart.TotalLength();
|
Yw.Geometry.Point2dList center_curve = new FeatPointList();
|
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 FeatPoint() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
}
|
|
return new ThroughParaCurve() { IsClosed = false, CurvePara = currentEta, DispTension = 0.5f, PointInfo = 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.GetPointOfMaxY();
|
Yw.Geometry.Point2d min_eta_pt_largeCurve = largeCurve.GetPointOfMinY();
|
|
Yw.Geometry.Point2d max_eta_pt_chart_largeCurve = new FeatPoint() { 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 FeatPoint() { X = (min_eta_pt_largeCurve.X - boundary.MinX) * ratio_x, Y = (min_eta_pt_largeCurve.Y - boundary.MinY) * ratio_y };
|
|
//暂时只能针对开放曲线
|
var points_small = BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
Yw.Geometry.Point2dList points_small_chart = new FeatPointList();
|
foreach (var pt in points_small)
|
{
|
points_small_chart.Add(new FeatPoint() { 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.GetPointOfMaxY();
|
Yw.Geometry.Point2d min_eta_pt_chart_smallCurve = points_small_chart.GetPointOfMinY();
|
|
|
var total_small_large_chart = points_small_chart.TotalLength();
|
Yw.Geometry.Point2dList center_curve = new FeatPointList();
|
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 FeatPoint() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
}
|
|
return new ThroughParaCurve() { IsClosed = false, CurvePara = currentEta, DispTension = 0.5f, PointInfo = center_curve };
|
|
#endregion
|
}
|
else
|
{
|
#region 大效率线 是 曲线
|
//大效率线 点处理, 暂时只能针对开放曲线
|
var points_large = BezierCurveHelper.GetApexPoints(largeCurve, 5);
|
Yw.Geometry.Point2dList points_large_chart = new FeatPointList();
|
foreach (var pt in points_large)
|
{
|
points_large_chart.Add(new FeatPoint() { 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 = BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
Yw.Geometry.Point2dList points_small_chart = new FeatPointList();
|
foreach (var pt in points_small)
|
{
|
points_small_chart.Add(new FeatPoint() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
}
|
var total_length_small_chart = points_small_chart.TotalLength();//总长
|
|
Yw.Geometry.Point2dList center_curve = new FeatPointList();
|
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 FeatPoint() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
}
|
return new ThroughParaCurve() { IsClosed = false, CurvePara = currentEta, DispTension = 0.5f, PointInfo = 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.GetPointOfMaxY();
|
Yw.Geometry.Point2d min_eta_pt_largeCurve = largeCurve.GetPointOfMinY();
|
|
Yw.Geometry.Point2d max_eta_pt_chart_largeCurve = new FeatPoint() { 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 FeatPoint() { X = (min_eta_pt_largeCurve.X - boundary.MinX) * ratio_x, Y = (min_eta_pt_largeCurve.Y - boundary.MinY) * ratio_y };
|
|
//暂时只能针对开放曲线
|
var points_small = BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
Yw.Geometry.Point2dList points_small_chart = new FeatPointList();
|
foreach (var pt in points_small)
|
{
|
points_small_chart.Add(new FeatPoint() { 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.GetPointOfMaxY();
|
Yw.Geometry.Point2d min_eta_pt_chart_smallCurve = points_small_chart.GetPointOfMinY();
|
var total_length_small_chart = points_small_chart.TotalLength();//总长
|
|
Yw.Geometry.Point2dList center_curve = new FeatPointList();
|
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 FeatPoint() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
}
|
|
return new ThroughParaCurve() { IsClosed = false, CurvePara = currentEta, DispTension = 0.5f, PointInfo = center_curve };
|
|
#endregion
|
}
|
else
|
{
|
var large_monitonicity = IsShapeC(largeCurve);
|
if (large_monitonicity)
|
{//小效率是L型曲线, 大效率线是C型
|
#region 大效率线 是 C型
|
//大效率线 点处理, 暂时只能针对开放曲线
|
var points_large = BezierCurveHelper.GetApexPoints(largeCurve, 5);
|
if (points_large.First().X > points_large.Last().X)
|
{
|
points_large.Reverse();
|
}
|
|
//小效率线 点处理, 暂时只能针对开放曲线
|
var points_small = BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
|
Yw.Geometry.Point2dList points_small_chart = new FeatPointList();
|
foreach (var pt in points_small)
|
{ //换算到图像点
|
points_small_chart.Add(new FeatPoint() { 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)
|
{//小效率线在大效率线左边
|
Yw.Geometry.Point2dList points_large_chart = new FeatPointList();
|
//切断大效率线
|
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 = Eventech.Common.FitCurveHelper.GetFitPointY(curveGroupMin.CurveExpressQH, pt.X);
|
if (pt_in_minFeatCurve_y <= pt.Y)
|
{//换算到图像点
|
points_large_chart.Add(new FeatPoint() { 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 FeatPoint() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
}
|
}
|
var total_length_large_chart = points_large_chart.TotalLength();//长度
|
|
Yw.Geometry.Point2dList center_curve = new FeatPointList();
|
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 FeatPoint() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
}
|
return new ThroughParaCurve() { IsClosed = false, CurvePara = currentEta, DispTension = 0.5f, PointInfo = center_curve };
|
}
|
else
|
{//小效率线在大效率线右边
|
//暂时不考虑
|
return null;
|
}
|
#endregion
|
}
|
else
|
{//小效率是L型曲线, 大效率线是L直型线
|
#region 大效率线 是 L型
|
//大效率线 点处理, 暂时只能针对开放曲线
|
var points_large = BezierCurveHelper.GetApexPoints(largeCurve, 5);
|
if (points_large.First().Y < points_large.Last().Y)
|
{
|
points_large.Reverse();
|
}
|
|
Yw.Geometry.Point2dList points_large_chart = new FeatPointList();
|
foreach (var pt in points_large)
|
{
|
points_large_chart.Add(new FeatPoint() { 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 = BezierCurveHelper.GetApexPoints(smallCurve, 5);
|
if (points_small.First().Y < points_small.Last().Y)
|
{
|
points_small.Reverse();
|
}
|
Yw.Geometry.Point2dList points_small_chart = new FeatPointList();
|
foreach (var pt in points_small)
|
{
|
points_small_chart.Add(new FeatPoint() { X = (pt.X - boundary.MinX) * ratio_x, Y = (pt.Y - boundary.MinY) * ratio_y });
|
}
|
var total_length_small_chart = points_small_chart.TotalLength();//总长
|
|
//换算到图像点
|
//Yw.Geometry.Point2d max_eta_pt_chart_smallCurve = points_small_chart.GetPointOfMaxY();
|
//Yw.Geometry.Point2d min_eta_pt_chart_smallCurve = points_small_chart.GetPointOfMinY();
|
|
//if (smallCurve.First().X < largeCurve.First().X)
|
//小效率线在大效率线左边
|
Yw.Geometry.Point2dList center_curve = new FeatPointList();
|
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 FeatPoint() { X = pt_chart_x / ratio_x + boundary.MinX, Y = pt_chart_y / ratio_y + boundary.MinY });//换算成真实坐标
|
}
|
|
return new ThroughParaCurve() { IsClosed = false, CurvePara = currentEta, DispTension = 0.5f, PointInfo = center_curve };
|
|
#endregion
|
}
|
}
|
}
|
}
|
|
//区分QE曲线
|
//LargeHcurve为高扬程处的L型曲线,middleHcurve中扬程处的C型曲线,smallHcurve为低扬程处的L型曲线
|
//而且返回的曲线参数从小到大排列好了
|
public static bool DevideCurveShape(
|
Eventech.Model.CombineCurveList curveInfoQE,
|
//Eventech.Model.CurveExpress ZeroCurveQH,//0角度的QH线
|
out Eventech.Model.CombineCurveList largeHcurve,
|
out Eventech.Model.CombineCurveList middleHcurve,
|
out Eventech.Model.CombineCurveList smallHcurve)
|
{
|
largeHcurve = middleHcurve = smallHcurve = null;
|
if (curveInfoQE == null || curveInfoQE.Count == 0)
|
return false;
|
Eventech.Model.CombineCurveList caosCurve = new Eventech.Model.CombineCurveList();
|
Eventech.Model.CombineCurveList nonCaosCurve = new Eventech.Model.CombineCurveList();
|
var sort_qe = from x in curveInfoQE orderby x.CurvePara select x;//从小到大排序
|
for (int i = 0; i < sort_qe.Count(); i++)
|
{
|
var curve = sort_qe.ElementAt(i);
|
if (curve.PointInfo == null || curve.PointInfo.Count < 3)
|
continue;
|
//判断是否是C型曲线:注意严格判断X的增减性来判断是否为C型线,有时有问题,因为有时可能有1个点故意偏移一点
|
//所以忽略一个点
|
if (IsShapeC(curve.PointInfo))
|
{//如果小的都是, 效率更高的也是
|
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 Eventech.Model.ThroughParaCurve.Comparer());//从小到大排序
|
middleHcurve = caosCurve;
|
|
//没有非C型曲线
|
if (nonCaosCurve.Count == 0)
|
return true;
|
|
//用效率最高的曲线的Y平均值作为用于比较的中间H值
|
List<Yw.Geometry.Point2d> curveMaxE = middleHcurve.Last().PointInfo;
|
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.CurvePara).Max();
|
var max_eta_curve = (from x in curveInfoQE where x.CurvePara == max_eta select x).ToList();
|
|
middleH = 0;
|
foreach (var curve in max_eta_curve)
|
{
|
//求平均值
|
double averH = 0;
|
for (int i = 0; i < curve.PointInfo.Count; i++)
|
{
|
averH += curve.PointInfo[i].Y;
|
}
|
|
middleH += averH / curve.PointInfo.Count;
|
}
|
|
middleH = middleH / max_eta_curve.Count;
|
}
|
|
//
|
largeHcurve = new Eventech.Model.CombineCurveList();
|
smallHcurve = new Eventech.Model.CombineCurveList();
|
foreach (Eventech.Model.CombineCurve curve in nonCaosCurve)
|
{
|
//求平均值
|
double averH = 0;
|
for (int i = 0; i < curve.PointInfo.Count; i++)
|
{
|
averH += curve.PointInfo[i].Y;
|
}
|
averH = averH / curve.PointInfo.Count;
|
|
//比较平均值
|
if (averH > middleH)
|
{
|
largeHcurve.Add(curve);
|
}
|
else
|
{
|
smallHcurve.Add(curve);
|
}
|
}
|
|
if (largeHcurve.Count > 0)
|
largeHcurve.Sort(new Eventech.Model.ThroughParaCurve.Comparer());//从小到大排序
|
else
|
largeHcurve = null;
|
|
if (smallHcurve.Count > 0)
|
smallHcurve.Sort(new Eventech.Model.ThroughParaCurve.Comparer());//从小到大排序
|
else
|
smallHcurve = null;
|
|
return true;
|
}
|
|
//规整等效线曲线
|
//C型圈:保证曲线Y值从大到小 ,开始Y值大,结束Y值小
|
//一型圈:保证流量值从小到大
|
public static void StandardCurve(ref Eventech.Model.CombineCurve curve)
|
{
|
CombineCurve.Standard4EqualCurveE(ref curve);
|
}
|
public static void StandardCurve(ref Eventech.Model.CombineCurveList 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 Eventech.Model.CombineCurve.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;
|
}
|
|
|
|
}
|
}
|