Winform 動態畫曲線 波峰波谷識別


項目需要識別數組的波峰波谷,我就想 可視化的測試自己的判斷波峰波谷的算法,於是就有了下面這張圖。
我就用gdi+再panel上描點,點畫完后,就點擊分析按鈕藍色的為波峰 綠色的為波谷。雖然說能識別出來,但是對於波峰來說識別的點對於項目來說有些生硬。比如這兩點
按照項目來講 384也應算作峰頂,但是我目前還沒實現。我的實現的思路是這樣,定義一個diff值,比如10,再387這里是最大值,然后往前循環,如果前一個值和387相差<10,再往前找,並判斷前面的點與387這個點的時間間隔是否>1秒 如果相差>10或者間隔>1秒就停止循環。
 
算法的思路是這樣,首先判斷曲線走勢,為上升的話, 找到第一個封頂,為下降的話,第一個點就是峰頂。然后找峰谷 ,一個循環就結束了。
代碼:
private void Recognize()
        {

            Font font = new Font("宋體", 10);

            if (LstDp.Count < 2)
            {
                return;
            }

            bIsScanStart = true;

            DataPoint dpDown = null;

            for (int i = 1; i < LstDp.Count; i++)
            {

                if (bIsScanStart)
                {

                    iSIndex = i - 1;
                    //判斷開始是否上升
                    bStartIsUp = ChargeIsStartUp(iSIndex, LstDp);

                    dpDown = LstDp[iSIndex];

                    bIsScanStart = false;
                }

                var dS = LstDp[i - 1];

                var dNext = LstDp[i];

                int topIndex = 0;

                if (bStartIsUp)//開始是上升的
                {

                    while (i + 1 < LstDp.Count)
                    {

                        dS = LstDp[i];

                        dNext = LstDp[i + 1];

                        ++i;

                        if (dNext.Val - dS.Val < 0)//到達峰頂dS
                        {

                            LstPtTop.Add(dS);

                            topIndex = LstPtTop.Count - 1;
                            break;

                        }

                    }

                }

                else
                {
                    LstPtTop.Add(dpDown);
                    topIndex = LstPtTop.Count - 1;
                }

                DataPoint temp = LstPtTop[topIndex];

                int j = i + 1;

                while (j < LstDp.Count)
                {

                    var dTopNext = LstDp[j];

                    var dTopS = LstDp[j - 1];

                    j++;

                    if (dTopNext.Val - dTopS.Val > 0)//峰谷dTops
                    {

                        LstDwn.Add(dTopS);
                        bIsScanStart = true;
                        break;
                    }

                    else
                    {

                        continue;

                    }
                }

                i = j - 1;

                if (i == LstDp.Count() - 1)
                {
                    if (LstDp[i].Val - LstDp[i - 1].Val > 0)
                    {
                        LstPtTop.Add(LstDp[i]);
                    }
                }
            }
            for (int i = 0; i < LstPtTop.Count; i++)
            {

                g.DrawString("峰頂", font, Brushes.Blue, new Point(LstPtTop[i].pt.X,LstPtTop[i].pt.Y-10));

            }

            for (int i = 0; i < LstDwn.Count; i++)
            {

                g.DrawString("峰谷", font, Brushes.DarkGreen, new Point(LstDwn[i].pt.X, LstDwn[i].pt.Y + 5));

            }
        }

下載:

代碼寫的很隨意,主要是思路。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM