using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
|
namespace Eventech.Model
|
{
|
public enum eCurveDrawType
|
{
|
Through=0,
|
Fit=1
|
}
|
//既可以用穿过点也可以用拟合点产生曲线
|
public class CombineCurve :Yw.Pump.CurveEqualE, ICloneable
|
{
|
#region 构造函数
|
public CombineCurve():base()
|
{
|
|
}
|
//拟合的方法
|
public CombineCurve(CurveExpressExPara curvePara, int pointNum)
|
{
|
this.CurveType = eCurveDrawType.Fit;
|
this.CurvePara = curvePara.CurvePara;
|
this.FitCurvePara = curvePara.Clone();
|
this.PointInfo = this.FitCurvePara.ToPoints(pointNum);
|
}
|
//拟合的方法
|
public CombineCurve(CurveExpressExPara curvePara, List<Eventech.Model.FeatPoint> pointPara)
|
{
|
this.CurveType = eCurveDrawType.Fit;
|
this.CurvePara = curvePara.CurvePara;
|
this.FitCurvePara = curvePara.Clone();
|
this.PointInfo = new Eventech.Model.FeatPointList(pointPara);
|
}
|
public CombineCurve TransUnitQ(Eventech.Model.UnitQ thisUnit, Eventech.Model.UnitQ toUnit)
|
{
|
CombineCurve trnCurve = new CombineCurve(this);
|
if (this.FitCurvePara != null)
|
{
|
trnCurve.FitCurvePara = this.FitCurvePara.TransUnitQ(thisUnit, toUnit);
|
}
|
if (this.PointInfo != null)
|
{
|
trnCurve.PointInfo = new FeatPointList();
|
foreach (var pt in this.PointInfo)
|
{
|
trnCurve.PointInfo.Add(
|
new FeatPoint(Eventech.Common.UnitQHelper.Convert(thisUnit, toUnit, pt.X),
|
pt.Y));
|
}
|
}
|
|
return trnCurve;
|
}
|
//通过点
|
public CombineCurve(ThroughParaCurve curvePara):base(curvePara)
|
{
|
this.CurveType = eCurveDrawType.Through;
|
this.FitCurvePara = null;
|
}
|
public CombineCurve(double para, List<Eventech.Model.FeatPoint> curveInfo, bool isClosed , float tension):base(para,curveInfo,isClosed,tension)
|
{
|
this.CurveType = eCurveDrawType.Through;
|
this.FitCurvePara = null;
|
}
|
|
//从数据库
|
public CombineCurve(string rhs, int pointNum = 12)
|
{
|
if (string.IsNullOrEmpty(rhs))
|
{
|
isNull = true;
|
return;
|
}
|
string[] strExpresses = rhs.Split(new string[] { "," }, StringSplitOptions.None);
|
this.CurveType = (eCurveDrawType)Convert.ToInt32(strExpresses[0]);
|
this.CurvePara = Convert.ToDouble(strExpresses[1]);
|
if (this.CurveType == eCurveDrawType.Fit)
|
{
|
this.CurveType = eCurveDrawType.Fit;
|
this.FitCurvePara = new Eventech.Model.CurveExpress(string.Join(",", strExpresses, 2, strExpresses.Count() - 2));
|
this.PointInfo = this.FitCurvePara.ToPoints(pointNum);
|
}
|
else
|
{
|
this.FitCurvePara = null;
|
this.CurveType = eCurveDrawType.Through;
|
ThroughCurve throughPara = new ThroughCurve(string.Join(",", strExpresses, 2, strExpresses.Count() - 2));
|
this.DispTension = throughPara.DispTension;
|
this.IsClosed = throughPara.IsClosed;
|
this.PointInfo = throughPara.PointInfo;
|
this.FitCurvePara = new Eventech.Model.CurveExpress(throughPara.PointInfo, Eventech.Model.eCurveFitType.ThroughPoint);
|
}
|
}
|
//
|
public CombineCurve(CombineCurve rhs)
|
{
|
this.CurveType = rhs.CurveType;
|
this.CurvePara = rhs.CurvePara;
|
if (this.CurveType == eCurveDrawType.Fit)
|
{
|
if (rhs.FitCurvePara != null)
|
this.FitCurvePara = rhs.FitCurvePara.Clone();
|
if (rhs.PointInfo != null)
|
this.PointInfo = rhs.PointInfo.Clone();
|
}
|
else
|
{
|
if (rhs.FitCurvePara != null)
|
this.FitCurvePara = rhs.FitCurvePara.Clone();
|
this.DispTension = rhs.DispTension;
|
this.IsClosed = rhs.IsClosed;
|
if (rhs.PointInfo != null)
|
this.PointInfo = rhs.PointInfo.Clone();
|
}
|
}
|
//
|
public CombineCurve(CombineCurve2 rhs)
|
{
|
this.CurveType = rhs.CurveType;
|
this.CurvePara = rhs.CurvePara;
|
if (this.CurveType == eCurveDrawType.Fit)
|
{
|
this.FitCurvePara = new CurveExpress(rhs.CurveInfo);
|
if (rhs.PointInfo != null)
|
this.PointInfo = rhs.PointInfo.Clone();
|
}
|
else
|
{
|
if (rhs.CurveInfo != null)
|
this.FitCurvePara = new CurveExpress(rhs.CurveInfo, Eventech.Model.eCurveFitType.ThroughPoint);
|
this.DispTension = rhs.DispTension;
|
this.IsClosed = rhs.IsClosed;
|
if (rhs.PointInfo != null)
|
this.PointInfo = rhs.PointInfo.Clone();
|
}
|
}
|
#endregion
|
|
//50HZ->60HZ
|
public CombineCurve From50to60HZ( )
|
{
|
return SimuBySpeed(1.2);
|
}
|
//相似换算(speed_ratio = 新的转速 除以 老的转速)
|
public CombineCurve SimuBySpeed(double speed_ratio)
|
{
|
CombineCurve c60 = new CombineCurve(this);
|
c60.CurvePara = this.CurvePara;
|
c60.CurveType = this.CurveType;
|
c60.DispTension = this.DispTension;
|
if (this.FitCurvePara != null)
|
c60.FitCurvePara = this.FitCurvePara.SimuBySpeed(Eventech.Model.eFeatCurveType.QH, speed_ratio);
|
|
c60.IsClosed = this.IsClosed;
|
if (this.PointInfo != null)
|
{
|
Eventech.Common.SimuSpeedStdCalcer calc = new Common.SimuSpeedStdCalcer();
|
|
List<Eventech.Model.FeatPoint> pointInfo60 = new List<FeatPoint>();
|
for (int i = 0; i < this.PointInfo.Count; i++)
|
{
|
double q50 = this.PointInfo[i].X;
|
double q60 = q50 * speed_ratio;
|
double Y50 = this.PointInfo[i].Y;
|
double h60 = Y50 * speed_ratio * speed_ratio;
|
pointInfo60.Add(new FeatPoint() { X = q60, Y = h60 });
|
}
|
|
c60.PointInfo = new FeatPointList(pointInfo60);
|
}
|
|
return c60;
|
}
|
|
|
private eCurveDrawType _curveType = eCurveDrawType.Fit;
|
public eCurveDrawType CurveType { get { return _curveType; } set { _curveType = value; } }
|
|
|
private CurveExpress _fitCurvePara = null;
|
public CurveExpress FitCurvePara { get { return _fitCurvePara; } set { _fitCurvePara = value; } }
|
|
|
|
#region Clone
|
object ICloneable.Clone()
|
{
|
return Clone();
|
}
|
|
public new CombineCurve Clone()
|
{
|
return new CombineCurve(this);
|
}
|
#endregion
|
|
public void ResetCurve(CurveExpress CurveExpress, int pointNumber)
|
{
|
var points = Eventech.Common.FitCurveHelper.GetFitPoints(CurveExpress, pointNumber);
|
_pointInfo.ResetCurve(points);
|
|
if (_curveType == eCurveDrawType.Fit)
|
{
|
_fitCurvePara.ResetCurve(points, CurveExpress.CurveFitType,false);
|
}
|
}
|
|
public void ResetCurve(List<Eventech.Model.FeatPoint> points)
|
{
|
_pointInfo.ResetCurve(points);
|
|
if (_curveType == eCurveDrawType.Fit)
|
{
|
_fitCurvePara.ResetCurve(points, 3, false);
|
}
|
}
|
public void ResetCurve()
|
{
|
if (_curveType == eCurveDrawType.Fit)
|
{
|
_fitCurvePara.ResetCurve(_pointInfo, 3, false);
|
}
|
}
|
public Eventech.Model.FeatPointList ToPoints(int PointNum)
|
{
|
if (this.isNull)
|
return null;
|
if (_curveType == eCurveDrawType.Fit)
|
return Eventech.Common.FitCurveHelper.GetFitPoints(_fitCurvePara, PointNum);
|
else
|
return _pointInfo.Clone();
|
}
|
|
public void ReClacPoint(int PointNum)
|
{
|
if (this.isNull)
|
return ;
|
if (_curveType == eCurveDrawType.Fit)
|
_pointInfo = Eventech.Common.FitCurveHelper.GetFitPoints(_fitCurvePara, PointNum);
|
}
|
|
#region ToDsString
|
public new string ToDsString()
|
{
|
return ToDsString(this);
|
}
|
|
public static string ToDsString(CombineCurve curve)
|
{
|
if (curve == null)
|
return null;
|
if (curve.IsNull)
|
return null;
|
|
|
if (curve.CurveType == eCurveDrawType.Fit)
|
return string.Format("{0},{1},{2}", (int)curve.CurveType, curve.CurvePara, curve.FitCurvePara.ToDsString());
|
else
|
return string.Format("{0},{1},{2}", (int)curve.CurveType, curve.CurvePara, (curve as ThroughCurve).ToDsString());
|
}
|
|
public override string ToString()
|
{
|
return this.CurvePara.ToString();
|
}
|
#endregion
|
|
|
#region 曲线标准化
|
//轴流泵QH曲线(单条线,流量从小到大排序)
|
public static void Standard4FeatCurveQH(ref Eventech.Model.CombineCurve curve)
|
{
|
if (curve == null)
|
return;
|
if (curve.PointInfo == null || curve.PointInfo.Count == 0)
|
return;
|
if (curve.CurveType == eCurveDrawType.Fit)
|
{
|
curve.PointInfo = curve.ToPoints(6);//只要保证流量从小到大即可
|
return;//拟合的方法不需要排序
|
}
|
|
//保证流量值从小到大
|
if (curve.PointInfo.First().X > curve.PointInfo.Last().X)
|
{
|
curve.PointInfo.Reverse();
|
}
|
}
|
|
//等效线曲线
|
//C型圈:保证曲线Y值从大到小 ,开始Y值大,结束Y值小
|
//一型圈:保证流量值从小到大
|
public static void Standard4EqualCurveE(ref Eventech.Model.CombineCurve curve)
|
{
|
if (curve == null)
|
return;
|
if (curve.PointInfo == null || curve.PointInfo.Count == 0)
|
return;
|
if (curve.CurveType == eCurveDrawType.Fit)
|
{
|
curve.PointInfo = curve.ToPoints(6);//只要保证流量从小到大即可
|
return;//拟合的方法不需要排序
|
}
|
if (curve.IsClosed)
|
return;//封闭就保证原始状态即可
|
|
//判断各种情况
|
Eventech.Model.FeatPointList point = curve.PointInfo;
|
if (Eventech.Common.EqualParaCurveEListHelper.IsShapeC(point))
|
{//C型圈:保证曲线X值从小到大, 即开始X值小, 结束X值大
|
if (point.First().X > point.Last().X)
|
{
|
point.Reverse();
|
}
|
}
|
else
|
{ //保证Y值从大到小(即从上到下)
|
if (point.First().Y < point.Last().Y)
|
{
|
point.Reverse();
|
}
|
}
|
|
curve.PointInfo = point;
|
}
|
#endregion
|
|
public static CombineCurve toM3H(UnitQ unit, CombineCurve curvePara)
|
{
|
if (unit == UnitQ.M3H)
|
return curvePara;
|
|
if (curvePara == null)
|
return null;
|
if (curvePara.PointInfo == null)
|
return curvePara;
|
|
CombineCurve newCurve = curvePara.Clone();
|
newCurve.PointInfo = new Eventech.Model.FeatPointList();
|
for (int i = 0; i < curvePara.PointInfo.Count; i++)
|
{
|
Eventech.Model.FeatPoint pt = curvePara.PointInfo[i];
|
newCurve.PointInfo.Add(new Eventech.Model.FeatPoint(Eventech.Common.UnitQHelper.toM3H(unit, pt.X), pt.Y));
|
}
|
|
return newCurve;
|
}
|
|
public static CombineCurve toLS(UnitQ unit, CombineCurve curvePara)
|
{
|
if (unit == UnitQ.LS)
|
return curvePara;
|
|
if (curvePara == null)
|
return null;
|
if (curvePara.PointInfo == null)
|
return curvePara;
|
|
CombineCurve newCurve = curvePara.Clone();
|
newCurve.PointInfo = new Eventech.Model.FeatPointList();
|
for (int i = 0; i < curvePara.PointInfo.Count; i++)
|
{
|
Eventech.Model.FeatPoint pt = curvePara.PointInfo[i];
|
newCurve.PointInfo.Add(new Eventech.Model.FeatPoint(Eventech.Common.UnitQHelper.toLS(unit, pt.X), pt.Y));
|
}
|
|
return newCurve;
|
}
|
|
|
public new class Comparer : IComparer<CombineCurve>
|
{
|
public Comparer()
|
{
|
}
|
|
#region IComparer<Eventech.Model.FeatPoint> 成员
|
private double ignoreDis = 0.001;
|
int IComparer<CombineCurve>.Compare(CombineCurve obj1, CombineCurve obj2)
|
{
|
if (Math.Abs(obj1.CurvePara - obj2.CurvePara) < ignoreDis)
|
{//参数一样 就比较Y的平均值
|
double y1_arv = (from x in obj1.PointInfo select x.Y).Average();
|
double y2_arv = (from x in obj2.PointInfo 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.CurvePara > obj2.CurvePara)
|
{
|
return 1;
|
}
|
else
|
{
|
return -1;
|
}
|
}
|
|
#endregion
|
}
|
|
//比较相同:主要用与LIST的Contains方法和Distinct
|
public new class EqualComparer : IEqualityComparer<CombineCurve>
|
{
|
private double ignoreDis = 0.001;
|
public EqualComparer()
|
{
|
ignoreDis = 0.001;
|
}
|
public EqualComparer(double dis)
|
{
|
ignoreDis = dis;
|
}
|
|
public bool Equals(CombineCurve lhs, CombineCurve rhs)
|
{
|
if (Math.Abs(lhs.CurvePara - rhs.CurvePara) < ignoreDis)
|
return true;
|
else
|
return false;
|
}
|
|
public int GetHashCode(CombineCurve obj)
|
{
|
//return obj.X.GetHashCode() + obj.Y.GetHashCode();
|
return 0;
|
}
|
}
|
|
|
}
|
|
|
}
|