zoukankan      html  css  js  c++  java
  • 等值线算法(转载)

    等值线算法

    对于二维的规则网格,本文以104*104格点大小数据做为说明,数据下载:http://yunpan.cn/ccB7Y36eLXk35  访问密码 00c3 ,Qcloud.txt为原始数据,re01.txt为01代码

    一.算法如下:

    1.在该层的数据网格中求出所有四个相邻的数据点构成的正方形;

    2.判断四个数据点数据与阈值之间的关系,生成01代码;

    3.由上步生成的代码按照下图的关系求出等值线与四个数据点之间的拓扑关系;

              

    4.由拓扑关系用线性插值方法求出等值线与正方形的交点;

    5.顺序连接等值线段,即得到等值线。

    二.源代码如下:

    头文件atest.h:

    #ifndef ATEST_H
    #define ATEST_H
     
    #include <QtGui/QtGui>
    #include "ui_atest.h"
    #include <iostream>
    #include <stdlib.h>
    #include <fstream>
    #include <string>
    #include <sstream>
    #include <vector>
     
    class ATest : public QMainWindow,public Ui_ATestClass
    {
        Q_OBJECT
     
    public:
        ATest(QWidget *parent = 0, Qt::WFlags flags = 0);
        ~ATest();
     
    private:
        QString filename;
        std::vector<float> result;//存放所有矩形插值得到的位置数据
        bool drawtf;
        void hookupsignals();
        void paintEvent(QPaintEvent *);
    private slots:
        void filesearch();
        void getParam();
    };
     
    #endif // ATEST_H

    实现文件atest.cpp:

    #include "atest.h"
    using namespace std;
     
    ATest::ATest(QWidget *parent, Qt::WFlags flags)
        : QMainWindow(parent, flags)
    {
        setupUi(this);
        hookupsignals();
        drawtf=false;
    }
     
    ATest::~ATest()
    {
     
    }
     
    //*************************************
    // 时    间:  2015/7/17 10:44
    // 权    限:  public
    // 返    回:  std::vector<std::string>
    // 方法说明:  将string转化成字符串数组
    //*************************************
    std::vector<std::string> split(std::string str,std::string pattern)
    { 
        std::string::size_type pos;  
        std::vector<std::string> result; 
        str+=pattern;//扩展字符串以方便操作  
        int size=str.size();    
        for(int i=0; i<size; i++)  
        {    
            pos=str.find(pattern,i);    
            if(pos<size)    
            {     
                std::string s=str.substr(i,pos-i);      
                result.push_back(s);     
                i=pos+pattern.size()-1;    
            }  
        }  
        return result;
    }
     
    //*************************************
    // 时    间:  2015/7/18 21:22 
    // 权    限:  public
    // 返    回:  float
    // 方法说明:  返回最终的插值结果
    //*************************************
    float execute(float yuzhi,float vmin,float vmax,float locmin,float locmax)
    {
        float result=(locmax-locmin)*(yuzhi-vmin)/(vmax-vmin);
        return result;
    }
     
    //*************************************
    // 时    间:  2015/7/17 15:00
    // 权    限:  public
    // 返    回:  vector<float>
    // 方法说明:  插值函数,返回插值得到的点的坐标
    //*************************************
    vector<float> interpolate(vector<int> flag,vector<float> data,vector<float> locate)
    {
        vector<float> result;
        float t;
        if(flag[0]==0)
        {
            if(flag[1]==0)
            {
                if(flag[2]==0)
                {
                    if(flag[3]==0)//0000
                    {              
                    }  
                    else//0001
                    {
                        t=execute(data[4],data[2],data[3],locate[4],locate[6]);
                        result.push_back(locate[5]);
                        result.push_back(locate[4]+t);
                        t=execute(data[4],data[3],data[0],locate[7],locate[1]);
                        result.push_back(locate[7]+t);
                        result.push_back(locate[6]);   
                    }
                }
                else
                {
                    if(flag[3]==0)//0010
                    {
                        t=execute(data[4],data[1],data[2],locate[3],locate[5]);
                        result.push_back(locate[3]+t);
                        result.push_back(locate[2]);
                         
                        t=execute(data[4],data[2],data[3],locate[4],locate[6]);                            
                        result.push_back(locate[5]);
                        result.push_back(locate[4]+t);
                         
                    }  
                    else//0011
                    {
                        t=execute(data[4],data[1],data[2],locate[3],locate[5]);
                        result.push_back(locate[3]+t);
                        result.push_back(locate[2]);
                         
                        t=execute(data[4],data[3],data[0],locate[7],locate[1]);                                
                        result.push_back(locate[7]+t);
                        result.push_back(locate[6]);
                         
                    }
                }
            }
            else
            {
                if(flag[2]==0)
                {
                    if(flag[3]==0)//0100
                    {
                        t=execute(data[4],data[0],data[1],locate[0],locate[2]);
                        result.push_back(locate[1]);
                        result.push_back(locate[0]+t);
                         
                        t=execute(data[4],data[1],data[2],locate[3],locate[5]);                                
                        result.push_back(locate[3]+t);
                        result.push_back(locate[2]);
                         
                    }  
                    else//0101
                    {
                        t=execute(data[4],data[0],data[1],locate[0],locate[2]);
                        result.push_back(locate[1]);
                        result.push_back(locate[0]+t);
                         
                        t=execute(data[4],data[3],data[0],locate[7],locate[1]);                                
                        result.push_back(locate[7]+t);
                        result.push_back(locate[6]);
                         
                        t=execute(data[4],data[1],data[2],locate[3],locate[5]);
                        result.push_back(locate[3]+t);
                        result.push_back(locate[2]);
                         
                        t=execute(data[4],data[2],data[3],locate[4],locate[6]);                                
                        result.push_back(locate[5]);
                        result.push_back(locate[4]+t);
                         
                    }
                }
                else
                {
                    if(flag[3]==0)//0110
                    {
                        t=execute(data[4],data[0],data[1],locate[0],locate[2]);
                        result.push_back(locate[1]);
                        result.push_back(locate[0]+t);
                         
                        t=execute(data[4],data[2],data[3],locate[4],locate[6]);                            
                        result.push_back(locate[5]);
                        result.push_back(locate[4]+t);
                         
                    }  
                    else//0111
                    {
                        t=execute(data[4],data[0],data[1],locate[0],locate[2]);
                        result.push_back(locate[1]);
                        result.push_back(locate[0]+t);
                         
                        t=execute(data[4],data[3],data[0],locate[7],locate[1]);                                
                        result.push_back(locate[7]+t);
                        result.push_back(locate[6]);
                         
                    }
                }
            }
        }
        else
        {
            if(flag[1]==0)
            {
                if(flag[2]==0)
                {
                    if(flag[3]==0)//1000
                    {
                        t=execute(data[4],data[0],data[1],locate[0],locate[2]);
                        result.push_back(locate[1]);
                        result.push_back(locate[0]+t);
                         
                        t=execute(data[4],data[3],data[0],locate[7],locate[1]);                                
                        result.push_back(locate[7]+t);
                        result.push_back(locate[6]);
                         
                    }  
                    else//1001
                    {
                        t=execute(data[4],data[0],data[1],locate[0],locate[2]);
                        result.push_back(locate[1]);
                        result.push_back(locate[0]+t);
                         
                        t=execute(data[4],data[2],data[3],locate[4],locate[6]);                            
                        result.push_back(locate[5]);
                        result.push_back(locate[4]+t);
                         
                    }
                }
                else
                {
                    if(flag[3]==0)//1010
                    {
                        t=execute(data[4],data[0],data[1],locate[0],locate[2]);
                        result.push_back(locate[1]);
                        result.push_back(locate[0]+t);
                         
                        t=execute(data[4],data[1],data[2],locate[3],locate[5]);                                
                        result.push_back(locate[3]+t);
                        result.push_back(locate[2]);
                         
                        t=execute(data[4],data[2],data[3],locate[4],locate[6]);
                        result.push_back(locate[5]);
                        result.push_back(locate[4]+t);
                         
                        t=execute(data[4],data[3],data[0],locate[7],locate[1]);
                        result.push_back(locate[7]+t);
                        result.push_back(locate[6]);
                         
                    }  
                    else//1011
                    {
                        t=execute(data[4],data[0],data[1],locate[0],locate[2]);
                        result.push_back(locate[1]);
                        result.push_back(locate[0]+t);
                         
                        t=execute(data[4],data[1],data[2],locate[3],locate[5]);                                
                        result.push_back(locate[3]+t);
                        result.push_back(locate[2]);
                         
                    }
                }
            }
            else
            {
                if(flag[2]==0)
                {
                    if(flag[3]==0)//1100
                    {
                        t=execute(data[4],data[1],data[2],locate[3],locate[5]);
                        result.push_back(locate[3]+t);
                        result.push_back(locate[2]);
                         
                        t=execute(data[4],data[3],data[0],locate[7],locate[1]);                                
                        result.push_back(locate[7]+t);
                        result.push_back(locate[6]);
                         
                    }  
                    else//1101
                    {
                        t=execute(data[4],data[1],data[2],locate[3],locate[5]);
                        result.push_back(locate[3]+t);
                        result.push_back(locate[2]);
                         
                        t=execute(data[4],data[2],data[3],locate[4],locate[6]);                            
                        result.push_back(locate[5]);
                        result.push_back(locate[4]+t);
                         
                    }
                }
                else
                {
                    if(flag[3]==0)//1110
                    {
                        t=execute(data[4],data[2],data[3],locate[4],locate[6]);
                        result.push_back(locate[5]);
                        result.push_back(locate[4]+t);
                         
                        t=execute(data[4],data[3],data[0],locate[7],locate[1]);
                        result.push_back(locate[7]+t);
                        result.push_back(locate[6]);
                         
                    }  
                    else//1111
                    {  
                    }
                }
            }
        }
     
        return result;
    }
     
    //*************************************
    // 时    间:  2015/7/17 10:44
    // 权    限:  private
    // 返    回:  void
    // 方法说明:  连接信号槽函数
    //*************************************
    void ATest::hookupsignals()
    {
        connect(btnfilesearch,SIGNAL(clicked()),this,SLOT(filesearch()));
        connect(btnContour,SIGNAL(clicked()),this,SLOT(getParam()));
    }
     
    //*************************************
    // 时    间:  2015/7/17 10:44
    // 权    限:  private
    // 返    回:  void
    // 方法说明:  文件查找
    //*************************************
    void ATest::filesearch()
    {
        QString dir=QFileDialog::getOpenFileName(this,
            tr("文件路径"),
            QDir::currentPath(),
            "File (*.txt)");
        if (!dir.isEmpty())
        {
            filename=dir;
            //QMessageBox::about(this,tr("通知"),tr("文件读取成功!"));
        }
        else
        {
            QMessageBox::about(this,tr("警告"),tr("文件读取失败!"));
        }
        fileedit->setText(filename);
    }
     
    //*************************************
    // 时    间:  2015/7/16 20:24
    // 权    限:  private
    // 返    回:  void
    // 方法说明:  获取参数,读取文件,数据与阈值比较,1*36*104*104
    //*************************************
    void ATest::getParam()
    {
        float yuzhi=valueedit->text().toFloat();     //读取用户指定的阈值
        ifstream infiles(filename.toStdString());       //打开将要读的文件
        ofstream outfile("E:/Project/Data/re01.txt");   //打开将要写的文件
        string datastr;                                 //每一行数据读取到datastr中
        vector<float> data;                               //存放所有数据
        vector<int> data01;                               //存放所有数据的转换后的01代码
        float pervalue;                                 //每一个数据值,用来与阈值比较
        int rowindex;                                   //控制当前读取的行数
     
         
        int n=0;                                        //读取指定行数数据
        rowindex=1;                                     //控制读取高度
        while(getline(infiles,datastr))
        {
            if (n>104*(rowindex-1)+1)                    //第一行和第二行不读取
            {          
                vector<string> result=split(datastr,"	");
                for (vector<string>::const_iterator it=result.begin()+3;it!=result.end();it++)
                {  
                    pervalue=atof((*it).c_str());       //每一行中的每一个数据
                    if (pervalue<yuzhi)                  //数据与阈值比较
                    {
                        data01.push_back(0);            //小,则为0
                    }
                    else
                    {
                        data01.push_back(1);            //大,则为1
                    }
                    data.push_back(pervalue);           //将每个数据存储起来
                }
            }  
            if (n>104*rowindex)                          //超过104行结束存储,因为105行意味着高度层为2
            {
                break;
            }
            n++;
        }  
        infiles.close();
     
        //将01代码数据存储起来
        //产生列序号
        for (int i=1;i<105;i++)
        {
            if (i<10)
            {
                outfile<<i<<"  ";
            }
            else if(i<100)
            {
                outfile<<i<<" ";
            }  
            else
            {
                outfile<<i;
            }
        }
        outfile<<endl;
     
        for (int i=0;i<104;i++)
        {
            for (int j=0;j<104;j++)
            {
                n=i*104+j;
                outfile<<data01[n]<<"  ";
            }
            outfile<<endl;
        } 
        outfile.close();
     
        //对数据进行处理,每四个数据处理一次,即一个矩形,数据和01代码以及位置都是按照矩形逆时针方向读取
        vector<int> flag(4);//每个矩形对应的四个顶点的01代码
        vector<float> datav(5);//0到3存储的是四个顶点对应的数据,4存放的是阈值
        vector<float> locate(8);//四个顶点对应的坐标值(x,y)
        vector<float> temp;//存放每个矩形插值得到的位置数据
         
        int index;
        for (int i=0;i<103;i++)//最后一行不需要处理
        {
            for (int j=0;j<103;j++)//最后一列不需要处理
            {
                index=i*104+j;
     
                flag[0]=data01[index];
                flag[1]=data01[index+104];
                flag[2]=data01[index+105];
                flag[3]=data01[index+1];
     
                datav[0]=data[index];
                datav[1]=data[index+104];
                datav[2]=data[index+105];
                datav[3]=data[index+1];
                datav[4]=yuzhi;             //存放阈值
     
                locate[0]=i;
                locate[1]=j;
                locate[2]=i+1;
                locate[3]=j;
                locate[4]=i+1;
                locate[5]=j+1;
                locate[6]=i;
                locate[7]=j+1;
     
                temp=interpolate(flag,datav,locate);
                for (int k=0;k<temp.size();k++)
                {
                    result.push_back(temp[k]);
                }
            }
        }
        drawtf=true;    //位置数据全部获取到,接下来绘制点位置,即连接点即可
     }
    void ATest::paintEvent(QPaintEvent *)
    {
        QPainter painter(this); //this为绘图设备,即表明在该部件上进行绘制
        painter.setPen(QColor(0,0,0,20));
        for (int i=0;i<104;i++)//最后一行不需要处理
        {
            for (int j=0;j<104;j++)//最后一列不需要处理
            {
                painter.drawLine(QPoint(i*7+250,j*7.5+25),QPoint(i*7+250,(j+1)*7.5+25));
                painter.drawLine(QPoint(i*7+250,j*7.5+25),QPoint((i+1)*7+250,j*7.5+25));
            }
        }
        painter.setPen(QColor(255,0,0));
        if (drawtf==true)
        {
            for (int i=0;i<result.size()-4;i+=4)//每隔4个数据,即每隔2个点,每个点对应xy值
            {
                painter.drawLine(result[i]*7+250, result[i+1]*7.5+25, result[i+2]*7+250, result[i+3]*7.5+25);
            }
        }
    }

    四.结果

    1.部分01代码图:

          

    2.部分等值线图:

         

  • 相关阅读:
    Linux常用命令
    PHP中的 extends与implements 区别
    IDEA链接MongoDB数据库-实现增删改查
    在IDEA中用三个jar包链接MongoDB数据库——实现增删改查
    MongoDB修改账号密码
    进入 MongoDB
    MongoDB安装
    解决{"error_code":110,"error_msg":"Access token invalid or no longer valid"}
    毕设进度(10.29)
    毕设进度(10.28)
  • 原文地址:https://www.cnblogs.com/Vae1990Silence/p/6561857.html
Copyright © 2011-2022 走看看