2019-06-21 04:24:47 +08:00
|
|
|
/** \example functionplot.cpp
|
2019-01-20 23:15:10 +08:00
|
|
|
* Shows how to plot Mathematical Functions as Line Graphs with JKQTPlotter (as evaluated C/C++ functions)
|
2019-01-13 01:53:16 +08:00
|
|
|
*
|
2019-01-20 23:15:10 +08:00
|
|
|
* \ref JKQTPlotterFunctionPlots
|
2019-01-13 01:53:16 +08:00
|
|
|
*/
|
|
|
|
|
2022-08-27 04:32:48 +08:00
|
|
|
#include "jkqtpexampleapplication.h"
|
2018-12-24 03:27:24 +08:00
|
|
|
#include <QApplication>
|
2020-09-05 19:14:46 +08:00
|
|
|
#include <QCheckBox>
|
2018-12-24 03:27:24 +08:00
|
|
|
#include <QVector>
|
|
|
|
#include <QMap>
|
|
|
|
#include "jkqtplotter/jkqtplotter.h"
|
2019-06-20 22:06:31 +08:00
|
|
|
#include "jkqtplotter/graphs/jkqtpevaluatedfunction.h"
|
2018-12-24 03:27:24 +08:00
|
|
|
|
2018-12-24 19:29:33 +08:00
|
|
|
double sinc(double x) {
|
2018-12-24 03:27:24 +08:00
|
|
|
return 10.0*sin(x)/x;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct SincSqr {
|
|
|
|
public:
|
|
|
|
inline SincSqr(double amplitude): a(amplitude) {}
|
2018-12-24 19:29:33 +08:00
|
|
|
inline double operator()(double x) {
|
2018-12-24 03:27:24 +08:00
|
|
|
return a*sin(x)*sin(x)/x/x;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
double a;
|
|
|
|
};
|
|
|
|
|
2020-09-05 18:44:02 +08:00
|
|
|
template <class TFUNCGRAPH>
|
|
|
|
void drawExample(QApplication& app, const QString& name) {
|
2020-09-05 19:14:46 +08:00
|
|
|
// 1.1 create a window that contains a line-edit to edit a function
|
2019-01-20 23:15:10 +08:00
|
|
|
// and a JKQTPlotter to display the function, combine everything in a layout
|
2020-09-05 18:44:02 +08:00
|
|
|
QWidget* mainWin=new QWidget();
|
|
|
|
mainWin->setWindowTitle(name);
|
|
|
|
JKQTPlotter* plot=new JKQTPlotter(mainWin);
|
2018-12-24 03:27:24 +08:00
|
|
|
QVBoxLayout* layout=new QVBoxLayout;
|
2020-09-05 18:44:02 +08:00
|
|
|
mainWin->setLayout(layout);
|
2018-12-24 03:27:24 +08:00
|
|
|
layout->addWidget(plot);
|
2020-09-05 19:14:46 +08:00
|
|
|
// 1.2 add checkbox that allows to switch the display of sample points
|
|
|
|
QCheckBox* chkShowSamples=new QCheckBox(app.tr("display sample points"));
|
|
|
|
chkShowSamples->setChecked(false);
|
|
|
|
layout->addWidget(chkShowSamples);
|
2018-12-24 03:27:24 +08:00
|
|
|
|
2019-01-20 17:49:29 +08:00
|
|
|
// 2. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function
|
2018-12-24 03:27:24 +08:00
|
|
|
// the function is defined as C++ inline function
|
2020-09-05 18:44:02 +08:00
|
|
|
TFUNCGRAPH* func1=new TFUNCGRAPH(plot);
|
2019-04-22 19:27:50 +08:00
|
|
|
func1->setPlotFunctionFunctor([](double x) { return 0.2*x*x-0.015*x*x*x; });
|
2019-01-26 20:00:40 +08:00
|
|
|
func1->setTitle("C++-inline function $0.2x^2-0.015x^3$");
|
2020-09-05 19:14:46 +08:00
|
|
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
|
|
|
func1->setDisplaySamplePoints(en);
|
|
|
|
plot->redrawPlot();
|
|
|
|
});
|
2018-12-24 03:27:24 +08:00
|
|
|
plot->addGraph(func1);
|
|
|
|
|
2019-01-20 17:49:29 +08:00
|
|
|
// 3. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function
|
2018-12-24 03:27:24 +08:00
|
|
|
// the function is again defined as C++ inline function, but now uses internal
|
|
|
|
// parameters (handed over to the function as a pointer to QVector<double>
|
2020-09-05 18:44:02 +08:00
|
|
|
TFUNCGRAPH* func2=new TFUNCGRAPH(plot);
|
2020-09-05 19:47:46 +08:00
|
|
|
func2->setPlotFunctionFunctor([](double x, const QVector<double>& p) {
|
|
|
|
return p.at(0)*sin(2.0*JKQTPSTATISTICS_PI*x*p.at(1));
|
2018-12-24 03:27:24 +08:00
|
|
|
});
|
|
|
|
// here we set the parameters p0, p1
|
2019-01-26 20:00:40 +08:00
|
|
|
func2->setParamsV(5, 0.2);
|
|
|
|
func2->setTitle("C++-inline function with int. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
2020-09-05 19:14:46 +08:00
|
|
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
|
|
|
func2->setDisplaySamplePoints(en);
|
|
|
|
plot->redrawPlot();
|
|
|
|
});
|
2018-12-24 03:27:24 +08:00
|
|
|
plot->addGraph(func2);
|
|
|
|
|
2020-09-05 19:47:46 +08:00
|
|
|
// 4. of course the function may also be any C+ funtor object:
|
2020-09-05 18:44:02 +08:00
|
|
|
TFUNCGRAPH* func4=new TFUNCGRAPH(plot);
|
2019-04-22 19:27:50 +08:00
|
|
|
func4->setPlotFunctionFunctor(SincSqr(-8));
|
2019-01-26 20:00:40 +08:00
|
|
|
func4->setTitle("C++ functor $-8*\\sin^2(x)/x^2$");
|
2020-09-05 19:14:46 +08:00
|
|
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
|
|
|
func4->setDisplaySamplePoints(en);
|
|
|
|
plot->redrawPlot();
|
|
|
|
});
|
2018-12-24 03:27:24 +08:00
|
|
|
plot->addGraph(func4);
|
|
|
|
|
|
|
|
|
2020-09-05 19:47:46 +08:00
|
|
|
// 5. now we use a JKQTPXFunctionLineGraph to draw a static C function
|
2020-09-05 18:44:02 +08:00
|
|
|
TFUNCGRAPH* func5=new TFUNCGRAPH(plot);
|
2019-04-22 19:27:50 +08:00
|
|
|
func5->setPlotFunctionFunctor(&sinc);
|
2019-01-26 20:00:40 +08:00
|
|
|
func5->setTitle("static C function $10*\\sin(x)/x$");
|
2020-09-05 19:14:46 +08:00
|
|
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
|
|
|
func5->setDisplaySamplePoints(en);
|
|
|
|
plot->redrawPlot();
|
|
|
|
});
|
2018-12-24 03:27:24 +08:00
|
|
|
plot->addGraph(func5);
|
|
|
|
|
2020-09-05 19:47:46 +08:00
|
|
|
// 6. finally JKQTPXFunctionLineGraph defines a small set of common functions
|
2020-09-05 18:44:02 +08:00
|
|
|
TFUNCGRAPH* func6=new TFUNCGRAPH(plot);
|
|
|
|
func6->setSpecialFunction(TFUNCGRAPH::Line);
|
2018-12-24 22:07:14 +08:00
|
|
|
// here we set offset p0=-1 and slope p1=1.5 of the line p0+p1*x
|
2019-01-26 20:00:40 +08:00
|
|
|
func6->setParamsV(-1,1.5);
|
|
|
|
func6->setTitle("special function: linear p_0=-1, p_1=1.5");
|
2020-09-05 19:14:46 +08:00
|
|
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
|
|
|
func6->setDisplaySamplePoints(en);
|
|
|
|
plot->redrawPlot();
|
|
|
|
});
|
2018-12-24 03:27:24 +08:00
|
|
|
plot->addGraph(func6);
|
|
|
|
|
2019-01-20 17:49:29 +08:00
|
|
|
// 7. finally JKQTPXFunctionLineGraph defines a small set of common functions
|
2020-09-05 18:44:02 +08:00
|
|
|
TFUNCGRAPH* func7=new TFUNCGRAPH(plot);
|
|
|
|
func7->setSpecialFunction(TFUNCGRAPH::Line);
|
2018-12-24 22:07:14 +08:00
|
|
|
// here we set offset p0=1 and slope p1=-1.5 of the line p0+p1*x by adding these into a column
|
|
|
|
// in the internal datastore and then set that column as parameterColumn for the function graph
|
|
|
|
QVector<double> params;
|
|
|
|
params << /*p0=*/1 << /*p1=*/-1.5;
|
|
|
|
size_t paramCol=plot->getDatastore()->addCopiedColumn(params);
|
2019-01-26 20:00:40 +08:00
|
|
|
func7->setParameterColumn(paramCol);
|
|
|
|
func7->setTitle("special function: linear p_0=1, p_1=-1.5");
|
2020-09-05 19:14:46 +08:00
|
|
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
|
|
|
func7->setDisplaySamplePoints(en);
|
|
|
|
plot->redrawPlot();
|
|
|
|
});
|
2018-12-24 22:07:14 +08:00
|
|
|
plot->addGraph(func7);
|
|
|
|
|
2018-12-24 03:27:24 +08:00
|
|
|
|
|
|
|
// 8. set some axis properties (we use LaTeX for nice equation rendering)
|
2019-01-26 03:16:04 +08:00
|
|
|
plot->getXAxis()->setAxisLabel(QObject::tr("x-axis"));
|
|
|
|
plot->getYAxis()->setAxisLabel(QObject::tr("y-axis"));
|
|
|
|
plot->getPlotter()->setKeyPosition(JKQTPKeyOutsideBottomLeft);
|
2018-12-24 03:27:24 +08:00
|
|
|
|
|
|
|
|
2020-09-05 19:47:46 +08:00
|
|
|
// 9. scale the plot so the graph is contained
|
2018-12-24 03:27:24 +08:00
|
|
|
plot->setXY(-10,10,-10,10);
|
2020-09-05 18:44:02 +08:00
|
|
|
plot->redrawPlot();
|
2018-12-24 03:27:24 +08:00
|
|
|
|
|
|
|
// show window and make it a decent size
|
2020-09-05 18:44:02 +08:00
|
|
|
mainWin->show();
|
2022-08-27 04:32:48 +08:00
|
|
|
mainWin->resize(600,600);
|
2020-09-05 18:44:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
|
|
{
|
2022-04-16 05:01:09 +08:00
|
|
|
|
2022-08-27 04:32:48 +08:00
|
|
|
JKQTPAppSettingController highDPIController(argc, argv);
|
|
|
|
JKQTPExampleApplication app(argc, argv);
|
2020-09-05 18:44:02 +08:00
|
|
|
|
2022-04-16 05:01:09 +08:00
|
|
|
|
2020-09-05 18:44:02 +08:00
|
|
|
drawExample<JKQTPXFunctionLineGraph>(app, "functionplot: JKQTPXFunctionLineGraph");
|
|
|
|
drawExample<JKQTPYFunctionLineGraph>(app, "functionplot: JKQTPYFunctionLineGraph");
|
|
|
|
|
2018-12-24 03:27:24 +08:00
|
|
|
|
|
|
|
return app.exec();
|
|
|
|
}
|