mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2025-01-13 01:10:33 +08:00
created common base class JKQTPFunctionLineGraphBase for all graphs that display evaluated functions
This commit is contained in:
parent
48a24a85d0
commit
29ee1aa376
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QCheckBox>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
@ -26,7 +27,7 @@ private:
|
|||||||
|
|
||||||
template <class TFUNCGRAPH>
|
template <class TFUNCGRAPH>
|
||||||
void drawExample(QApplication& app, const QString& name) {
|
void drawExample(QApplication& app, const QString& name) {
|
||||||
// 1. create a window that contains a line-edit to edit a function
|
// 1.1 create a window that contains a line-edit to edit a function
|
||||||
// and a JKQTPlotter to display the function, combine everything in a layout
|
// and a JKQTPlotter to display the function, combine everything in a layout
|
||||||
QWidget* mainWin=new QWidget();
|
QWidget* mainWin=new QWidget();
|
||||||
mainWin->setWindowTitle(name);
|
mainWin->setWindowTitle(name);
|
||||||
@ -34,12 +35,20 @@ void drawExample(QApplication& app, const QString& name) {
|
|||||||
QVBoxLayout* layout=new QVBoxLayout;
|
QVBoxLayout* layout=new QVBoxLayout;
|
||||||
mainWin->setLayout(layout);
|
mainWin->setLayout(layout);
|
||||||
layout->addWidget(plot);
|
layout->addWidget(plot);
|
||||||
|
// 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);
|
||||||
|
|
||||||
// 2. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function
|
// 2. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function
|
||||||
// the function is defined as C++ inline function
|
// the function is defined as C++ inline function
|
||||||
TFUNCGRAPH* func1=new TFUNCGRAPH(plot);
|
TFUNCGRAPH* func1=new TFUNCGRAPH(plot);
|
||||||
func1->setPlotFunctionFunctor([](double x) { return 0.2*x*x-0.015*x*x*x; });
|
func1->setPlotFunctionFunctor([](double x) { return 0.2*x*x-0.015*x*x*x; });
|
||||||
func1->setTitle("C++-inline function $0.2x^2-0.015x^3$");
|
func1->setTitle("C++-inline function $0.2x^2-0.015x^3$");
|
||||||
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
||||||
|
func1->setDisplaySamplePoints(en);
|
||||||
|
plot->redrawPlot();
|
||||||
|
});
|
||||||
plot->addGraph(func1);
|
plot->addGraph(func1);
|
||||||
|
|
||||||
// 3. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function
|
// 3. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function
|
||||||
@ -53,6 +62,10 @@ void drawExample(QApplication& app, const QString& name) {
|
|||||||
// here we set the parameters p0, p1
|
// here we set the parameters p0, p1
|
||||||
func2->setParamsV(5, 0.2);
|
func2->setParamsV(5, 0.2);
|
||||||
func2->setTitle("C++-inline function with int. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
func2->setTitle("C++-inline function with int. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
||||||
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
||||||
|
func2->setDisplaySamplePoints(en);
|
||||||
|
plot->redrawPlot();
|
||||||
|
});
|
||||||
plot->addGraph(func2);
|
plot->addGraph(func2);
|
||||||
|
|
||||||
// 4. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function
|
// 4. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function
|
||||||
@ -75,6 +88,10 @@ void drawExample(QApplication& app, const QString& name) {
|
|||||||
TFUNCGRAPH* func4=new TFUNCGRAPH(plot);
|
TFUNCGRAPH* func4=new TFUNCGRAPH(plot);
|
||||||
func4->setPlotFunctionFunctor(SincSqr(-8));
|
func4->setPlotFunctionFunctor(SincSqr(-8));
|
||||||
func4->setTitle("C++ functor $-8*\\sin^2(x)/x^2$");
|
func4->setTitle("C++ functor $-8*\\sin^2(x)/x^2$");
|
||||||
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
||||||
|
func4->setDisplaySamplePoints(en);
|
||||||
|
plot->redrawPlot();
|
||||||
|
});
|
||||||
plot->addGraph(func4);
|
plot->addGraph(func4);
|
||||||
|
|
||||||
|
|
||||||
@ -82,6 +99,10 @@ void drawExample(QApplication& app, const QString& name) {
|
|||||||
TFUNCGRAPH* func5=new TFUNCGRAPH(plot);
|
TFUNCGRAPH* func5=new TFUNCGRAPH(plot);
|
||||||
func5->setPlotFunctionFunctor(&sinc);
|
func5->setPlotFunctionFunctor(&sinc);
|
||||||
func5->setTitle("static C function $10*\\sin(x)/x$");
|
func5->setTitle("static C function $10*\\sin(x)/x$");
|
||||||
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
||||||
|
func5->setDisplaySamplePoints(en);
|
||||||
|
plot->redrawPlot();
|
||||||
|
});
|
||||||
plot->addGraph(func5);
|
plot->addGraph(func5);
|
||||||
|
|
||||||
// 7. finally JKQTPXFunctionLineGraph defines a small set of common functions
|
// 7. finally JKQTPXFunctionLineGraph defines a small set of common functions
|
||||||
@ -90,6 +111,10 @@ void drawExample(QApplication& app, const QString& name) {
|
|||||||
// here we set offset p0=-1 and slope p1=1.5 of the line p0+p1*x
|
// here we set offset p0=-1 and slope p1=1.5 of the line p0+p1*x
|
||||||
func6->setParamsV(-1,1.5);
|
func6->setParamsV(-1,1.5);
|
||||||
func6->setTitle("special function: linear p_0=-1, p_1=1.5");
|
func6->setTitle("special function: linear p_0=-1, p_1=1.5");
|
||||||
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
||||||
|
func6->setDisplaySamplePoints(en);
|
||||||
|
plot->redrawPlot();
|
||||||
|
});
|
||||||
plot->addGraph(func6);
|
plot->addGraph(func6);
|
||||||
|
|
||||||
// 7. finally JKQTPXFunctionLineGraph defines a small set of common functions
|
// 7. finally JKQTPXFunctionLineGraph defines a small set of common functions
|
||||||
@ -102,6 +127,10 @@ void drawExample(QApplication& app, const QString& name) {
|
|||||||
size_t paramCol=plot->getDatastore()->addCopiedColumn(params);
|
size_t paramCol=plot->getDatastore()->addCopiedColumn(params);
|
||||||
func7->setParameterColumn(paramCol);
|
func7->setParameterColumn(paramCol);
|
||||||
func7->setTitle("special function: linear p_0=1, p_1=-1.5");
|
func7->setTitle("special function: linear p_0=1, p_1=-1.5");
|
||||||
|
QObject::connect(chkShowSamples, &QCheckBox::toggled, [=](bool en) {
|
||||||
|
func7->setDisplaySamplePoints(en);
|
||||||
|
plot->redrawPlot();
|
||||||
|
});
|
||||||
plot->addGraph(func7);
|
plot->addGraph(func7);
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ isEmpty(JKQTP_PLOTTER_PRI_INCLUDED) {
|
|||||||
$$PWD/jkqtplotter/jkqtpoverlaysbase.h \
|
$$PWD/jkqtplotter/jkqtpoverlaysbase.h \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpboxplot.h \
|
$$PWD/jkqtplotter/graphs/jkqtpboxplot.h \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpboxplotstylingmixins.h \
|
$$PWD/jkqtplotter/graphs/jkqtpboxplotstylingmixins.h \
|
||||||
|
$$PWD/jkqtplotter/graphs/jkqtpevaluatedfunctionbase.h \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpevaluatedfunction.h \
|
$$PWD/jkqtplotter/graphs/jkqtpevaluatedfunction.h \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpfilledcurve.h \
|
$$PWD/jkqtplotter/graphs/jkqtpfilledcurve.h \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpgeometric.h \
|
$$PWD/jkqtplotter/graphs/jkqtpgeometric.h \
|
||||||
@ -77,6 +78,7 @@ isEmpty(JKQTP_PLOTTER_PRI_INCLUDED) {
|
|||||||
$$PWD/jkqtplotter/jkqtpoverlaysbase.cpp \
|
$$PWD/jkqtplotter/jkqtpoverlaysbase.cpp \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpboxplot.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtpboxplot.cpp \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpboxplotstylingmixins.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtpboxplotstylingmixins.cpp \
|
||||||
|
$$PWD/jkqtplotter/graphs/jkqtpevaluatedfunctionbase.cpp \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpevaluatedfunction.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtpevaluatedfunction.cpp \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpfilledcurve.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtpfilledcurve.cpp \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpgeometric.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtpgeometric.cpp \
|
||||||
|
@ -44,6 +44,7 @@ set(SOURCES_GRAPHS
|
|||||||
graphs/jkqtpbarchart.cpp
|
graphs/jkqtpbarchart.cpp
|
||||||
graphs/jkqtpboxplot.cpp
|
graphs/jkqtpboxplot.cpp
|
||||||
graphs/jkqtpboxplotstylingmixins.cpp
|
graphs/jkqtpboxplotstylingmixins.cpp
|
||||||
|
graphs/jkqtpevaluatedfunctionbase.cpp
|
||||||
graphs/jkqtpevaluatedfunction.cpp
|
graphs/jkqtpevaluatedfunction.cpp
|
||||||
graphs/jkqtpfilledcurve.cpp
|
graphs/jkqtpfilledcurve.cpp
|
||||||
graphs/jkqtpgeometric.cpp
|
graphs/jkqtpgeometric.cpp
|
||||||
@ -97,6 +98,7 @@ set(HEADERS
|
|||||||
set(HEADERS_GRAPHS
|
set(HEADERS_GRAPHS
|
||||||
graphs/jkqtpboxplot.h
|
graphs/jkqtpboxplot.h
|
||||||
graphs/jkqtpboxplotstylingmixins.h
|
graphs/jkqtpboxplotstylingmixins.h
|
||||||
|
graphs/jkqtpevaluatedfunctionbase.h
|
||||||
graphs/jkqtpevaluatedfunction.h
|
graphs/jkqtpevaluatedfunction.h
|
||||||
graphs/jkqtpfilledcurve.h
|
graphs/jkqtpfilledcurve.h
|
||||||
graphs/jkqtpgeometric.h
|
graphs/jkqtpgeometric.h
|
||||||
|
@ -34,19 +34,12 @@
|
|||||||
|
|
||||||
|
|
||||||
JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(JKQTBasePlotter* parent):
|
JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(JKQTBasePlotter* parent):
|
||||||
JKQTPGraph(parent)
|
JKQTPFunctionLineGraphBase(parent)
|
||||||
{
|
{
|
||||||
functionType=SpecialFunction::UserFunction;
|
functionType=SpecialFunction::UserFunction;
|
||||||
drawLine=true;
|
drawLine=true;
|
||||||
fillCurve=false;
|
fillCurve=false;
|
||||||
params=nullptr;
|
params=nullptr;
|
||||||
minSamples=50;
|
|
||||||
maxRefinementDegree=5;
|
|
||||||
slopeTolerance=0.005;
|
|
||||||
minPixelPerSample=32;
|
|
||||||
dataCleanupMaxAllowedAngleDegree=0.2;
|
|
||||||
displaySamplePoints=false;
|
|
||||||
data.clear();
|
|
||||||
|
|
||||||
initLineStyle(parent, parentPlotStyle);
|
initLineStyle(parent, parentPlotStyle);
|
||||||
initFillStyle(parent, parentPlotStyle);
|
initFillStyle(parent, parentPlotStyle);
|
||||||
@ -301,16 +294,6 @@ void JKQTPXFunctionLineGraph::collectParameters()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JKQTPXFunctionLineGraph::drawSamplePoints(JKQTPEnhancedPainter& painter) {
|
|
||||||
QColor c=getLineColor();
|
|
||||||
c.setHsv(fmod(c.hue()+90, 360), c.saturation(), c.value());
|
|
||||||
painter.save(); auto __finalpaintsamplepoints=JKQTPFinally([&painter]() {painter.restore();});
|
|
||||||
for (const auto& d: data) {
|
|
||||||
if (JKQTPIsOKFloat(d.x()) && JKQTPIsOKFloat(d.y())) {
|
|
||||||
JKQTPPlotSymbol(painter, d.x(), d.y(), JKQTPCross, 6,1*parent->getLineWidthMultiplier(), c, QColor(Qt::transparent));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void JKQTPXFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
void JKQTPXFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||||
@ -432,7 +415,7 @@ void JKQTPXFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (displaySamplePoints) drawSamplePoints(painter);
|
if (displaySamplePoints) drawSamplePoints(painter, getLineColor());
|
||||||
}
|
}
|
||||||
drawErrorsAfter(painter);
|
drawErrorsAfter(painter);
|
||||||
//std::cout<<"plot done\n";
|
//std::cout<<"plot done\n";
|
||||||
@ -620,7 +603,7 @@ void JKQTPYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (displaySamplePoints) drawSamplePoints(painter);
|
if (displaySamplePoints) drawSamplePoints(painter, getLineColor());
|
||||||
}
|
}
|
||||||
drawErrorsAfter(painter);
|
drawErrorsAfter(painter);
|
||||||
//std::cout<<"plot done\n";
|
//std::cout<<"plot done\n";
|
||||||
@ -858,66 +841,6 @@ QVector<double> JKQTPXFunctionLineGraph::getInternalErrorParams() const {
|
|||||||
return ierrorparams;
|
return ierrorparams;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JKQTPXFunctionLineGraph::setMinSamples(const unsigned int &__value)
|
|
||||||
{
|
|
||||||
this->minSamples = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int JKQTPXFunctionLineGraph::getMinSamples() const
|
|
||||||
{
|
|
||||||
return this->minSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXFunctionLineGraph::setMaxRefinementDegree(const unsigned int &__value)
|
|
||||||
{
|
|
||||||
this->maxRefinementDegree = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int JKQTPXFunctionLineGraph::getMaxRefinementDegree() const
|
|
||||||
{
|
|
||||||
return this->maxRefinementDegree;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXFunctionLineGraph::setSlopeTolerance(double __value)
|
|
||||||
{
|
|
||||||
this->slopeTolerance = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPXFunctionLineGraph::getSlopeTolerance() const
|
|
||||||
{
|
|
||||||
return this->slopeTolerance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXFunctionLineGraph::setMinPixelPerSample(double __value)
|
|
||||||
{
|
|
||||||
this->minPixelPerSample = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPXFunctionLineGraph::getMinPixelPerSample() const
|
|
||||||
{
|
|
||||||
return this->minPixelPerSample;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXFunctionLineGraph::setDataCleanupMaxAllowedAngleDegree(double __value)
|
|
||||||
{
|
|
||||||
dataCleanupMaxAllowedAngleDegree=__value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPXFunctionLineGraph::getDataCleanupMaxAllowedAngleDegree() const
|
|
||||||
{
|
|
||||||
return dataCleanupMaxAllowedAngleDegree;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXFunctionLineGraph::setDisplaySamplePoints(bool __value)
|
|
||||||
{
|
|
||||||
this->displaySamplePoints = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JKQTPXFunctionLineGraph::getDisplaySamplePoints() const
|
|
||||||
{
|
|
||||||
return this->displaySamplePoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXFunctionLineGraph::setDrawErrorPolygons(bool __value)
|
void JKQTPXFunctionLineGraph::setDrawErrorPolygons(bool __value)
|
||||||
{
|
{
|
||||||
this->drawErrorPolygons = __value;
|
this->drawErrorPolygons = __value;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
#include "jkqtplotter/jkqtplotter_imexport.h"
|
#include "jkqtplotter/jkqtplotter_imexport.h"
|
||||||
#include "jkqtcommon/jkqtpgeometrytools.h"
|
#include "jkqtcommon/jkqtpgeometrytools.h"
|
||||||
|
#include "jkqtplotter/graphs/jkqtpevaluatedfunctionbase.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#ifndef jkqtpgraphsevaluatedfunction_H
|
#ifndef jkqtpgraphsevaluatedfunction_H
|
||||||
@ -73,7 +74,7 @@ typedef std::function<double(double)> jkqtpSimplePlotFunctionType;
|
|||||||
|
|
||||||
\see \ref JKQTPlotterFunctionPlots, JKQTPAdaptiveFunctionGraphEvaluator, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph, jkqtpstatAddPolyFit(), jkqtpstatAddWeightedRegression(), jkqtpstatAddRobustIRLSRegression(), jkqtpstatAddRegression(), jkqtpstatAddLinearWeightedRegression(), jkqtpstatAddRobustIRLSLinearRegression(), jkqtpstatAddLinearRegression()
|
\see \ref JKQTPlotterFunctionPlots, JKQTPAdaptiveFunctionGraphEvaluator, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph, jkqtpstatAddPolyFit(), jkqtpstatAddWeightedRegression(), jkqtpstatAddRobustIRLSRegression(), jkqtpstatAddRegression(), jkqtpstatAddLinearWeightedRegression(), jkqtpstatAddRobustIRLSLinearRegression(), jkqtpstatAddLinearRegression()
|
||||||
*/
|
*/
|
||||||
class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPGraph, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
|
class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPFunctionLineGraphBase, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -180,30 +181,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPGraph, public
|
|||||||
QVector<double> getInternalParams() const;
|
QVector<double> getInternalParams() const;
|
||||||
/** \brief returns the currently set internal parameter vector */
|
/** \brief returns the currently set internal parameter vector */
|
||||||
QVector<double> getInternalErrorParams() const;
|
QVector<double> getInternalErrorParams() const;
|
||||||
/*! \copydoc minSamples */
|
|
||||||
void setMinSamples(const unsigned int & __value);
|
|
||||||
/*! \copydoc minSamples */
|
|
||||||
unsigned int getMinSamples() const;
|
|
||||||
/*! \copydoc maxRefinementDegree */
|
|
||||||
void setMaxRefinementDegree(const unsigned int & __value);
|
|
||||||
/*! \copydoc maxRefinementDegree */
|
|
||||||
unsigned int getMaxRefinementDegree() const;
|
|
||||||
/*! \copydoc slopeTolerance */
|
|
||||||
void setSlopeTolerance(double __value);
|
|
||||||
/*! \copydoc slopeTolerance */
|
|
||||||
double getSlopeTolerance() const;
|
|
||||||
/*! \copydoc minPixelPerSample */
|
|
||||||
void setMinPixelPerSample(double __value);
|
|
||||||
/*! \copydoc minPixelPerSample */
|
|
||||||
double getMinPixelPerSample() const;
|
|
||||||
/*! \copydoc dataCleanupMaxAllowedAngleDegree */
|
|
||||||
void setDataCleanupMaxAllowedAngleDegree(double __value);
|
|
||||||
/*! \copydoc dataCleanupMaxAllowedAngleDegree */
|
|
||||||
double getDataCleanupMaxAllowedAngleDegree() const;
|
|
||||||
/*! \copydoc displaySamplePoints */
|
|
||||||
void setDisplaySamplePoints(bool __value);
|
|
||||||
/*! \copydoc displaySamplePoints */
|
|
||||||
bool getDisplaySamplePoints() const;
|
|
||||||
/*! \copydoc drawErrorPolygons */
|
/*! \copydoc drawErrorPolygons */
|
||||||
void setDrawErrorPolygons(bool __value);
|
void setDrawErrorPolygons(bool __value);
|
||||||
/*! \copydoc drawErrorPolygons */
|
/*! \copydoc drawErrorPolygons */
|
||||||
@ -288,11 +266,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPGraph, public
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
/** \brief plot data calculated by createPlotData(), i.e. the datapoints \f$ \mbox{transform}\left(x, y=f(x, \vec{p})\right) \f$ to be plotted */
|
|
||||||
QVector<QPointF> data;
|
|
||||||
|
|
||||||
/** \brief fill the data array with data from the function plotFunction */
|
/** \brief fill the data array with data from the function plotFunction */
|
||||||
virtual void createPlotData( bool collectParams=true);
|
virtual void createPlotData( bool collectParams=true) override;
|
||||||
/** \brief ensure that current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams and ierrorparams */
|
/** \brief ensure that current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams and ierrorparams */
|
||||||
virtual void collectParameters();
|
virtual void collectParameters();
|
||||||
|
|
||||||
@ -314,24 +289,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPGraph, public
|
|||||||
SpecialFunction functionType;
|
SpecialFunction functionType;
|
||||||
/** \brief pointer to the parameters supplied to the plotting funtion */
|
/** \brief pointer to the parameters supplied to the plotting funtion */
|
||||||
void* params;
|
void* params;
|
||||||
/** \brief the minimum number of points to evaluate the function at */
|
|
||||||
unsigned int minSamples;
|
|
||||||
/** \brief the maximum number of recursive refinement steps
|
|
||||||
*
|
|
||||||
* each step bisects the interval \f$ [a, b] \f$ into two halfes. So the maximum number
|
|
||||||
* of points plotted at all are thus:
|
|
||||||
* \f[ \mbox{minSamples} \cdot 2^{\mbox{maxRefinementDegree}} \f]
|
|
||||||
*/
|
|
||||||
unsigned int maxRefinementDegree;
|
|
||||||
/** \brief the tolerance for the difference of two subsequent slopes */
|
|
||||||
double slopeTolerance;
|
|
||||||
/** \brief create one sample at least every \a minPixelPerSample pixels */
|
|
||||||
double minPixelPerSample;
|
|
||||||
/** \brief in the clean-up step of plot-data creation, a point is removed from the data, if
|
|
||||||
* it caused its neighboring line-segments to form an angle less than this value, given in degrees. */
|
|
||||||
double dataCleanupMaxAllowedAngleDegree;
|
|
||||||
/** \brief if true [default: off] display the points where the function has been sampled */
|
|
||||||
bool displaySamplePoints;
|
|
||||||
/** \brief indicates whether an error polygon should be drawn */
|
/** \brief indicates whether an error polygon should be drawn */
|
||||||
bool drawErrorPolygons;
|
bool drawErrorPolygons;
|
||||||
/** \brief indicates whether error lines should be drawn */
|
/** \brief indicates whether error lines should be drawn */
|
||||||
@ -362,8 +321,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPGraph, public
|
|||||||
QVector<double> iparams;
|
QVector<double> iparams;
|
||||||
/** \brief internal storage for the current error function parameters for errorPlotFunction (which may stem from different sources, as direct data, a datastore column ...) */
|
/** \brief internal storage for the current error function parameters for errorPlotFunction (which may stem from different sources, as direct data, a datastore column ...) */
|
||||||
QVector<double> ierrorparams;
|
QVector<double> ierrorparams;
|
||||||
/** \brief draw all the sample points in data as small symbols */
|
|
||||||
void drawSamplePoints(JKQTPEnhancedPainter &painter);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ x=f(y) \f$
|
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ x=f(y) \f$
|
||||||
|
134
lib/jkqtplotter/graphs/jkqtpevaluatedfunctionbase.cpp
Normal file
134
lib/jkqtplotter/graphs/jkqtpevaluatedfunctionbase.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2020 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This software is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||||
|
the Free Software Foundation, either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License (LGPL) for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "jkqtplotter/graphs/jkqtpevaluatedfunctionbase.h"
|
||||||
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <iostream>
|
||||||
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
#include "jkqtplotter/graphs/jkqtpimage.h"
|
||||||
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
JKQTPFunctionLineGraphBase::JKQTPFunctionLineGraphBase(JKQTBasePlotter* parent):
|
||||||
|
JKQTPGraph(parent)
|
||||||
|
{
|
||||||
|
minSamples=50;
|
||||||
|
maxRefinementDegree=5;
|
||||||
|
slopeTolerance=0.005;
|
||||||
|
minPixelPerSample=32;
|
||||||
|
dataCleanupMaxAllowedAngleDegree=0.2;
|
||||||
|
displaySamplePoints=false;
|
||||||
|
data.clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPFunctionLineGraphBase::JKQTPFunctionLineGraphBase(JKQTPlotter* parent):
|
||||||
|
JKQTPFunctionLineGraphBase(parent->getPlotter())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPFunctionLineGraphBase::~JKQTPFunctionLineGraphBase()
|
||||||
|
{
|
||||||
|
data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JKQTPFunctionLineGraphBase::drawSamplePoints(JKQTPEnhancedPainter& painter, QColor graphColor) {
|
||||||
|
QColor c=graphColor;
|
||||||
|
c.setHsv(fmod(c.hue()+90, 360), c.saturation(), c.value());
|
||||||
|
painter.save(); auto __finalpaintsamplepoints=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
|
for (const auto& d: data) {
|
||||||
|
if (JKQTPIsOKFloat(d.x()) && JKQTPIsOKFloat(d.y())) {
|
||||||
|
JKQTPPlotSymbol(painter, d.x(), d.y(), JKQTPCross, 6,1*parent->getLineWidthMultiplier(), c, QColor(Qt::transparent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void JKQTPFunctionLineGraphBase::setMinSamples(const unsigned int &__value)
|
||||||
|
{
|
||||||
|
this->minSamples = __value;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int JKQTPFunctionLineGraphBase::getMinSamples() const
|
||||||
|
{
|
||||||
|
return this->minSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPFunctionLineGraphBase::setMaxRefinementDegree(const unsigned int &__value)
|
||||||
|
{
|
||||||
|
this->maxRefinementDegree = __value;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int JKQTPFunctionLineGraphBase::getMaxRefinementDegree() const
|
||||||
|
{
|
||||||
|
return this->maxRefinementDegree;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPFunctionLineGraphBase::setSlopeTolerance(double __value)
|
||||||
|
{
|
||||||
|
this->slopeTolerance = __value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double JKQTPFunctionLineGraphBase::getSlopeTolerance() const
|
||||||
|
{
|
||||||
|
return this->slopeTolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPFunctionLineGraphBase::setMinPixelPerSample(double __value)
|
||||||
|
{
|
||||||
|
this->minPixelPerSample = __value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double JKQTPFunctionLineGraphBase::getMinPixelPerSample() const
|
||||||
|
{
|
||||||
|
return this->minPixelPerSample;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPFunctionLineGraphBase::setDataCleanupMaxAllowedAngleDegree(double __value)
|
||||||
|
{
|
||||||
|
dataCleanupMaxAllowedAngleDegree=__value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double JKQTPFunctionLineGraphBase::getDataCleanupMaxAllowedAngleDegree() const
|
||||||
|
{
|
||||||
|
return dataCleanupMaxAllowedAngleDegree;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPFunctionLineGraphBase::setDisplaySamplePoints(bool __value)
|
||||||
|
{
|
||||||
|
this->displaySamplePoints = __value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPFunctionLineGraphBase::getDisplaySamplePoints() const
|
||||||
|
{
|
||||||
|
return this->displaySamplePoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
128
lib/jkqtplotter/graphs/jkqtpevaluatedfunctionbase.h
Normal file
128
lib/jkqtplotter/graphs/jkqtpevaluatedfunctionbase.h
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2020 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This software is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||||
|
the Free Software Foundation, either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License (LGPL) for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPair>
|
||||||
|
#include "jkqtplotter/graphs/jkqtpscatter.h"
|
||||||
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
|
#include "jkqtplotter/jkqtplotter_imexport.h"
|
||||||
|
#include "jkqtcommon/jkqtpgeometrytools.h"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#ifndef jkqtpevaluatedfunctionbase_H
|
||||||
|
#define jkqtpevaluatedfunctionbase_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Base class for graph classes that evaluate a mathematical function (e.g. defined as a C-fucntion),
|
||||||
|
using an adaptive plotting algorithm from JKQTPAdaptiveFunctionGraphEvaluator
|
||||||
|
\ingroup jkqtplotter_functiongraphs
|
||||||
|
|
||||||
|
This class uses the intelligent plotting algorithm for functions, implemented in JKQTPAdaptiveFunctionGraphEvaluator.
|
||||||
|
It starts by sampling the function at minSamples positions. Then each function interval is bisected recursively if
|
||||||
|
necessary. To do so the function is evaluated at the mid point and the slopes \f$ \alpha_{\mbox{left}} \f$
|
||||||
|
and \f$ \alpha_{\mbox{right}} \f$ of the two linear segments are compared. the midpoint is added
|
||||||
|
to the graph if \f[ \left|\alpha_{\mbox{right}}-\alpha_{\mbox{left}}\right|>\mbox{slopeTolerance} \f]
|
||||||
|
In addition all sampling points except minimum and maximum are beeing shifted by a random fraction their
|
||||||
|
distance to the other points. This helps to prevent beats when sampling periodic functions.
|
||||||
|
|
||||||
|
Finally the obtained data is cleaned up to reduce the amount of points, by deleting a point, when it leads to an
|
||||||
|
angle between consecutive line-segments of less than dataCleanupMaxAllowedAngleDegree.
|
||||||
|
|
||||||
|
|
||||||
|
\see JKQTPAdaptiveFunctionGraphEvaluator, JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph
|
||||||
|
*/
|
||||||
|
class JKQTPLOTTER_LIB_EXPORT JKQTPFunctionLineGraphBase: public JKQTPGraph {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPFunctionLineGraphBase(JKQTBasePlotter* parent=nullptr);
|
||||||
|
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPFunctionLineGraphBase(JKQTPlotter* parent);
|
||||||
|
|
||||||
|
/** \brief class destructor */
|
||||||
|
virtual ~JKQTPFunctionLineGraphBase() ;
|
||||||
|
|
||||||
|
|
||||||
|
/*! \copydoc minSamples */
|
||||||
|
unsigned int getMinSamples() const;
|
||||||
|
/*! \copydoc maxRefinementDegree */
|
||||||
|
unsigned int getMaxRefinementDegree() const;
|
||||||
|
/*! \copydoc slopeTolerance */
|
||||||
|
double getSlopeTolerance() const;
|
||||||
|
/*! \copydoc minPixelPerSample */
|
||||||
|
double getMinPixelPerSample() const;
|
||||||
|
/*! \copydoc dataCleanupMaxAllowedAngleDegree */
|
||||||
|
double getDataCleanupMaxAllowedAngleDegree() const;
|
||||||
|
/*! \copydoc displaySamplePoints */
|
||||||
|
bool getDisplaySamplePoints() const;
|
||||||
|
public slots:
|
||||||
|
/*! \copydoc minSamples */
|
||||||
|
void setMinSamples(const unsigned int & __value);
|
||||||
|
/*! \copydoc maxRefinementDegree */
|
||||||
|
void setMaxRefinementDegree(const unsigned int & __value);
|
||||||
|
/*! \copydoc slopeTolerance */
|
||||||
|
void setSlopeTolerance(double __value);
|
||||||
|
/*! \copydoc minPixelPerSample */
|
||||||
|
void setMinPixelPerSample(double __value);
|
||||||
|
/*! \copydoc dataCleanupMaxAllowedAngleDegree */
|
||||||
|
void setDataCleanupMaxAllowedAngleDegree(double __value);
|
||||||
|
/*! \copydoc displaySamplePoints */
|
||||||
|
void setDisplaySamplePoints(bool __value);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief plot data calculated by createPlotData(), i.e. the datapoints \f$ \mbox{transform}\left(x, y=f(x, \vec{p})\right) \f$ to be plotted */
|
||||||
|
QVector<QPointF> data;
|
||||||
|
|
||||||
|
/** \brief fill the data array with data from the function plotFunction */
|
||||||
|
virtual void createPlotData( bool collectParams=true) =0;
|
||||||
|
|
||||||
|
/** \brief the minimum number of points to evaluate the function at */
|
||||||
|
unsigned int minSamples;
|
||||||
|
/** \brief the maximum number of recursive refinement steps
|
||||||
|
*
|
||||||
|
* each step bisects the interval \f$ [a, b] \f$ into two halfes. So the maximum number
|
||||||
|
* of points plotted at all are thus:
|
||||||
|
* \f[ \mbox{minSamples} \cdot 2^{\mbox{maxRefinementDegree}} \f]
|
||||||
|
*/
|
||||||
|
unsigned int maxRefinementDegree;
|
||||||
|
/** \brief the tolerance for the difference of two subsequent slopes */
|
||||||
|
double slopeTolerance;
|
||||||
|
/** \brief create one sample at least every \a minPixelPerSample pixels */
|
||||||
|
double minPixelPerSample;
|
||||||
|
/** \brief in the clean-up step of plot-data creation, a point is removed from the data, if
|
||||||
|
* it caused its neighboring line-segments to form an angle less than this value, given in degrees. */
|
||||||
|
double dataCleanupMaxAllowedAngleDegree;
|
||||||
|
/** \brief if true [default: off] display the points where the function has been sampled */
|
||||||
|
bool displaySamplePoints;
|
||||||
|
|
||||||
|
/** \brief draw all the sample points in data as small symbols */
|
||||||
|
void drawSamplePoints(JKQTPEnhancedPainter &painter, QColor graphColor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // jkqtpevaluatedfunctionbase_H
|
@ -35,17 +35,11 @@
|
|||||||
|
|
||||||
|
|
||||||
JKQTPXYFunctionLineGraph::JKQTPXYFunctionLineGraph(JKQTBasePlotter* parent):
|
JKQTPXYFunctionLineGraph::JKQTPXYFunctionLineGraph(JKQTBasePlotter* parent):
|
||||||
JKQTPGraph(parent)
|
JKQTPFunctionLineGraphBase(parent)
|
||||||
{
|
{
|
||||||
tmin=0.0;
|
tmin=0.0;
|
||||||
tmax=1.0;
|
tmax=1.0;
|
||||||
params=nullptr;
|
params=nullptr;
|
||||||
minSamples=100;
|
|
||||||
maxRefinementDegree=7;
|
|
||||||
slopeTolerance=0.005;
|
|
||||||
minPixelPerSample=32;
|
|
||||||
plotRefinement=true;
|
|
||||||
displaySamplePoints=false;
|
|
||||||
|
|
||||||
initLineStyle(parent, parentPlotStyle);
|
initLineStyle(parent, parentPlotStyle);
|
||||||
|
|
||||||
@ -268,7 +262,7 @@ void JKQTPXYFunctionLineGraph::createPlotData(bool collectParams) {
|
|||||||
|
|
||||||
JKQTPAdaptiveFunctionGraphEvaluator evaluator(fTransformedFunc, minSamples, maxRefinementDegree, slopeTolerance, minPixelPerSample);
|
JKQTPAdaptiveFunctionGraphEvaluator evaluator(fTransformedFunc, minSamples, maxRefinementDegree, slopeTolerance, minPixelPerSample);
|
||||||
data=evaluator.evaluate(tmin, tmax);
|
data=evaluator.evaluate(tmin, tmax);
|
||||||
|
data=JKQTPSimplyfyLineSegemnts(data, dataCleanupMaxAllowedAngleDegree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JKQTPXYFunctionLineGraph::collectParameters()
|
void JKQTPXYFunctionLineGraph::collectParameters()
|
||||||
@ -326,17 +320,7 @@ void JKQTPXYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QColor c=getLineColor();
|
if (displaySamplePoints) drawSamplePoints(painter, getLineColor());
|
||||||
c.setHsv(fmod(c.hue()+90, 360), c.saturation(), c.value());
|
|
||||||
if (displaySamplePoints) {
|
|
||||||
painter.save(); auto __finalpaintsamplepoints=JKQTPFinally([&painter]() {painter.restore();});
|
|
||||||
for (const auto& d: data) {
|
|
||||||
if (JKQTPIsOKFloat(d.x()) && JKQTPIsOKFloat(d.x())) {
|
|
||||||
JKQTPPlotSymbol(painter, d.x(), d.y(), JKQTPCross, 6,1*parent->getLineWidthMultiplier(), c, QColor(Qt::transparent));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
drawErrorsAfter(painter);
|
drawErrorsAfter(painter);
|
||||||
//std::cout<<"plot done\n";
|
//std::cout<<"plot done\n";
|
||||||
@ -409,66 +393,6 @@ QVector<double> JKQTPXYFunctionLineGraph::getInternalParams() const {
|
|||||||
return iparams;
|
return iparams;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JKQTPXYFunctionLineGraph::setMinSamples(const unsigned int &__value)
|
|
||||||
{
|
|
||||||
this->minSamples = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int JKQTPXYFunctionLineGraph::getMinSamples() const
|
|
||||||
{
|
|
||||||
return this->minSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXYFunctionLineGraph::setMaxRefinementDegree(const unsigned int &__value)
|
|
||||||
{
|
|
||||||
this->maxRefinementDegree = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int JKQTPXYFunctionLineGraph::getMaxRefinementDegree() const
|
|
||||||
{
|
|
||||||
return this->maxRefinementDegree;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXYFunctionLineGraph::setSlopeTolerance(double __value)
|
|
||||||
{
|
|
||||||
this->slopeTolerance = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPXYFunctionLineGraph::getSlopeTolerance() const
|
|
||||||
{
|
|
||||||
return this->slopeTolerance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXYFunctionLineGraph::setMinPixelPerSample(double __value)
|
|
||||||
{
|
|
||||||
this->minPixelPerSample = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPXYFunctionLineGraph::getMinPixelPerSample() const
|
|
||||||
{
|
|
||||||
return this->minPixelPerSample;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXYFunctionLineGraph::setPlotRefinement(bool __value)
|
|
||||||
{
|
|
||||||
this->plotRefinement = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JKQTPXYFunctionLineGraph::getPlotRefinement() const
|
|
||||||
{
|
|
||||||
return this->plotRefinement;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPXYFunctionLineGraph::setDisplaySamplePoints(bool __value)
|
|
||||||
{
|
|
||||||
this->displaySamplePoints = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JKQTPXYFunctionLineGraph::getDisplaySamplePoints() const
|
|
||||||
{
|
|
||||||
return this->displaySamplePoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool JKQTPXYFunctionLineGraph::usesColumn(int c) const
|
bool JKQTPXYFunctionLineGraph::usesColumn(int c) const
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
#include "jkqtplotter/jkqtplotter_imexport.h"
|
#include "jkqtplotter/jkqtplotter_imexport.h"
|
||||||
#include "jkqtcommon/jkqtpgeometrytools.h"
|
#include "jkqtcommon/jkqtpgeometrytools.h"
|
||||||
|
#include "jkqtplotter/graphs/jkqtpevaluatedfunctionbase.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#ifndef jkqtpevaluatedparametriccurve_H
|
#ifndef jkqtpevaluatedparametriccurve_H
|
||||||
@ -57,14 +58,17 @@ typedef std::function<QPointF(double)> jkqtpSimpleParametricCurveFunctionType;
|
|||||||
The function is evaluated on a user-specified range \f$ t \in \left[t_\text{min}, t_\text{max}\right] \f$
|
The function is evaluated on a user-specified range \f$ t \in \left[t_\text{min}, t_\text{max}\right] \f$
|
||||||
\ingroup jkqtplotter_functiongraphs
|
\ingroup jkqtplotter_functiongraphs
|
||||||
|
|
||||||
This class implements an intelligent plotting algorithm for functions. It starts by sampling
|
This class uses the intelligent plotting algorithm for functions, implemented in JKQTPAdaptiveFunctionGraphEvaluator.
|
||||||
the function at minSamples positions. Then each function interval is bisected recursively if
|
It starts by sampling the function at minSamples positions. Then each function interval is bisected recursively if
|
||||||
necessary. To do so the function is evaluated at the mid point and the slopes \f$ \alpha_{\mbox{left}} \f$
|
necessary. To do so the function is evaluated at the mid point and the slopes \f$ \alpha_{\mbox{left}} \f$
|
||||||
and \f$ \alpha_{\mbox{right}} \f$ of the two linear segments are compared. The midpoint is added
|
and \f$ \alpha_{\mbox{right}} \f$ of the two linear segments are compared. the midpoint is added
|
||||||
to the graph if \f[ \left|\alpha_{\mbox{right}}-\alpha_{\mbox{left}}\right|>\mbox{slopeTolerance} \f]
|
to the graph if \f[ \left|\alpha_{\mbox{right}}-\alpha_{\mbox{left}}\right|>\mbox{slopeTolerance} \f]
|
||||||
In addition all sampling points except minimum and maximum are beeing shifted by a random fraction their
|
In addition all sampling points except minimum and maximum are beeing shifted by a random fraction their
|
||||||
distance to the other points. This helps to prevent beats when sampling periodic functions.
|
distance to the other points. This helps to prevent beats when sampling periodic functions.
|
||||||
|
|
||||||
|
Finally the obtained data is cleaned up to reduce the amount of points, by deleting a point, when it leads to an
|
||||||
|
angle between consecutive line-segments of less than dataCleanupMaxAllowedAngleDegree.
|
||||||
|
|
||||||
the following image shows a Lissajou's fugure drawn with this function
|
the following image shows a Lissajou's fugure drawn with this function
|
||||||
|
|
||||||
\image html plot_evalcurve.png
|
\image html plot_evalcurve.png
|
||||||
@ -84,7 +88,7 @@ typedef std::function<QPointF(double)> jkqtpSimpleParametricCurveFunctionType;
|
|||||||
|
|
||||||
\see \ref JKQTPlotterEvalCurves , JKQTPAdaptiveFunctionGraphEvaluator, JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph
|
\see \ref JKQTPlotterEvalCurves , JKQTPAdaptiveFunctionGraphEvaluator, JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph
|
||||||
*/
|
*/
|
||||||
class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPGraph, public JKQTPGraphLineStyleMixin {
|
class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPFunctionLineGraphBase, public JKQTPGraphLineStyleMixin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -177,30 +181,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPGraph, public
|
|||||||
/** \brief returns the currently set internal parameter vector */
|
/** \brief returns the currently set internal parameter vector */
|
||||||
QVector<double> getInternalParams() const;
|
QVector<double> getInternalParams() const;
|
||||||
|
|
||||||
/*! \copydoc minSamples */
|
|
||||||
void setMinSamples(const unsigned int & __value);
|
|
||||||
/*! \copydoc minSamples */
|
|
||||||
unsigned int getMinSamples() const;
|
|
||||||
/*! \copydoc maxRefinementDegree */
|
|
||||||
void setMaxRefinementDegree(const unsigned int & __value);
|
|
||||||
/*! \copydoc maxRefinementDegree */
|
|
||||||
unsigned int getMaxRefinementDegree() const;
|
|
||||||
/*! \copydoc slopeTolerance */
|
|
||||||
void setSlopeTolerance(double __value);
|
|
||||||
/*! \copydoc slopeTolerance */
|
|
||||||
double getSlopeTolerance() const;
|
|
||||||
/*! \copydoc minPixelPerSample */
|
|
||||||
void setMinPixelPerSample(double __value);
|
|
||||||
/*! \copydoc minPixelPerSample */
|
|
||||||
double getMinPixelPerSample() const;
|
|
||||||
/*! \copydoc plotRefinement */
|
|
||||||
void setPlotRefinement(bool __value);
|
|
||||||
/*! \copydoc plotRefinement */
|
|
||||||
bool getPlotRefinement() const;
|
|
||||||
/*! \copydoc displaySamplePoints */
|
|
||||||
void setDisplaySamplePoints(bool __value);
|
|
||||||
/*! \copydoc displaySamplePoints */
|
|
||||||
bool getDisplaySamplePoints() const;
|
|
||||||
|
|
||||||
/*! \copydoc parameterColumn */
|
/*! \copydoc parameterColumn */
|
||||||
void setParameterColumn(int __value);
|
void setParameterColumn(int __value);
|
||||||
@ -233,14 +214,10 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPGraph, public
|
|||||||
double tmin;
|
double tmin;
|
||||||
/** \brief upper bound of t-value range for \f$ [x,y]=f(t), t \in \left[t_\text{min}, t_\text{max}\right] \f$ , i.e. \f$ t_\text{min} \f$ , default is 1 */
|
/** \brief upper bound of t-value range for \f$ [x,y]=f(t), t \in \left[t_\text{min}, t_\text{max}\right] \f$ , i.e. \f$ t_\text{min} \f$ , default is 1 */
|
||||||
double tmax;
|
double tmax;
|
||||||
|
|
||||||
/** \brief plot data calculated by createPlotData() */
|
|
||||||
QVector<QPointF> data;
|
|
||||||
|
|
||||||
/** \brief fill the data array with data from the function plotFunction */
|
/** \brief fill the data array with data from the function plotFunction */
|
||||||
virtual void createPlotData( bool collectParams=true);
|
virtual void createPlotData( bool collectParams=true) override;
|
||||||
/** \brief ensure that current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams */
|
/** \brief ensure that current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams */
|
||||||
virtual void collectParameters();
|
virtual void collectParameters() ;
|
||||||
|
|
||||||
/** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the plot function */
|
/** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the plot function */
|
||||||
int parameterColumn;
|
int parameterColumn;
|
||||||
@ -251,23 +228,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPGraph, public
|
|||||||
jkqtpSimpleParametricCurveFunctionType simplePlotFunction;
|
jkqtpSimpleParametricCurveFunctionType simplePlotFunction;
|
||||||
/** \brief pointer to the parameters supplied to the plotting funtion */
|
/** \brief pointer to the parameters supplied to the plotting funtion */
|
||||||
void* params;
|
void* params;
|
||||||
/** \brief the minimum number of points to evaluate the function at */
|
|
||||||
unsigned int minSamples;
|
|
||||||
/** \brief the maximum number of recursive refinement steps
|
|
||||||
*
|
|
||||||
* each step bisects the interval \f$ [a, b] \f$ into two halfes. So the maximum number
|
|
||||||
* of points plotted at all are thus:
|
|
||||||
* \f[ \mbox{minSamples} \cdot 2^{\mbox{maxRefinementDegree}} \f]
|
|
||||||
*/
|
|
||||||
unsigned int maxRefinementDegree;
|
|
||||||
/** \brief the tolerance for the difference of two subsequent slopes */
|
|
||||||
double slopeTolerance;
|
|
||||||
/** \brief create one sample at least every \a minPixelPerSample pixels */
|
|
||||||
double minPixelPerSample;
|
|
||||||
/** \brief switch on or off [default: on] the plot refinement algorithm */
|
|
||||||
bool plotRefinement;
|
|
||||||
/** \brief if true [default: off] display the points where the function has been sampled */
|
|
||||||
bool displaySamplePoints;
|
|
||||||
/** \brief internal storage for the current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) */
|
/** \brief internal storage for the current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) */
|
||||||
QVector<double> iparams;
|
QVector<double> iparams;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user