using IStation.Model;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
|
namespace IStation.Common
|
{
|
//修正曲线
|
public static class AmendCurveHelper
|
{
|
/// <summary>
|
/// 根据曲线中一个点,修改曲线,按比例调整(0点不会变,在newPt.X变化最大,大于newPt.X的点 和newPt一样变化
|
/// </summary>
|
/// <param name="originCurvePoints"></param>
|
/// <param name="newPt">在newPt.X</param>
|
/// <returns></returns>
|
public static List<IStation.Model.CurvePoint> ByOnePointY1(List<IStation.Model.CurvePoint> originCurvePoints, IStation.Model.CurvePoint newPt)
|
{
|
if (originCurvePoints == null)
|
return null;
|
|
List<IStation.Model.CurvePoint> newCurve = new List<IStation.Model.CurvePoint>();
|
|
//计算差距
|
double baseX = newPt.X;
|
double baseDisY = IStation.Common.FitCurveHelper.GetFitPointY(originCurvePoints, baseX) - newPt.Y;
|
|
//
|
for (int i = 0; i < originCurvePoints.Count; i++)
|
{
|
double dis = 1;
|
if (originCurvePoints[i].X <= baseX)
|
{
|
dis = originCurvePoints[i].X * baseDisY / baseX;
|
}
|
else
|
{
|
dis = baseDisY;
|
}
|
|
newCurve.Add(new IStation.Model.CurvePoint(originCurvePoints[i].X, originCurvePoints[i].Y - dis));
|
}
|
|
//
|
newCurve.Add(newPt);
|
|
return IStation.Model.FitCurveHelper.GetFitPoints(newCurve);
|
}
|
|
|
public static CurveExpress ByOnePointY1(CurveExpress originCurve, IStation.Model.CurvePoint newPt)
|
{
|
return ByOnePointY1(originCurve, newPt, 30);
|
}
|
|
//insertPointNumber越多越精确
|
public static CurveExpress ByOnePointY1(CurveExpress originCurve, IStation.Model.CurvePoint newPt, int insertPointNumber)
|
{
|
if (originCurve == null)
|
return null;
|
|
CurveExpress newCurveExpress = originCurve;
|
for (int i = 0; i < 3; i++)
|
{
|
newCurveExpress = ByOnePointY1内部(newCurveExpress, newPt, insertPointNumber);
|
}
|
|
return newCurveExpress;
|
}
|
|
private static CurveExpress ByOnePointY1内部(CurveExpress originCurve, IStation.Model.CurvePoint newPt, int insertPointNumber)
|
{
|
if (originCurve == null)
|
return null;
|
|
List<IStation.Model.CurvePoint> newCurvePoints = new List<IStation.Model.CurvePoint>();
|
List<IStation.Model.CurvePoint> originCurvePoints = IStation.Model.FitCurveHelper.GetFitPoints(originCurve, insertPointNumber);
|
//计算差距
|
double baseX = newPt.X;
|
double baseDisY = IStation.Model.FitCurveHelper.GetFitPointY(originCurve, baseX) - newPt.Y;
|
|
//
|
for (int i = 0; i < insertPointNumber; i++)
|
{
|
double dis = 1;
|
if (originCurvePoints[i].X <= baseX)
|
{
|
dis = originCurvePoints[i].X * baseDisY / baseX;
|
}
|
else
|
{
|
dis = baseDisY;
|
}
|
|
newCurvePoints.Add(new IStation.Model.CurvePoint(originCurvePoints[i].X, originCurvePoints[i].Y - dis));
|
}
|
|
//
|
newCurvePoints.Add(newPt);
|
|
var newCurveExpress = new CurveExpress(newCurvePoints);
|
return newCurveExpress;
|
}
|
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="originCurve"></param>
|
/// <param name="newPt"></param>
|
/// <param name="ignoreDis">小于多少就不迭代了</param>
|
/// <param name="SplitPointNumber">分割点数</param>
|
/// <param name="iterationNum">迭代次数</param>
|
/// <returns></returns>
|
public static IStation.Model.CurveExpress ByOnePointY1(IStation.Model.CurveExpress originCurve, IStation.Model.CurvePoint newPt, double ignoreDis,
|
int SplitPointNumber = 100, int iterationNum = 6)
|
{
|
if (originCurve == null)
|
return null;
|
IStation.Model.CurveExpress newCurve = new CurveExpress(originCurve);
|
|
for (int i = 0; i < iterationNum; i++)
|
{
|
var pointQE = IStation.Model.FitCurveHelper.GetFitPoints(newCurve, SplitPointNumber);
|
newCurve = new CurveExpress(
|
IStation.Common.AmendCurveHelper.ByOnePointY1(pointQE, newPt));
|
if (Math.Abs(IStation.Model.FitCurveHelper.GetFitPointY(newCurve, newPt.X) - newPt.Y) < ignoreDis)
|
{
|
return newCurve;
|
}
|
}
|
|
return newCurve;
|
}
|
|
|
//2点修补,新曲线通过minPt,maxPt
|
public static List<IStation.Model.CurvePoint> ByTwoPointY1(List<IStation.Model.CurvePoint> originCurve0, IStation.Model.CurvePoint minPt, IStation.Model.CurvePoint fixPt, IStation.Model.CurvePoint maxPt)
|
{
|
if (originCurve0 == null || originCurve0.Count < 3)
|
return null;
|
//if (minPt.X > fixPt.X)
|
// return null;
|
//if (fixPt.X > maxPt.X)
|
// return null;
|
|
double x, y;
|
|
//先保证通过额定规定点
|
double ratedDis1 = IStation.Common.FitCurveHelper.GetFitPointY(originCurve0, fixPt.X) - fixPt.Y;
|
var originCurve1 = originCurve0;// new List<CurvePoint>();
|
//foreach (var pt in originCurve0)
|
//{
|
// newCurve.Add(new CurvePoint(pt.X, pt.Y - ratedDis1));
|
//}
|
double ratedPtDisY = IStation.Common.FitCurveHelper.GetFitPointY(originCurve1, fixPt.X) - fixPt.Y;
|
double minPtDisY = IStation.Common.FitCurveHelper.GetFitPointY(originCurve1, minPt.X) - minPt.Y;
|
double maxPtDisY = IStation.Common.FitCurveHelper.GetFitPointY(originCurve1, maxPt.X) - maxPt.Y;
|
|
List<IStation.Model.CurvePoint> amendCurve = new List<IStation.Model.CurvePoint>();
|
int num = 4;
|
double space = minPt.X / (num - 1);
|
for (int i = 0; i < num - 1; i++)
|
{
|
x = space * i;
|
y = IStation.Common.FitCurveHelper.GetFitPointY(originCurve1, x) - minPtDisY * i / (num - 1);
|
amendCurve.Add(new IStation.Model.CurvePoint(x, y));
|
}
|
|
//插入小流量点
|
amendCurve.Add(minPt);
|
|
//小流量点和中间点插入2点
|
x = minPt.X + (fixPt.X - minPt.X) / 3;
|
y = IStation.Common.FitCurveHelper.GetFitPointY(originCurve1, x) - (ratedPtDisY + (ratedPtDisY - minPtDisY) / 3);
|
amendCurve.Add(new IStation.Model.CurvePoint(x, y));
|
|
|
x = minPt.X + (fixPt.X - minPt.X) * 2 / 3;
|
y = IStation.Common.FitCurveHelper.GetFitPointY(originCurve1, x) - (ratedPtDisY + (ratedPtDisY - minPtDisY) * 2 / 3);
|
amendCurve.Add(new IStation.Model.CurvePoint(x, y));
|
|
|
//插入额定点
|
amendCurve.Add(fixPt);
|
|
//中间插入2点
|
x = fixPt.X + (maxPt.X - fixPt.X) / 3;
|
y = IStation.Common.FitCurveHelper.GetFitPointY(originCurve1, x) - (maxPtDisY + (maxPtDisY - ratedPtDisY) / 3);
|
amendCurve.Add(new IStation.Model.CurvePoint(x, y));
|
|
|
x = minPt.X + (fixPt.X - minPt.X) * 2 / 3;
|
y = IStation.Common.FitCurveHelper.GetFitPointY(originCurve1, x) - (maxPtDisY + (maxPtDisY - ratedPtDisY) * 2 / 3);
|
amendCurve.Add(new IStation.Model.CurvePoint(x, y));
|
|
|
|
//插入大流量点
|
amendCurve.Add(maxPt);
|
|
//插入最后一个点
|
if (maxPt.X < originCurve1.Last().X * 0.98)
|
{
|
amendCurve.Add(new IStation.Model.CurvePoint(originCurve1.Last().X, originCurve1.Last().Y - maxPtDisY));
|
}
|
|
|
return IStation.Model.FitCurveHelper.GetFitPoints(amendCurve);
|
}
|
|
|
public static List<IStation.Model.CurvePoint> ByThreePointY1(List<IStation.Model.CurvePoint> originCurve0, IStation.Model.CurvePoint minPt, IStation.Model.CurvePoint ratedPt, IStation.Model.CurvePoint maxPt, int splitPointNum = 13)
|
{
|
if (originCurve0 == null || originCurve0.Count < 3)
|
return null;
|
if (minPt.X > ratedPt.X)
|
return null;
|
if (ratedPt.X > maxPt.X)
|
return null;
|
|
var originCurve1 = IStation.Model.FitCurveHelper.GetFitPoints(originCurve0, splitPointNum);
|
|
int indexMinDis = 0;
|
double minDis = minPt.X;
|
for (int i = 0; i < originCurve1.Count; i++)
|
{
|
var pt = originCurve1[i];
|
if (Math.Abs(pt.X - minPt.X) < minDis)
|
{
|
minDis = Math.Abs(pt.X - minPt.X);
|
indexMinDis = i;
|
}
|
}
|
originCurve1[indexMinDis].X = minPt.X;
|
originCurve1[indexMinDis].Y = minPt.Y;
|
|
|
indexMinDis = 0;
|
minDis = ratedPt.X;
|
for (int i = 0; i < originCurve1.Count; i++)
|
{
|
var pt = originCurve1[i];
|
if (Math.Abs(pt.X - ratedPt.X) < minDis)
|
{
|
minDis = Math.Abs(pt.X - minPt.X);
|
indexMinDis = i;
|
}
|
}
|
originCurve1[indexMinDis].X = ratedPt.X;
|
originCurve1[indexMinDis].Y = ratedPt.Y;
|
|
|
indexMinDis = 0;
|
minDis = maxPt.X;
|
for (int i = 0; i < originCurve1.Count; i++)
|
{
|
var pt = originCurve1[i];
|
if (Math.Abs(pt.X - maxPt.X) < minDis)
|
{
|
minDis = Math.Abs(pt.X - minPt.X);
|
indexMinDis = i;
|
}
|
}
|
originCurve1[indexMinDis].X = maxPt.X;
|
originCurve1[indexMinDis].Y = maxPt.Y;
|
|
// IStation.Model.FitCurveHelper theCurveFit = new IStation.Model.FitCurveHelper();
|
// theCurveFit.FitPointNum = originCurve.Count;
|
return IStation.Model.FitCurveHelper.GetFitPoints(originCurve1);
|
}
|
|
|
//修改曲线0点位置的值,曲线值会根据比例逐渐变化,直到fixPtX,不再变化
|
public static List<IStation.Model.CurvePoint> ByZeroPointY(List<IStation.Model.CurvePoint> originCurve, double fixPtX, double zeroPtY)
|
{
|
if (originCurve == null || originCurve.Count < 3)
|
return null;
|
|
IStation.Model.CurvePointList newCurve = new IStation.Model.CurvePointList();
|
|
|
//计算差距
|
double zeroDis = originCurve.First().Y - zeroPtY;
|
|
//
|
for (int i = 0; i < originCurve.Count; i++)
|
{
|
double dis = 0;
|
if (originCurve[i].X <= fixPtX)
|
{
|
dis = zeroDis * (1 - originCurve[i].X / fixPtX);
|
}
|
else
|
{
|
dis = 0;
|
}
|
|
newCurve.Add(new IStation.Model.CurvePoint(originCurve[i].X, originCurve[i].Y - dis));
|
}
|
|
//
|
return IStation.Model.FitCurveHelper.GetFitPoints(newCurve, originCurve.Count);
|
}
|
|
|
public static CurveExpress ByZeroPointY(CurveExpress originCurve, double fixPtX, double zeroPtY)
|
{
|
if (originCurve == null)
|
return null;
|
List<IStation.Model.CurvePoint> originCurvePoint = IStation.Model.FitCurveHelper.GetFitPoints(originCurve, 30);
|
return new CurveExpress(ByZeroPointY(originCurvePoint, fixPtX, zeroPtY));
|
}
|
|
}
|
}
|