Repository navigation
Expand file tree
/
Copy pathsimpleanimation.h
More file actions
116 lines (99 loc) · 3.85 KB
/
Copy pathsimpleanimation.h
File metadata and controls
116 lines (99 loc) · 3.85 KB
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
//Must include "QT += core charts widgets" in .pro file
#ifdef QT_CORE_LIB
#ifndef SIMPLEANIMATION_H
#define SIMPLEANIMATION_H
#include "eigenmatrixtypes.h"
#include <QtWidgets/QApplication>
#include <QtCharts/QChartView> //Qt's plotting library to visualize results
#include <QtCharts/QLineSeries>
#include <QMessageBox>
#include <thread>
#include <QTime>
namespace ContinuumRobotLibrary{
//There must be separate threads to update the animation
//and to assume responsibility for the plotting window.
//A thread is created to run this function.
static void workerAnimationFunc(MatrixXd x,
MatrixXd y,
double dt,
double t0,
QString title,
QtCharts::QLineSeries* p,
QtCharts::QChart* c){
QTime plot_time = QTime::currentTime();
double t = t0;
int cols = static_cast<int>(x.cols());
for(int i = 0; i < x.rows(); i++){
//Approximately do not exceed the time step
while(plot_time.msecsTo(QTime::currentTime()) < 1000*dt);
plot_time = QTime::currentTime();
t += dt;
//Plot the series at this time
QList<QPointF> points;
points.reserve(cols);
for(int j = 0; j < cols; j++)
points << QPointF(x(i,j),y(i,j));
p->replace(points);
c->setTitle("<b>" + title + "</b><br>t = " + QString::number(t) + 's');
}
}
/*! Shows an animated plot of the evolution of x and y series over time.
Each row of x and y represents the data series at an instant in time.
The thread of execution is paused while the window is open. */
inline void playAnimation(MatrixXd x,
MatrixXd y,
double dt = 1,
QString title = "",
QString x_title = "",
QString y_title = "",
double t0 = 0){
if(x.cols()!=y.cols() || x.rows()!=y.rows()){
QMessageBox msgBox;
msgBox.setWindowTitle("Animation Error");
msgBox.setText("x and y series must be the same size.");
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
return;
}
if(x.cols()==0 || x.rows()==0){
QMessageBox msgBox;
msgBox.setWindowTitle("Animation Error");
msgBox.setText("The animated series are empty.");
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
return;
}
int argc = 0;
char* argv[1];
char null = '\0';
argv[0] = &null;
QApplication a(argc, argv);
QtCharts::QChart* chart = new QtCharts::QChart();
chart->setTitle("<b>" + title + "</b><br>t = " + QString::number(t0) + 's');
QtCharts::QLineSeries* p = new QtCharts::QLineSeries(chart);
for (int i = 0; i < x.cols(); i++)
p->append(QPointF(x(0,i), y(0,i)));
chart->addSeries(p);
chart->createDefaultAxes();
chart->axes(Qt::Horizontal).back()->setTitleText(x_title);
chart->axes(Qt::Vertical).back()->setTitleText(y_title);
chart->legend()->hide();
double x_min = x.minCoeff();
double x_max = x.maxCoeff();
double y_min = y.minCoeff();
double y_max = y.maxCoeff();
double x_range = x_max - x_min;
double y_range = y_max - y_min;
chart->axes(Qt::Horizontal).back()->setRange(x_min - 0.05*x_range, x_max + 0.05*x_range);
chart->axes(Qt::Vertical).back()->setRange(y_min - 0.05*y_range, y_max + 0.05*y_range);
QtCharts::QChartView* chartView = new QtCharts::QChartView(chart);
chartView->resize(600,600);
chartView->show();
std::thread t(workerAnimationFunc, x, y, dt, t0, title, p, chart);
a.exec();
}
}
#endif // SIMPLEANIMATION_H
#endif // QT_CORE_LIB