Exemplo n.º 1
0
        //获取真实坐标对应的画布坐标
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        /// <summary>
        /// 设置真实的数据点,并根据需要计算插值
        /// </summary>
        /// <param name="oriPointArray">真实的数据点</param>
        /// <param name="evalAll">是否需要计算所有数据点</param>
        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();
        }
Exemplo n.º 4
0
        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 / (Math.Abs((H[sPos] * H[sPos])));//原来是   yVlaue = yVlaue /  (H[sPos] * H[sPos]);
                    rsltPoints[i].Current = yVlaue;
                }
                #endregion

                return(rsltPoints);
            }
            catch //(Exception ex)
            {
                return(null);
            }
        }