-
Notifications
You must be signed in to change notification settings - Fork 0
/
qtsurfaceplotterribidialog.cpp
129 lines (106 loc) · 4.01 KB
/
qtsurfaceplotterribidialog.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "qtsurfaceplotterribidialog.h"
#include <cassert>
#include <boost/lexical_cast.hpp>
#include <QDesktopWidget>
#include <QKeyEvent>
#include "fparser.hh"
#include "ui_qtsurfaceplotterribidialog.h"
ribi::QtSurfacePlotterRibiDialog::QtSurfacePlotterRibiDialog(QWidget *parent)
: QDialog(parent),
ui(new Ui::QtSurfacePlotterRibiDialog)
{
ui->setupUi(this);
QObject::connect(this->ui->edit_equation,SIGNAL(textChanged(QString)),this,SLOT(OnAnyChange()));
QObject::connect(this->ui->edit_minx,SIGNAL(textChanged(QString)),this,SLOT(OnAnyChange()));
QObject::connect(this->ui->edit_miny,SIGNAL(textChanged(QString)),this,SLOT(OnAnyChange()));
QObject::connect(this->ui->edit_maxx,SIGNAL(textChanged(QString)),this,SLOT(OnAnyChange()));
QObject::connect(this->ui->edit_maxy,SIGNAL(textChanged(QString)),this,SLOT(OnAnyChange()));
ui->edit_minx->setText(boost::lexical_cast<std::string>(-1.0).c_str());
ui->edit_miny->setText(boost::lexical_cast<std::string>(-1.0).c_str());
ui->edit_maxx->setText(boost::lexical_cast<std::string>( 1.0).c_str());
ui->edit_maxy->setText(boost::lexical_cast<std::string>( 1.0).c_str());
ui->edit_equation->setText("cos(x*y*100)");
{
//Put the dialog in the screen center at 50% x 50% of its size
const QRect screen = QApplication::desktop()->screenGeometry();
this->setGeometry(0,0,screen.width() / 2,screen.height() / 2);
this->move( screen.center() - this->rect().center() );
}
}
ribi::QtSurfacePlotterRibiDialog::~QtSurfacePlotterRibiDialog() noexcept
{
delete ui;
}
void ribi::QtSurfacePlotterRibiDialog::keyPressEvent(QKeyEvent *event)
{
switch (event->key())
{
case Qt::Key_Escape: close(); return;
}
}
void ribi::QtSurfacePlotterRibiDialog::OnAnyChange()
{
try { boost::lexical_cast<double>(ui->edit_minx->text().toStdString()); }
catch (boost::bad_lexical_cast&)
{
this->setWindowTitle("Value of x_min is not a valid double"); return;
}
try { boost::lexical_cast<double>(ui->edit_miny->text().toStdString()); }
catch (boost::bad_lexical_cast&)
{
this->setWindowTitle("Value of y_min is not a valid double"); return;
}
try { boost::lexical_cast<double>(ui->edit_maxx->text().toStdString()); }
catch (boost::bad_lexical_cast&)
{
this->setWindowTitle("Value of x_max is not a valid double"); return;
}
try { boost::lexical_cast<double>(ui->edit_maxy->text().toStdString()); }
catch (boost::bad_lexical_cast&)
{
this->setWindowTitle("Value of y_max is not a valid double"); return;
}
FunctionParser f;
//Parse the formula
f.Parse(ui->edit_equation->text().toStdString().c_str(),"x,y");
if (f.GetParseErrorType()!= FunctionParser::FP_NO_ERROR)
{
this->setWindowTitle("Function cannot not be parsed"); return;
}
const double x_min = boost::lexical_cast<double>(ui->edit_minx->text().toStdString());
const double y_min = boost::lexical_cast<double>(ui->edit_miny->text().toStdString());
const double x_max = boost::lexical_cast<double>(ui->edit_maxx->text().toStdString());
const double y_max = boost::lexical_cast<double>(ui->edit_maxy->text().toStdString());
if (x_min >= x_max)
{
this->setWindowTitle("Value of x_min must be smaller than x_max"); return;
}
if (y_min >= y_max)
{
this->setWindowTitle("Value of y_min must be smaller than y_max"); return;
}
struct MyFunction : public QtSurfacePlotWidget::Function
{
MyFunction(const FunctionParser& f) : m_f(f) {}
double operator()(const double x, const double y) const noexcept
{
const double xs[2] = { x,y };
//FunctionParser::Eval is not const, although it does not change
//the state of the FunctionParser itself
const double z{const_cast<FunctionParser&>(m_f).Eval(xs)};
return m_f.EvalError() ? 0.0 : z;
}
private:
const FunctionParser m_f;
};
ui->surfaceplotwidget->Plot(
MyFunction(f),
x_min, x_max,
y_min, y_max
);
this->setWindowTitle("Function plotted successfully");
}
void ribi::QtSurfacePlotterRibiDialog::resizeEvent(QResizeEvent *)
{
OnAnyChange();
}