zoukankan      html  css  js  c++  java
  • 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));
    
                }
            }
    

    下载:

    代码写的很随意,主要是思路。
  • 相关阅读:
    32位和64位系统区别及int字节数
    C++默认参数不能是一个引用
    sprintf的缓冲区溢出
    linux之cp/scp命令+scp命令详解
    linux文件属性详细说明
    linux tar打包
    sed命令
    常用linux命令
    C++ 类T T t;构造时分配的内存在静态数据区 T t=new T()分配的内存在堆 这样说对吗
    Dom事件的三种绑定方式
  • 原文地址:https://www.cnblogs.com/HelloQLQ/p/15413065.html
Copyright © 2011-2022 走看看