软件约束
软件界面
“缓和曲线放样资料计算与精度评定软件”主要有两个子界面,图6.1所示界面用于计算缓和曲线放样资料,图6.2所示界面用于测设数据精度评定。
软件操作
缓和曲线放样资料计算
- 在窗口中输入各个常数的值;
- 点击“导出数据”,选择导出的文件,当弹出如图6.4(右)的数据导出成功的提示后,代表数据导出成功;
- 我们打开导出的文件,内容如图6.5所示,每一行数据从左到右代表:放样点,置镜点,后视点,距离值,角度值,正反拨。
测设数据精度评定
- 首先点击“导入数据”,选择待精度评定的数据文件;
- 点击“计算显示”,界面中会分别用图和表格的形式表示各个点的精度情况。
附录:源代码
LayOffCaculate.h
#ifndef LAYOFFCACULATE_H
#define LAYOFFCACULATE_H
#include<iostream>
#include<vector>
#define PI 3.141592653589793238
using namespace std;
struct Point {
string name;
string zhiJing;
string houShi;
double juLi;
double rad;
int ZhengFan;
double liCheng;
};
double dgree2rad(int dd, int mm, double ss);
void rad2degree(int &dd, int &mm, double &ss, double rad);
double biaozhunLicheng2Caculate(size_t bignum, double smallnum);
void caculateLicheng2Biaozhun(size_t &bignum, double &smallnum, double cacunum);
double fangxiangAngle(double dx, double dy);
class ZhuDian {
public:
ZhuDian(double r_, double l0_, double alpha_, double zh_lc_, double t_, double l_, double e_)
:r(r_), l0(l0_), alpha(alpha_), zh_lc(zh_lc_),t(t_), l(l_), e(e_) {}
Point caculateZH();
Point caculateQZ();
Point caculateHY();
private:
double r, l0, alpha, zh_lc, t, l, e;
};
class HuanHe {
public:
HuanHe(Point ZH_, Point HY_, double r_, double l0_) //拷贝类型
:ZH(ZH_),HY(HY_),r(r_),l0(l0_){}
vector<Point> caculateHH();
protected:
int point_count();
private:
Point ZH, HY;
double r;
double l0;
};
class YuanQX {
public:
YuanQX(double r_, double l0_, Point HY_,Point QZ_, Point ZH_)
:r(r_),l0(l0_),HY(HY_),QZ(QZ_),ZH(ZH_){};
vector<Point> caculateYQX();
protected:
double caculateM();
double caculateP();
double caculateBelta0();
private:
double r, l0;
Point HY, QZ, ZH;
};
#endif LAYOFFCACULATE_H
LayOffCaculate.cpp
#include "LayOffCaculate.h"
#include <string>
double dgree2rad(int dd, int mm, double ss) {
dd = dd + mm / 60 + ss / 3600;
return dd * PI / 180;
}
void rad2degree(int &dd, int &mm, double &ss, double rad) {
double temp;
temp = rad * 180 / PI;
dd = int(temp);
mm = int((temp - dd) * 60);
ss = ((temp - dd) * 60 - mm) * 60;
}
double biaozhunLicheng2Caculate(size_t bignum, double smallnum) {
return bignum * 1000 + smallnum;
}
void caculateLicheng2Biaozhun(size_t &bignum, double &smallnum, double cacunum) {
bignum = int(cacunum / 1000);
smallnum = cacunum - bignum * 1000;
}
double fangxiangAngle(double dx, double dy) {//未检测
double angle;
//if (dx == 0) {
// if(dy>=0)
// return angle = 0.0;
//}
//if (dy == 0) { angle = PI / 2; }
if (dy != 0 && dx != 0) {
angle = abs(atan(dy / dx));
if (dx > 0 && dy > 0) {
angle = angle;
}
if (dx < 0 && dy>0) {
angle = PI - angle;
}
if (dx < 0 && dy < 0) {
angle = PI + angle;
}
if (dx > 0 && dy < 0) {
angle = 2 * PI - angle;
}
}
return angle;
}
Point ZhuDian::caculateZH()
{
Point ZH;
ZH.name = "ZH";
ZH.zhiJing = "JD";
ZH.houShi = "ZD";
ZH.juLi = t;
ZH.rad = 0.0;
ZH.ZhengFan = 0;
ZH.liCheng = zh_lc;
return ZH;
}
Point ZhuDian::caculateQZ()
{
Point QZ;
QZ.name = "QZ";
QZ.zhiJing = "JD";
QZ.houShi = "ZD";
QZ.juLi = e;
QZ.rad = (PI - alpha) / 2;
QZ.ZhengFan = 1;
QZ.liCheng = zh_lc + l / 2;
return QZ;
}
Point ZhuDian::caculateHY()
{
Point HY;
HY.name = "HY";
HY.zhiJing = "ZH";
HY.houShi = "JD";
double x = l0 - pow(l0,3) / 40 / pow(r,2);
double y = pow(l0, 2) / 6 / r;
HY.rad = atan(y / x);
HY.juLi = sqrt(pow(x, 2) + pow(y, 2));
HY.ZhengFan = 0;
HY.liCheng = zh_lc + l0;
return HY;
}
vector<Point> HuanHe::caculateHH()
{
int count = point_count();
count--;
vector<Point> hh_point_list;
Point hh_point;
double li, licheng,smallnum;
size_t bignum;
double x, y;
for (int i = 1; i <= count; i++) {
li = 10 * i;
x = li - pow(li, 5) / 40 / pow(r, 2)/pow(l0,2);
y = pow(li, 3) / 6 / r/l0;
cout << "x=" << x << " y=" << y << endl;
licheng = ZH.liCheng + li;
caculateLicheng2Biaozhun(bignum, smallnum, licheng);
hh_point.name = "DK" + to_string(bignum) + "+" + to_string(smallnum);
hh_point.zhiJing = "ZH";
hh_point.houShi = "JD";
hh_point.juLi = sqrt(pow(x, 2) + pow(y, 2));
hh_point.liCheng = licheng;
hh_point.rad = atan(y / x);
cout << hh_point.rad << endl;
hh_point.ZhengFan = 0;
hh_point_list.push_back(hh_point);
}
return hh_point_list;
}
int HuanHe::point_count()
{
double zh_hy = HY.liCheng- ZH.liCheng;
int count = int(zh_hy / 10);
return count;
}
vector<Point> YuanQX::caculateYQX()
{
int hy_temp = HY.liCheng / 20;
hy_temp = hy_temp * 20;
int count = int((QZ.liCheng - hy_temp) / 20);
vector<Point> yqx_point_list;
Point yqx_point;
double li, alphai, x, y,smallnum;
size_t bignum;
for (int i = 1; i <= count; i++) {
li = hy_temp-ZH.liCheng + 20 * i;
alphai = (li - l0) / r + caculateBelta0();
x = r * sin(alphai) + caculateM();
y = r * (1 - cos(alphai)) + caculateP();
caculateLicheng2Biaozhun(bignum, smallnum, li+ZH.liCheng);
yqx_point.name = "DK" + to_string(bignum) + "+" + to_string(smallnum);
yqx_point.zhiJing = "ZH";
yqx_point.houShi = "JD";
yqx_point.juLi = sqrt(pow(x, 2) + pow(y, 2));
yqx_point.liCheng = li+ZH.liCheng;
yqx_point.rad = atan(y / x);
yqx_point.ZhengFan = 0;
yqx_point_list.push_back(yqx_point);
}
return yqx_point_list;
}
double YuanQX::caculateM()
{
return l0 / 2 - pow(l0, 3) / 240 / pow(r, 2);
}
double YuanQX::caculateP()
{
return pow(l0, 2) / 24 / r;
}
double YuanQX::caculateBelta0()
{
return l0 / 2 / r;
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include<QMainWindow>
//#include<MyMathLib/LayOffCaculate.h>
#include "LayOffCaculate.h"
#include<vector>
#include <iostream>
QT_BEGIN_HEADER
namespace Ui { class MainWindow; }
QT_END_HEADER
class MainWindow :public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void caculateClick();
void accuracyClick();
private:
Ui::MainWindow *ui;
double r, l0, rad, zh_lc, t, l, e;
Si::Point zh, qz, hy;
vector<Si::Point> hh_point_list, yqx_point_list;
std::string qstr2str(const QString qstr)
{
QByteArray cdata = qstr.toLocal8Bit();
return std::string(cdata);
}
QString str2qstr(const std::string str)
{
return QString::fromLocal8Bit(str.data());
}
};
#endif MAINWINDOW_H
MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <qfiledialog.h>
#include <QMessageBox>
#include <fstream>
#include <sstream>
#include <iostream>
#include "AccuracyWindow.h"
#include <qdebug.h>
#include<qstandarditemmodel.h>
#include<string>
MainWindow::MainWindow(QWidget *parent)
:QMainWindow(parent) //继承
,ui(new Ui::MainWindow) //在ui中,mainwindow继承了ui_mainwindow
{
ui->setupUi(this);
//r = 200;
//l0 = 30;
//rad = Si::dgree2rad(20, 00, 00);
//zh_lc = Si::biaozhunLicheng2Caculate(100, 335.79);
//t = 50.296;
//l = 99.813;
//e = 3.276;
//
connect(ui->btn_out, SIGNAL(clicked()), this, SLOT(caculateClick()));
connect(ui->btn_accuracy, SIGNAL(clicked()), this, SLOT(accuracyClick()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::accuracyClick()
{
AccuracyWindow *accuracyWindow = new AccuracyWindow();
accuracyWindow->show();
}
using namespace Si;
void MainWindow::caculateClick()
{
r = atof(ui->input_r->text().toStdString().c_str());
l0= atof(ui->input_l0->text().toStdString().c_str());
int dd, mm;
double ss, smallnum;
size_t bignum;
dd= atoi(ui->input_a0->text().toStdString().c_str());
mm= atoi(ui->input_a1->text().toStdString().c_str());
ss= atof(ui->input_a2->text().toStdString().c_str());
rad = dgree2rad(dd, mm, ss);
bignum= atoi(ui->input_zh0->text().toStdString().c_str());
smallnum= atof(ui->input_zh1->text().toStdString().c_str());
zh_lc = biaozhunLicheng2Caculate(bignum, smallnum);
t= atof(ui->input_t->text().toStdString().c_str());
l= atof(ui->input_l->text().toStdString().c_str());
e= atof(ui->input_e->text().toStdString().c_str());
ZhuDian zd(r, l0, rad, zh_lc, t, l, e);
hy = zd.caculateHY();
zh = zd.caculateZH();
qz = zd.caculateQZ();
HuanHe hh(zh, hy, r, l0);
hh_point_list = hh.caculateHH();
YuanQX yqx(r, l0, hy, qz, zh);
yqx_point_list = yqx.caculateYQX();
//打开文件
QString filename;
filename = QFileDialog::getOpenFileName(this, QString::fromLocal8Bit("选择导出文件"), "", tr("(*.csv)"));
std::ofstream ofs;
string str_filename = qstr2str(filename);
ofs.open(str_filename, std::ios::trunc);//打开清空内容
//先写入主点测设资料
//ofs << "主点测设" << std::endl;
//string temp = "放样点,置镜点,后视点,距离,角度,正反拨";
//ofs << temp << std::endl;
rad2degree(dd, mm, ss, zh.rad);
ofs << zh.name << "," << zh.zhiJing << "," << zh.houShi << "," << zh.juLi << "," << dd << " " << mm << " " << ss << "," << zh.ZhengFan << std::endl;
rad2degree(dd, mm, ss, qz.rad);
ofs << qz.name << "," << qz.zhiJing << "," << qz.houShi << "," << qz.juLi << "," << dd << " " << mm << " " << ss << "," << qz.ZhengFan << std::endl;
rad2degree(dd, mm, ss, hy.rad);
ofs << hy.name << "," << hy.zhiJing << "," << hy.houShi << "," << hy.juLi << "," << dd << " " << mm << " " << ss << "," << hy.ZhengFan << std::endl;
ofs << std::endl;
//ofs << "详细测设-缓和曲线" << std::endl;
//ofs << temp << std::endl;
for (int i = 0; i < hh_point_list.size(); i++) {
rad2degree(dd, mm, ss, hh_point_list[i].rad);
ofs << hh_point_list[i].name << "," << hh_point_list[i].zhiJing << "," << hh_point_list[i].houShi
<< "," << hh_point_list[i].juLi << "," << dd << " " << mm << " " << ss << ","
<< hh_point_list[i].ZhengFan << std::endl;
}
ofs << std::endl;
//ofs <<"详细测设-圆曲线"<< std::endl;
//ofs << temp << std::endl;
for (int i = 0; i < yqx_point_list.size(); i++) {
rad2degree(dd, mm, ss, yqx_point_list[i].rad);
ofs << yqx_point_list[i].name << "," << yqx_point_list[i].zhiJing << "," << yqx_point_list[i].houShi
<< "," << yqx_point_list[i].juLi << "," << dd << " " << mm << " " << ss << ","
<< yqx_point_list[i].ZhengFan << std::endl;
}
ofs.close();
QMessageBox::information(NULL, "information", "Output Successfull!!");
}
AccuracyWindow.h
#ifndef ACCURACYWINDOW_H
#define ACCURACYWINDOW_H
#include<QtCharts>
#include<QMainWindow>
#include <vector>
#include<string>
using namespace std;
QT_BEGIN_HEADER
namespace Ui { class AccuracyWindow; }
QT_END_HEADER
class AccuracyWindow :public QMainWindow
{
Q_OBJECT
public:
AccuracyWindow(QWidget *parent = nullptr);
vector<double> accuracyCaculate();
~AccuracyWindow();
public slots:
void InputFileData();
void CaculateShow();
private:
Ui::AccuracyWindow *ui;
vector<double> alpha0_list;
vector<double> alpha1_list, juli0_list, juli1_list;
std::string qstr2str(const QString qstr)
{
QByteArray cdata = qstr.toLocal8Bit();
return std::string(cdata);
}
QString str2qstr(const std::string str)
{
return QString::fromLocal8Bit(str.data());
}
};
#endif ACCURACYWINDOW_H
AccuracyWindow.cpp
//#include "MainWindow.h"
#include "AccuracyWindow.h"
#include <fstream>
#include <sstream>
#include "ui_AccuracyWindow.h"
#include "LayOffCaculate.h"
#include <qfiledialog.h>
#include<QChartView>
//using namespace Si;
using namespace QtCharts;
AccuracyWindow::AccuracyWindow(QWidget *parent)
:QMainWindow(parent) //继承
,ui(new Ui::AccuracyWindow) //在ui中,mainwindow继承了ui_mainwindow
{
ui->setupUi(this);
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(InputFileData()));
connect(ui->btn_caculate, SIGNAL(clicked()), this, SLOT(CaculateShow()));
}
vector<double> AccuracyWindow::accuracyCaculate()
{
vector<double> mm_list;
double mm, jltemp, alphatemp;
for (size_t i = 0; i < juli0_list.size(); i++) {
jltemp = juli0_list[i] - juli1_list[i];
alphatemp = abs(alpha0_list[i] - alpha1_list[i]);
mm = sqrt(pow(jltemp, 2) + pow(alphatemp*juli0_list[i], 2));
mm_list.push_back(mm);
}
return mm_list;
}
AccuracyWindow::~AccuracyWindow()
{
delete ui;
}
#include<qdebug.h>
namespace Si {
//根据字符分割字符串
std::vector<std::string> string_split_by_character(const std::string &str, const char &character) {
std::vector<std::string> mod_vec_str; //返回值
if (str.empty()) {
mod_vec_str.push_back(str);
}
size_t position = 0;
std::string mod_str = str;
while ((position = mod_str.find(character, position)) != std::string::npos) {
mod_vec_str.push_back(mod_str.substr(0, position));
mod_str = mod_str.substr(position + 1, mod_str.size());
position = 0;
}
if (!mod_str.empty()) {
mod_vec_str.push_back(mod_str);
}
return mod_vec_str;
}
}
void AccuracyWindow::InputFileData()
{
juli0_list.clear();
juli1_list.clear();
alpha0_list.clear();
alpha1_list.clear();
QString filename;
filename = QFileDialog::getOpenFileName(this, QString::fromLocal8Bit("选择数据文件"), "", tr("(*.txt)"));
string str_filename = qstr2str(filename);
std::ifstream ifs;
ifs.open(str_filename);
std::string temp;
std::string alpha0, alpha1, jl0, jl1;
int dd, mm;
double ss;
std::vector<string> alpha_temp;
vector<string> temp_list;
while (std::getline(ifs, temp)) {
temp_list = Si::string_split_by_character(temp,',');
//原始方向距离:
//方向
alpha_temp = Si::string_split_by_character(temp_list[0], ' ');
jl0 = temp_list[1];
dd = atoi(alpha_temp[0].c_str());
mm= atoi(alpha_temp[1].c_str());
ss= atof(alpha_temp[2].c_str());
alpha0_list.push_back(Si::dgree2rad(dd, mm, ss));
juli0_list.push_back(atof(jl0.c_str()));
//实测方向距离:
alpha_temp = Si::string_split_by_character(temp_list[2], ' ');
jl0 = temp_list[3];
dd = atoi(alpha_temp[0].c_str());
mm = atoi(alpha_temp[1].c_str());
ss = atof(alpha_temp[2].c_str());
alpha1_list.push_back(Si::dgree2rad(dd, mm, ss));
juli1_list.push_back(atof(jl0.c_str()));
}
}
#include<qstandarditemmodel.h>
#include<qdebug.h>
#include<qbarseries.h>
void AccuracyWindow::CaculateShow()
{
vector<double> mm_list = accuracyCaculate();
//表格
QStandardItemModel* model = new QStandardItemModel();
//QStringList labels;
//labels << QStringLiteral("理论角度值") << QStringLiteral("理论距离值") << QStringLiteral("实际角度值") << QStringLiteral("实际距离值") << QStringLiteral("点位中误差");
//QStringList labels = QObject::trUtf8("理论角度值,理论距离值,实际角度值,实际距离值,点位中误差").simplified().split(",");//将string转为QStringList
QStringList labels = QObject::trUtf8("alpha0,l0,alpha1,l1,sigma").simplified().split(",");
model->setHorizontalHeaderLabels(labels);
QStandardItem *item = nullptr;
double ss;
int dd, mm;
string dms;
for (size_t i=0; i < juli0_list.size(); i++) {
Si::rad2degree(dd, mm, ss, alpha0_list[i]);
dms = std::to_string(dd) + " " + std::to_string(mm) + " " + std::to_string(ss);
item = new QStandardItem(QString::fromStdString(dms));
model->setItem(i, 0, item);
item = new QStandardItem(QString::fromStdString(std::to_string(juli0_list[i])));
model->setItem(i, 1, item);
Si::rad2degree(dd, mm, ss, alpha1_list[i]);
dms = std::to_string(dd) + " " + std::to_string(mm) + " " + std::to_string(ss);
item = new QStandardItem(QString::fromStdString(dms));
model->setItem(i, 2, item);
item = new QStandardItem(QString::fromStdString(std::to_string(juli1_list[i])));
model->setItem(i, 3, item);
item = new QStandardItem(QString::fromStdString(std::to_string(mm_list[i])));
model->setItem(i, 4, item);
}
ui->tableView->setModel(model);
//画图
QBarSeries *series = new QBarSeries;
QBarCategoryAxis *axis = new QBarCategoryAxis();
QBarSet *set = new QBarSet(QStringLiteral("sigma"));
for (double i = 0; i < juli0_list.size(); i++) {
set->append(mm_list[i]);
}
series->append(set);
QChart *chart = new QChart();
chart->addSeries(series);
chart->setTitle(QString::fromLocal8Bit("error of mean squares"));
chart->setAnimationOptions(QChart::SeriesAnimations); //动画
QStringList categories;
for (size_t i = 0; i < juli0_list.size(); i++) {
categories.push_back(QString::fromLocal8Bit(to_string(i).c_str()));
}
axis->append(categories);
chart->createDefaultAxes();
chart->setAxisX(axis, series);
chart->legend()->setVisible(true); //设置图例为显示状态
chart->legend()->setAlignment(Qt::AlignBottom);//设置图例的显示位置在底部
ui->mychart->setChart(chart);
ui->mychart->setRenderHint(QPainter::Antialiasing);
chart->createDefaultAxes();
chart->setTheme(QChart::ChartThemeDark);
}