//获取真实坐标对应的画布坐标 private Point GetPointByOriginal(I_V_Point oriPoint) { double X = _CvsRect.X + oriPoint.Voltage * _CvsRect.Width / CurvesCurrent; double Y = _CvsRect.Y + (CurvesVoltage - oriPoint.Current) * _CvsRect.Height / CurvesVoltage; Point point = new Point(); point.X = (int)X; point.Y = (int)Y; return(point); }
public static I_V_Point[] Spline1(I_V_Point[] oriPoints) { double maxVoltage = oriPoints[oriPoints.Length - 1].Voltage; int len = (int)(maxVoltage * _CurvesPaneWidth / _MaxVoltageAxis - 0.5); Coefs[] coefsArray = CalcCoefs(oriPoints); I_V_Point[] pointArray = new I_V_Point[len]; for (int i = 0; i < len; i++) { double xVal = i * _MaxVoltageAxis / _CurvesPaneWidth; int sPos = 0; if (xVal < oriPoints[0].Voltage) { sPos = 0; } else if (xVal > oriPoints[len - 1].Voltage) { sPos = len - 2; } else { for (int j = 1; j < len; j++) { if (xVal <= oriPoints[j].Voltage) { sPos = j - 1; break; } } } pointArray[i] = new I_V_Point(); pointArray[i].Voltage = xVal; pointArray[i].Current = EvaluateValue(coefsArray[sPos], xVal); } return(pointArray); }
public static I_V_Point[] Spline(I_V_Point[] oriPoints) { try { if (oriPoints.Length < 3) { throw new Exception("参考点不能少于3个。"); } double maxVoltage = oriPoints[oriPoints.Length - 1].Voltage; int pointCount = (int)(maxVoltage * _CurvesPaneWidth / _MaxVoltageAxis - 0.5); int cNum = oriPoints.Length - 1; //N double[] H = new double[cNum + 1]; //dX1[N + 1] double[] A = new double[cNum + 1]; //dx2[N + 1] double[] B = new double[cNum + 1]; //B[N +1] double[] C = new double[cNum + 1]; //C[N +1] double[] D = new double[cNum + 1]; //D[N +1] #region 计算中间参数 for (int i = 1; i <= cNum; i++) { H[i - 1] = oriPoints[i].Voltage - oriPoints[i - 1].Voltage; } for (int i = 1; i <= cNum - 1; i++) { A[i] = H[i - 1] / (H[i - 1] + H[i]); B[i] = 3 * ((1 - A[i]) * (oriPoints[i].Current - oriPoints[i - 1].Current) / H[i - 1] + A[i] * (oriPoints[i + 1].Current - oriPoints[i].Current) / H[i]); } A[0] = 1; A[cNum] = 0; B[0] = 3 * (oriPoints[1].Current - oriPoints[0].Current) / H[0]; B[cNum] = 3 * (oriPoints[cNum].Current - oriPoints[cNum - 1].Current) / H[cNum - 1]; for (int i = 0; i <= cNum; i++) { D[i] = 2; } for (int i = 0; i <= cNum; i++) { C[i] = 1 - A[i]; } for (int i = 1; i <= cNum; i++) { if (Math.Abs(D[i]) <= 0.000001) { throw new Exception("数据错误,无解"); } A[i - 1] = A[i - 1] / D[i - 1]; B[i - 1] = B[i - 1] / D[i - 1]; D[i] = A[i - 1] * (-C[i]) + D[i]; B[i] = -C[i] * B[i - 1] + B[i]; } B[cNum] = B[cNum] / D[cNum]; for (int i = 1; i <= cNum; i++) { B[cNum - i] = B[cNum - i] - A[cNum - i] * B[cNum - i + 1]; } #endregion #region 计算返回值 I_V_Point[] rsltPoints = new I_V_Point[pointCount]; double dbStep = (oriPoints[cNum].Voltage - oriPoints[0].Voltage) / (pointCount - 1); rsltPoints[0] = oriPoints[0]; for (int i = 1; i < pointCount; ++i) { rsltPoints[i] = new I_V_Point(); double xValue = oriPoints[0].Voltage + dbStep * i; rsltPoints[i].Voltage = xValue; int sPos = 0; if (xValue < oriPoints[0].Voltage) { sPos = 0; } else if (xValue > oriPoints[cNum].Voltage) { sPos = cNum - 1; } else { for (int j = 1; j <= cNum; j++) { if (xValue <= oriPoints[j].Voltage) { sPos = j - 1; break; } } } double diffPrev = xValue - oriPoints[sPos].Voltage; double diffNext = oriPoints[sPos + 1].Voltage - xValue; double yVlaue = 0; yVlaue = (3 * Math.Pow(diffNext, 2) - 2 * Math.Pow(diffNext, 3) / H[sPos]) * oriPoints[sPos].Current + (3 * Math.Pow(diffPrev, 2) - 2 * Math.Pow(diffPrev, 3) / H[sPos]) * oriPoints[sPos + 1].Current + (H[sPos] * Math.Pow(diffNext, 2) - Math.Pow(diffNext, 3)) * B[sPos] - (H[sPos] * Math.Pow(diffPrev, 2) - Math.Pow(diffPrev, 3)) * B[sPos + 1]; yVlaue = yVlaue / (H[sPos] * H[sPos]); rsltPoints[i].Current = yVlaue; } #endregion return(rsltPoints); } catch //(Exception ex) { return(null); } }
public void SetOriginalPoints(I_V_Point[] oriPointArray, bool evalAll) { OldoriPointArray = oriPointArray; //#region 2013-06-03 曲线异常Bug修改,如果倒数第二个点靠近最后一个点,则移除 I_V_Point[] pointArray = null; //if (oriPointArray != null) //{ // int oriLen = oriPointArray.Length; // if (oriPointArray[oriLen - 2].Current < 0.5) // { // pointArray = new I_V_Point[oriLen - 1]; // Array.Copy(oriPointArray, pointArray, oriLen - 1); // pointArray[oriLen - 2].Current = oriPointArray[oriLen - 1].Current; // pointArray[oriLen - 2].Voltage = oriPointArray[oriLen - 1].Voltage; // } // else // { // pointArray = oriPointArray; // } //} //#endregion _OriPointList = new List <Point>(); _CurvasPointList = new List <Point>(); _PowerPointList = new List <Point>();// add by genhong.hu On 2016-06-02 增加功率曲线 if (oriPointArray == null) { CleanSpine(); return; } if (oriPointArray.Length != 3) { //MessageBox.Show("RFID标签数据异常,无法显示曲线。"); //return; if (oriPointArray != null) { int oriLen = oriPointArray.Length; if (oriPointArray[oriLen - 2].Current < 0.5) { pointArray = new I_V_Point[oriLen - 1]; Array.Copy(oriPointArray, pointArray, oriLen - 1); pointArray[oriLen - 2].Current = oriPointArray[oriLen - 1].Current; pointArray[oriLen - 2].Voltage = oriPointArray[oriLen - 1].Voltage; } else { pointArray = oriPointArray; } } } else { #region ====================================================== int PointCount = 100; double Voc = oriPointArray[2].Voltage; double Isc = oriPointArray[0].Current; double Vpm = oriPointArray[1].Voltage; double Ipm = oriPointArray[1].Current; pointArray = new I_V_Point[PointCount + 3]; I_V_Point s1 = new I_V_Point(); s1.Voltage = 0; s1.Current = Isc; pointArray[0] = s1; for (int i = 1; i < PointCount + 1; i++) { I_V_Point s2 = new I_V_Point(); s2.Voltage = 0 + (Vpm - 0) / (PointCount + 1) * i; s2.Current = Isc - (Isc - Ipm) / (PointCount + 1) * i; pointArray[i] = s2; } I_V_Point s4 = new I_V_Point(); s4.Voltage = Vpm; s4.Current = Ipm; I_V_Point s5 = new I_V_Point(); s5.Voltage = Voc; s5.Current = 0; pointArray[PointCount + 1] = s4; pointArray[PointCount + 2] = s5; #endregion } foreach (I_V_Point oriPoint in pointArray) { _OriPointList.Add(GetPointByOriginal(oriPoint)); } if (evalAll) { I_V_Point[] points = MySpline.Spline(pointArray); if (points == null) { MessageBox.Show("RFID标签数据异常,无法显示曲线。"); return; } foreach (I_V_Point oriPoint in points) { _CurvasPointList.Add(GetPointByOriginal(oriPoint)); // add by genhong.hu On 2016-06-02 增加功率曲线 P_V_Point pmaxpoint = new P_V_Point(); pmaxpoint.Pmax = oriPoint.Current * oriPoint.Voltage; pmaxpoint.Voltage = oriPoint.Voltage; _PowerPointList.Add(GetPowerPointByOriginal(pmaxpoint)); } #region 计算 // _CurvasPointList = _OriPointList; #endregion //2014-03-30 曲线画到电流为0 Point lastPointToZero = new Point(); lastPointToZero.X = _CurvasPointList[_CurvasPointList.Count - 1].X; lastPointToZero.Y = _CvsRect.Top + _CvsRect.Height; _CurvasPointList.Add(lastPointToZero); _PowerPointList.Add(lastPointToZero);// add by genhong.hu On 2016-06-02 增加功率曲线 } this.Invalidate(); }
/// <summary> /// 设置真实的数据点,并根据需要计算插值 /// </summary> /// <param name="oriPointArray">真实的数据点</param> /// <param name="evalAll">是否需要计算所有数据点</param> public void SetOriginalPoints_0(I_V_Point[] oriPointArray, bool evalAll) { #region 2013-06-03 曲线异常Bug修改,如果倒数第二个点靠近最后一个点,则移除 I_V_Point[] pointArray = null; if (oriPointArray != null) { int oriLen = oriPointArray.Length; if (oriPointArray[oriLen - 2].Current < 0.5) { pointArray = new I_V_Point[oriLen - 1]; Array.Copy(oriPointArray, pointArray, oriLen - 1); pointArray[oriLen - 2].Current = oriPointArray[oriLen - 1].Current; pointArray[oriLen - 2].Voltage = oriPointArray[oriLen - 1].Voltage; } else { pointArray = oriPointArray; } } #endregion _OriPointList = new List <Point>(); _CurvasPointList = new List <Point>(); _PowerPointList = new List <Point>();// add by genhong.hu On 2016-06-02 增加功率曲线 if (pointArray == null) { return; } foreach (I_V_Point oriPoint in pointArray) { _OriPointList.Add(GetPointByOriginal(oriPoint)); } if (evalAll) { I_V_Point[] points = MySpline.Spline(pointArray); if (points == null) { MessageBox.Show("RFID标签数据异常,无法显示曲线。"); return; } foreach (I_V_Point oriPoint in points) { _CurvasPointList.Add(GetPointByOriginal(oriPoint)); // add by genhong.hu On 2016-06-02 增加功率曲线 P_V_Point pmaxpoint = new P_V_Point(); pmaxpoint.Pmax = oriPoint.Current * oriPoint.Voltage; pmaxpoint.Voltage = oriPoint.Voltage; _PowerPointList.Add(GetPowerPointByOriginal(pmaxpoint)); } //2014-03-30 曲线画到电流为0 Point lastPointToZero = new Point(); lastPointToZero.X = _CurvasPointList[_CurvasPointList.Count - 1].X; lastPointToZero.Y = _CvsRect.Top + _CvsRect.Height; _CurvasPointList.Add(lastPointToZero); _PowerPointList.Add(lastPointToZero);// add by genhong.hu On 2016-06-02 增加功率曲线 } this.Invalidate(); }