前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >等值线算法「建议收藏」

等值线算法「建议收藏」

作者头像
全栈程序员站长
发布2022-09-20 10:34:01
7780
发布2022-09-20 10:34:01
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。 Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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

一.算法如下:

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

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

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

等值线算法「建议收藏」
等值线算法「建议收藏」

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

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

二.源代码如下:

头文件atest.h:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
/*
* 提示:该行代码过长,系统自动注释不进行高亮。一键复制会移除系统注释 
* #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,"\t"); 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.部分等值线图:

等值线算法「建议收藏」
等值线算法「建议收藏」

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/167656.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档