mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 10:01:38 +08:00
- added further base-class JKQTPEvaluatedFunctionWithParamsGraphBase, which extends JKQTPEvaluatedFunctionGraphBase with parameters
- modified plot-function with parameters, as the old unsafe way of giving a void* for parameters is no longer necessary with C++-lambdas and std::bind()
This commit is contained in:
parent
dcdee469fe
commit
414e12920e
@ -18,31 +18,14 @@ The first example shows how to plot a C++ inline function:
|
||||
In any such plot function, you can also use parameters, provided via the second parameter. Usually these are "internal parameters", defined by `func2->setParamsV(p0, p1, ...)`:
|
||||
```.cpp
|
||||
JKQTPXFunctionLineGraph* func2=new JKQTPXFunctionLineGraph(plot);
|
||||
func2->setPlotFunctionFunctor([](double x, void* params) {
|
||||
QVector<double>* p=static_cast<QVector<double>*>(params);
|
||||
return p->at(0)*sin(2.0*M_PI*x*p->at(1));
|
||||
});
|
||||
// here we set the parameters p0, p1
|
||||
func2->setPlotFunctionFunctor([](double x, const QVector<double>& p) {
|
||||
return p.at(0)*sin(2.0*JKQTPSTATISTICS_PI*x*p.at(1));
|
||||
}); // here we set the parameters p0, p1
|
||||
func2->setParamsV(5, 0.2);
|
||||
func2->setTitle("C++-inline function with int. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
||||
plot->addGraph(func2);
|
||||
```
|
||||
|
||||
... but generally any pointer can be used as parameter (the set by `setParameter(static_cast<void*>(myDataObject))`):
|
||||
```.cpp
|
||||
JKQTPXFunctionLineGraph* func3=new JKQTPXFunctionLineGraph(plot);
|
||||
func3->setPlotFunctionFunctor([](double x, void* params) {
|
||||
QMap<QString,double>* p=static_cast<QMap<QString,double>*>(params);
|
||||
return p->value("amplitude")*sin(2.0*M_PI*x*p->value("frequency"));
|
||||
});
|
||||
// here we set the parameters p0, p1
|
||||
QMap<QString,double> params3;
|
||||
params3["amplitude"]=-3;
|
||||
params3["frequency"]=0.3;
|
||||
func3->setParams(¶ms3);
|
||||
func3->setTitle("C++-inline function with ext. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
||||
plot->addGraph(func3);
|
||||
```
|
||||
|
||||
# C++ functors as plot functions
|
||||
|
||||
|
@ -55,9 +55,8 @@ void drawExample(QApplication& app, const QString& name) {
|
||||
// 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>
|
||||
TFUNCGRAPH* func2=new TFUNCGRAPH(plot);
|
||||
func2->setPlotFunctionFunctor([](double x, void* params) {
|
||||
QVector<double>* p=static_cast<QVector<double>*>(params);
|
||||
return p->at(0)*sin(2.0*JKQTPSTATISTICS_PI*x*p->at(1));
|
||||
func2->setPlotFunctionFunctor([](double x, const QVector<double>& p) {
|
||||
return p.at(0)*sin(2.0*JKQTPSTATISTICS_PI*x*p.at(1));
|
||||
});
|
||||
// here we set the parameters p0, p1
|
||||
func2->setParamsV(5, 0.2);
|
||||
@ -68,23 +67,7 @@ void drawExample(QApplication& app, const QString& name) {
|
||||
});
|
||||
plot->addGraph(func2);
|
||||
|
||||
// 4. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function
|
||||
// the function is again defined as C++ inline function, but now uses external
|
||||
// parameters, which may have any type (here QMap<QString,double)
|
||||
/*TFUNCGRAPH* func3=new TFUNCGRAPH(plot);
|
||||
func3->setPlotFunctionFunctor([](double x, void* params) {
|
||||
QMap<QString,double>* p=static_cast<QMap<QString,double>*>(params);
|
||||
return p->value("amplitude")*sin(2.0*JKQTPSTATISTICS_PI*x*p->value("frequency"));
|
||||
});
|
||||
// here we set the parameters p0, p1
|
||||
QMap<QString,double> params3;
|
||||
params3["amplitude"]=-3;
|
||||
params3["frequency"]=0.3;
|
||||
func3->setParams(¶ms3);
|
||||
func3->setTitle("C++-inline function with ext. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
||||
plot->addGraph(func3);*/
|
||||
|
||||
// 5. of course the function may also be any C+ funtor object:
|
||||
// 4. of course the function may also be any C+ funtor object:
|
||||
TFUNCGRAPH* func4=new TFUNCGRAPH(plot);
|
||||
func4->setPlotFunctionFunctor(SincSqr(-8));
|
||||
func4->setTitle("C++ functor $-8*\\sin^2(x)/x^2$");
|
||||
@ -95,7 +78,7 @@ void drawExample(QApplication& app, const QString& name) {
|
||||
plot->addGraph(func4);
|
||||
|
||||
|
||||
// 6. now we use a JKQTPXFunctionLineGraph to draw a static C function
|
||||
// 5. now we use a JKQTPXFunctionLineGraph to draw a static C function
|
||||
TFUNCGRAPH* func5=new TFUNCGRAPH(plot);
|
||||
func5->setPlotFunctionFunctor(&sinc);
|
||||
func5->setTitle("static C function $10*\\sin(x)/x$");
|
||||
@ -105,7 +88,7 @@ void drawExample(QApplication& app, const QString& name) {
|
||||
});
|
||||
plot->addGraph(func5);
|
||||
|
||||
// 7. finally JKQTPXFunctionLineGraph defines a small set of common functions
|
||||
// 6. finally JKQTPXFunctionLineGraph defines a small set of common functions
|
||||
TFUNCGRAPH* func6=new TFUNCGRAPH(plot);
|
||||
func6->setSpecialFunction(TFUNCGRAPH::Line);
|
||||
// here we set offset p0=-1 and slope p1=1.5 of the line p0+p1*x
|
||||
@ -140,7 +123,7 @@ void drawExample(QApplication& app, const QString& name) {
|
||||
plot->getPlotter()->setKeyPosition(JKQTPKeyOutsideBottomLeft);
|
||||
|
||||
|
||||
// 4. scale the plot so the graph is contained
|
||||
// 9. scale the plot so the graph is contained
|
||||
plot->setXY(-10,10,-10,10);
|
||||
plot->redrawPlot();
|
||||
|
||||
|
@ -34,12 +34,11 @@
|
||||
|
||||
|
||||
JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(JKQTBasePlotter* parent):
|
||||
JKQTPEvaluatedFunctionGraphBase(parent)
|
||||
JKQTPEvaluatedFunctionWithParamsGraphBase(parent)
|
||||
{
|
||||
functionType=SpecialFunction::UserFunction;
|
||||
drawLine=true;
|
||||
fillCurve=false;
|
||||
params=nullptr;
|
||||
|
||||
initLineStyle(parent, parentPlotStyle);
|
||||
initFillStyle(parent, parentPlotStyle);
|
||||
@ -53,7 +52,6 @@ JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(JKQTBasePlotter* parent):
|
||||
errorLineWidth=1;
|
||||
errorFillStyle=Qt::SolidPattern;
|
||||
|
||||
parameterColumn=-1;
|
||||
errorParameterColumn=-1;
|
||||
|
||||
|
||||
@ -181,20 +179,6 @@ jkqtpSimplePlotFunctionType JKQTPXFunctionLineGraph::getSimplePlotFunction() con
|
||||
return simplePlotFunction;
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setParams(void *__value)
|
||||
{
|
||||
if (this->params != __value) {
|
||||
this->params = __value;
|
||||
data.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void *JKQTPXFunctionLineGraph::getParams() const
|
||||
{
|
||||
return this->params;
|
||||
}
|
||||
|
||||
|
||||
void JKQTPXFunctionLineGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
QPen p=getLinePen(painter, parent);
|
||||
@ -236,7 +220,7 @@ void JKQTPXFunctionLineGraph::createPlotData(bool collectParams) {
|
||||
if (!plotFunction && !simplePlotFunction) return;
|
||||
|
||||
jkqtpSimplePlotFunctionType func;
|
||||
if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, params);
|
||||
if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, getInternalParams());
|
||||
else if (simplePlotFunction) func=simplePlotFunction;
|
||||
|
||||
const double xmin=parent->getXMin();
|
||||
@ -251,29 +235,8 @@ void JKQTPXFunctionLineGraph::createPlotData(bool collectParams) {
|
||||
|
||||
void JKQTPXFunctionLineGraph::collectParameters()
|
||||
{
|
||||
if (parent && parameterColumn>=0) {
|
||||
iparams.clear();
|
||||
JKQTPDatastore* datastore=parent->getDatastore();
|
||||
int imin=0;
|
||||
int imax=static_cast<int>(datastore->getRows(parameterColumn));
|
||||
JKQTPEvaluatedFunctionWithParamsGraphBase::collectParameters();
|
||||
|
||||
for (int i=imin; i<imax; i++) {
|
||||
double xv=datastore->get(parameterColumn,i);
|
||||
iparams<<xv;
|
||||
}
|
||||
//qDebug()<<"iparams_beforeclean:";
|
||||
//for (int i=0; i<iparams.size(); i++) qDebug()<<iparams[i];
|
||||
int i=iparams.size()-1;
|
||||
while (i>=0 && !JKQTPIsOKFloat(iparams[i])) {
|
||||
iparams.remove(i,1);
|
||||
i--;
|
||||
}
|
||||
|
||||
//qDebug()<<"iparams:";
|
||||
//for (i=0; i<iparams.size(); i++) qDebug()<<iparams[i];
|
||||
|
||||
params=&iparams;
|
||||
}
|
||||
if (parent && errorParameterColumn>=0) {
|
||||
ierrorparams.clear();
|
||||
JKQTPDatastore* datastore=parent->getDatastore();
|
||||
@ -349,7 +312,7 @@ void JKQTPXFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||
double yv=backtransformY(y);
|
||||
double ype=0, yme=0;
|
||||
if ((drawErrorLines || drawErrorPolygons) && (static_cast<bool>(errorPlotFunction))) {
|
||||
double e=errorPlotFunction(xv, errorParams);
|
||||
double e=errorPlotFunction(xv, getInternalErrorParams());
|
||||
ype=transformY(yv+e);
|
||||
yme=transformY(yv-e);
|
||||
ype=qBound(yami, ype, yama);
|
||||
@ -538,7 +501,7 @@ void JKQTPYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||
double yv=backtransformY(y);
|
||||
double xpe=0, xme=0;
|
||||
if ((drawErrorLines || drawErrorPolygons) && (static_cast<bool>(errorPlotFunction))) {
|
||||
double e=errorPlotFunction(yv, errorParams);
|
||||
double e=errorPlotFunction(yv, getInternalErrorParams());
|
||||
xpe=transformX(xv+e);
|
||||
xme=transformX(xv-e);
|
||||
xpe=qBound(xami, xpe, xama);
|
||||
@ -618,7 +581,7 @@ void JKQTPYFunctionLineGraph::createPlotData(bool collectParams) {
|
||||
if (!plotFunction && !simplePlotFunction) return;
|
||||
|
||||
jkqtpSimplePlotFunctionType func;
|
||||
if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, params);
|
||||
if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, getInternalParams());
|
||||
else if (simplePlotFunction) func=simplePlotFunction;
|
||||
|
||||
const double ymin=parent->getYMin();
|
||||
@ -654,48 +617,6 @@ QPen JKQTPXFunctionLineGraph::getErrorLinePen(JKQTPEnhancedPainter& painter) con
|
||||
}
|
||||
|
||||
|
||||
void JKQTPXFunctionLineGraph::setParams(const QVector<double> ¶ms)
|
||||
{
|
||||
iparams=params;
|
||||
setParams(&iparams);
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setCopiedParams(const double *params, int N)
|
||||
{
|
||||
QVector<double> v;
|
||||
for (int i=0; i<N; i++) { v<<params[i]; }
|
||||
setParams(v);
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setParamsV(double p1) {
|
||||
QVector<double> p;
|
||||
p<<p1;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setParamsV(double p1, double p2) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setParamsV(double p1, double p2, double p3) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2<<p3;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setParamsV(double p1, double p2, double p3, double p4) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2<<p3<<p4;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setParamsV(double p1, double p2, double p3, double p4, double p5) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2<<p3<<p4<<p5;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setErrorParams(const QVector<double> &errorParams)
|
||||
{
|
||||
@ -703,20 +624,6 @@ void JKQTPXFunctionLineGraph::setErrorParams(const QVector<double> &errorParams)
|
||||
setErrorParams(&ierrorparams);
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setParameterColumn(int __value)
|
||||
{
|
||||
this->parameterColumn = __value;
|
||||
}
|
||||
|
||||
int JKQTPXFunctionLineGraph::getParameterColumn() const
|
||||
{
|
||||
return this->parameterColumn;
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setParameterColumn(size_t __value) {
|
||||
this->parameterColumn = static_cast<int>(__value);
|
||||
}
|
||||
|
||||
void JKQTPXFunctionLineGraph::setErrorParameterColumn(int __value)
|
||||
{
|
||||
this->errorParameterColumn = __value;
|
||||
@ -784,14 +691,13 @@ double JKQTPXFunctionLineGraph::getErrorLineWidth() const
|
||||
void JKQTPXFunctionLineGraph::setSpecialFunction(JKQTPXFunctionLineGraph::SpecialFunction function)
|
||||
{
|
||||
if (function==JKQTPXFunctionLineGraph::Polynomial) {
|
||||
setPlotFunctionFunctor([](double x, void* param) {
|
||||
setPlotFunctionFunctor([](double x, const QVector<double>& param) {
|
||||
double res=0;
|
||||
QVector<double>* d=static_cast<QVector<double>*>(param);
|
||||
if (d && d->size()>0) {
|
||||
res=d->value(0,0);
|
||||
if (param.size()>0) {
|
||||
res=param.value(0,0);
|
||||
double xx=x;
|
||||
for (int i=1; i<d->size(); i++) {
|
||||
res=res+d->value(i,0)*xx;
|
||||
for (int i=1; i<param.size(); i++) {
|
||||
res=res+param.value(i,0)*xx;
|
||||
xx=xx*x;
|
||||
}
|
||||
}
|
||||
@ -799,30 +705,23 @@ void JKQTPXFunctionLineGraph::setSpecialFunction(JKQTPXFunctionLineGraph::Specia
|
||||
return res;
|
||||
});
|
||||
}
|
||||
else if (function==JKQTPXFunctionLineGraph::Exponential) setPlotFunctionFunctor([](double x, void* param) {
|
||||
else if (function==JKQTPXFunctionLineGraph::Exponential) setPlotFunctionFunctor([](double x, const QVector<double>& param) {
|
||||
double res=0;
|
||||
QVector<double>* d=static_cast<QVector<double>*>(param);
|
||||
if (d) {
|
||||
if (d->size()>=3) {
|
||||
res=d->value(0,0)+d->value(1,0)*exp(x/d->value(2,0));
|
||||
} else if (d->size()>=2) {
|
||||
res=d->value(0,0)*exp(x/d->value(1,0));
|
||||
}
|
||||
if (param.size()>=3) {
|
||||
res=param.value(0,0)+param.value(1,0)*exp(x/param.value(2,0));
|
||||
} else if (param.size()>=2) {
|
||||
res=param.value(0,0)*exp(x/param.value(1,0));
|
||||
}
|
||||
return res;
|
||||
});
|
||||
else if (function==JKQTPXFunctionLineGraph::PowerLaw) setPlotFunctionFunctor([](double x, void* param) {
|
||||
else if (function==JKQTPXFunctionLineGraph::PowerLaw) setPlotFunctionFunctor([](double x, const QVector<double>& param) {
|
||||
double res=0;
|
||||
QVector<double>* d=static_cast<QVector<double>*>(param);
|
||||
if (d) {
|
||||
if (d->size()>=3) {
|
||||
res=d->value(0,0)+d->value(1,0)*pow(x, d->value(2,1));
|
||||
} else if (d->size()>=2) {
|
||||
res=d->value(0,0)*pow(x, d->value(1,1));
|
||||
} else if (d->size()>=1) {
|
||||
res=pow(x, d->value(0,1));
|
||||
}
|
||||
|
||||
if (param.size()>=3) {
|
||||
res=param.value(0,0)+param.value(1,0)*pow(x, param.value(2,1));
|
||||
} else if (param.size()>=2) {
|
||||
res=param.value(0,0)*pow(x, param.value(1,1));
|
||||
} else if (param.size()>=1) {
|
||||
res=pow(x, param.value(0,1));
|
||||
}
|
||||
return res;
|
||||
});
|
||||
@ -834,9 +733,6 @@ JKQTPXFunctionLineGraph::SpecialFunction JKQTPXFunctionLineGraph::getFunctionTyp
|
||||
return functionType;
|
||||
}
|
||||
|
||||
QVector<double> JKQTPXFunctionLineGraph::getInternalParams() const {
|
||||
return iparams;
|
||||
}
|
||||
QVector<double> JKQTPXFunctionLineGraph::getInternalErrorParams() const {
|
||||
return ierrorparams;
|
||||
}
|
||||
@ -910,6 +806,6 @@ void *JKQTPXFunctionLineGraph::getErrorParams() const
|
||||
|
||||
bool JKQTPXFunctionLineGraph::usesColumn(int c) const
|
||||
{
|
||||
return (c==parameterColumn)||(c==errorParameterColumn);
|
||||
return JKQTPEvaluatedFunctionWithParamsGraphBase::usesColumn(c)||(c==errorParameterColumn);
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
influence its result. Parameters are given as a pointer to some memory location. The function has to
|
||||
know on its own how to interpret these.
|
||||
*/
|
||||
typedef std::function<double(double, void*)> jkqtpPlotFunctionType;
|
||||
typedef std::function<double(double, const QVector<double>&)> jkqtpPlotFunctionType;
|
||||
|
||||
/*! \brief simplified type of functions (without parameters) that may be plotted by JKQTPXFunctionLineGraph and JKQTPYFunctionLineGraph
|
||||
\ingroup jkqtplotter_functiongraphs
|
||||
@ -74,7 +74,7 @@ typedef std::function<double(double)> jkqtpSimplePlotFunctionType;
|
||||
|
||||
\see \ref JKQTPlotterFunctionPlots, JKQTPAdaptiveFunctionGraphEvaluator, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph, jkqtpstatAddPolyFit(), jkqtpstatAddWeightedRegression(), jkqtpstatAddRobustIRLSRegression(), jkqtpstatAddRegression(), jkqtpstatAddLinearWeightedRegression(), jkqtpstatAddRobustIRLSLinearRegression(), jkqtpstatAddLinearRegression()
|
||||
*/
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunctionGraphBase, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunctionWithParamsGraphBase, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@ -158,27 +158,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
|
||||
/*! \copydoc simplePlotFunction */ \
|
||||
virtual jkqtpSimplePlotFunctionType getSimplePlotFunction () const;
|
||||
|
||||
/*! \copydoc params */
|
||||
virtual void setParams(void* __value);
|
||||
/*! \copydoc params */
|
||||
void* getParams() const;
|
||||
/** \brief sets the params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
|
||||
virtual void setParams(const QVector<double>& params);
|
||||
/** \brief sets the params from a copy of the given array of length \a N */
|
||||
void setCopiedParams(const double* params, int N);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1} */
|
||||
void setParamsV(double p1);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2} */
|
||||
void setParamsV(double p1, double p2);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3} */
|
||||
void setParamsV(double p1, double p2, double p3);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4} */
|
||||
void setParamsV(double p1, double p2, double p3, double p4);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4,p5} */
|
||||
void setParamsV(double p1, double p2, double p3, double p4, double p5);
|
||||
|
||||
/** \brief returns the currently set internal parameter vector */
|
||||
QVector<double> getInternalParams() const;
|
||||
/** \brief returns the currently set internal parameter vector */
|
||||
QVector<double> getInternalErrorParams() const;
|
||||
|
||||
@ -220,13 +200,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
|
||||
void *getErrorParams() const;
|
||||
/** \brief sets the error params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
|
||||
void setErrorParams(const QVector<double>& errorParams);
|
||||
|
||||
/*! \copydoc parameterColumn */
|
||||
void setParameterColumn(int __value);
|
||||
/*! \copydoc parameterColumn */
|
||||
int getParameterColumn() const;
|
||||
/*! \copydoc parameterColumn */
|
||||
void setParameterColumn (size_t __value);
|
||||
/*! \copydoc errorParameterColumn */
|
||||
void setErrorParameterColumn(int __value);
|
||||
/*! \copydoc errorParameterColumn */
|
||||
@ -264,16 +237,14 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
|
||||
/** \brief returns, which special function is set (or if any is set) */
|
||||
SpecialFunction getFunctionType() const;
|
||||
protected:
|
||||
/** \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() override;
|
||||
|
||||
|
||||
/** \brief fill the data array with data from the function plotFunction */
|
||||
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 */
|
||||
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 */
|
||||
int parameterColumn;
|
||||
/** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the error plot function */
|
||||
int errorParameterColumn;
|
||||
|
||||
@ -287,8 +258,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
|
||||
jkqtpSimplePlotFunctionType simplePlotFunction;
|
||||
/** \brief indicates whether a special function is set (and if so, which one), or a user-supplied function */
|
||||
SpecialFunction functionType;
|
||||
/** \brief pointer to the parameters supplied to the plotting funtion */
|
||||
void* params;
|
||||
|
||||
|
||||
/** \brief indicates whether an error polygon should be drawn */
|
||||
@ -317,8 +286,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
|
||||
|
||||
QBrush getErrorBrush(JKQTPEnhancedPainter& painter) const;
|
||||
QPen getErrorLinePen(JKQTPEnhancedPainter &painter) const;
|
||||
/** \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;
|
||||
/** \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;
|
||||
};
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||
#include "jkqtplotter/jkqtplotter.h"
|
||||
|
||||
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||||
|
||||
|
||||
|
||||
@ -131,4 +132,156 @@ bool JKQTPEvaluatedFunctionGraphBase::getDisplaySamplePoints() const
|
||||
return this->displaySamplePoints;
|
||||
}
|
||||
|
||||
bool JKQTPEvaluatedFunctionGraphBase::getXMinMax(double &minx, double &maxx, double &smallestGreaterZero)
|
||||
{
|
||||
if (data.size()==0) createPlotData();
|
||||
if (data.size()>0){
|
||||
bool start=true;
|
||||
minx=0;
|
||||
maxx=0;
|
||||
smallestGreaterZero=0;
|
||||
|
||||
for (auto const& d: data) {
|
||||
if (JKQTPIsOKFloat(d.x())) {
|
||||
if (start || d.x()>maxx) maxx=d.x();
|
||||
if (start || d.x()<minx) minx=d.x();
|
||||
double xvsgz;
|
||||
xvsgz=d.x(); SmallestGreaterZeroCompare_xvsgz();
|
||||
start=false;
|
||||
}
|
||||
}
|
||||
return !start;
|
||||
} else {
|
||||
smallestGreaterZero=minx=maxx=0; return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool JKQTPEvaluatedFunctionGraphBase::getYMinMax(double &miny, double &maxy, double &smallestGreaterZero)
|
||||
{
|
||||
if (data.size()==0) createPlotData();
|
||||
if (data.size()>0){
|
||||
bool start=true;
|
||||
miny=0;
|
||||
maxy=0;
|
||||
smallestGreaterZero=0;
|
||||
|
||||
for (auto const& d: data) {
|
||||
if (JKQTPIsOKFloat(d.y())) {
|
||||
if (start || d.y()>maxy) maxy=d.y();
|
||||
if (start || d.y()<miny) miny=d.y();
|
||||
double xvsgz;
|
||||
xvsgz=d.x(); SmallestGreaterZeroCompare_xvsgz();
|
||||
start=false;
|
||||
}
|
||||
}
|
||||
return !start;
|
||||
} else {
|
||||
smallestGreaterZero=miny=maxy=0; return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
JKQTPEvaluatedFunctionWithParamsGraphBase::JKQTPEvaluatedFunctionWithParamsGraphBase(JKQTBasePlotter *parent):
|
||||
parameterColumn(-1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JKQTPEvaluatedFunctionWithParamsGraphBase::JKQTPEvaluatedFunctionWithParamsGraphBase(JKQTPlotter *parent):
|
||||
JKQTPEvaluatedFunctionWithParamsGraphBase(parent->getPlotter())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JKQTPEvaluatedFunctionWithParamsGraphBase::~JKQTPEvaluatedFunctionWithParamsGraphBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::collectParameters()
|
||||
{
|
||||
if (parent && parameterColumn>=0) {
|
||||
iparams.clear();
|
||||
JKQTPDatastore* datastore=parent->getDatastore();
|
||||
int imin=0;
|
||||
int imax=static_cast<int>(datastore->getRows(parameterColumn));
|
||||
|
||||
for (int i=imin; i<imax; i++) {
|
||||
double xv=datastore->get(parameterColumn,i);
|
||||
iparams<<xv;
|
||||
}
|
||||
int i=iparams.size()-1;
|
||||
while (i>=0 && !JKQTPIsOKFloat(iparams[i])) {
|
||||
iparams.remove(i,1);
|
||||
i--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParams(const QVector<double> ¶ms)
|
||||
{
|
||||
iparams=params;
|
||||
}
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::setCopiedParams(const double *params, int N)
|
||||
{
|
||||
QVector<double> v;
|
||||
for (int i=0; i<N; i++) { v<<params[i]; }
|
||||
setParams(v);
|
||||
}
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1) {
|
||||
QVector<double> p;
|
||||
p<<p1;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1, double p2) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1, double p2, double p3) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2<<p3;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1, double p2, double p3, double p4) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2<<p3<<p4;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1, double p2, double p3, double p4, double p5) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2<<p3<<p4<<p5;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParameterColumn(int __value)
|
||||
{
|
||||
this->parameterColumn = __value;
|
||||
}
|
||||
|
||||
int JKQTPEvaluatedFunctionWithParamsGraphBase::getParameterColumn() const
|
||||
{
|
||||
return this->parameterColumn;
|
||||
}
|
||||
|
||||
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParameterColumn(size_t __value) {
|
||||
this->parameterColumn = static_cast<int>(__value);
|
||||
}
|
||||
|
||||
QVector<double> JKQTPEvaluatedFunctionWithParamsGraphBase::getInternalParams() const {
|
||||
return iparams;
|
||||
}
|
||||
|
||||
bool JKQTPEvaluatedFunctionWithParamsGraphBase::usesColumn(int c) const
|
||||
{
|
||||
return (c==parameterColumn);
|
||||
}
|
||||
|
@ -34,67 +34,75 @@
|
||||
|
||||
|
||||
|
||||
/*! \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
|
||||
/** \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 JKQTPEvaluatedFunctionGraphBase: public JKQTPGraph {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
/** \brief class constructor */
|
||||
JKQTPEvaluatedFunctionGraphBase(JKQTBasePlotter* parent=nullptr);
|
||||
explicit JKQTPEvaluatedFunctionGraphBase(JKQTBasePlotter* parent=nullptr);
|
||||
|
||||
/** \brief class constructor */
|
||||
JKQTPEvaluatedFunctionGraphBase(JKQTPlotter* parent);
|
||||
explicit JKQTPEvaluatedFunctionGraphBase(JKQTPlotter* parent);
|
||||
|
||||
/** \brief class destructor */
|
||||
virtual ~JKQTPEvaluatedFunctionGraphBase() ;
|
||||
|
||||
/** \brief get the maximum and minimum x-value of the graph
|
||||
*
|
||||
* This functions returns 0 for both parameters, so that the plotter uses the predefined
|
||||
* min and max values.
|
||||
*/
|
||||
virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) override;
|
||||
/** \brief get the maximum and minimum y-value of the graph
|
||||
*/
|
||||
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
||||
|
||||
/*! \copydoc minSamples */
|
||||
|
||||
/** \copydoc minSamples */
|
||||
unsigned int getMinSamples() const;
|
||||
/*! \copydoc maxRefinementDegree */
|
||||
/** \copydoc maxRefinementDegree */
|
||||
unsigned int getMaxRefinementDegree() const;
|
||||
/*! \copydoc slopeTolerance */
|
||||
/** \copydoc slopeTolerance */
|
||||
double getSlopeTolerance() const;
|
||||
/*! \copydoc minPixelPerSample */
|
||||
/** \copydoc minPixelPerSample */
|
||||
double getMinPixelPerSample() const;
|
||||
/*! \copydoc dataCleanupMaxAllowedAngleDegree */
|
||||
/** \copydoc dataCleanupMaxAllowedAngleDegree */
|
||||
double getDataCleanupMaxAllowedAngleDegree() const;
|
||||
/*! \copydoc displaySamplePoints */
|
||||
/** \copydoc displaySamplePoints */
|
||||
bool getDisplaySamplePoints() const;
|
||||
public slots:
|
||||
/*! \copydoc minSamples */
|
||||
/** \copydoc minSamples */
|
||||
void setMinSamples(const unsigned int & __value);
|
||||
/*! \copydoc maxRefinementDegree */
|
||||
/** \copydoc maxRefinementDegree */
|
||||
void setMaxRefinementDegree(const unsigned int & __value);
|
||||
/*! \copydoc slopeTolerance */
|
||||
/** \copydoc slopeTolerance */
|
||||
void setSlopeTolerance(double __value);
|
||||
/*! \copydoc minPixelPerSample */
|
||||
/** \copydoc minPixelPerSample */
|
||||
void setMinPixelPerSample(double __value);
|
||||
/*! \copydoc dataCleanupMaxAllowedAngleDegree */
|
||||
/** \copydoc dataCleanupMaxAllowedAngleDegree */
|
||||
void setDataCleanupMaxAllowedAngleDegree(double __value);
|
||||
/*! \copydoc displaySamplePoints */
|
||||
/** \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;
|
||||
|
||||
@ -125,4 +133,61 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPEvaluatedFunctionGraphBase: public JKQTPGraph
|
||||
};
|
||||
|
||||
|
||||
/** \brief extends JKQTPEvaluatedFunctionGraphBase with a set of functions that support function parameters
|
||||
* \ingroup jkqtplotter_functiongraphs
|
||||
*
|
||||
* \see JKQTPEvaluatedFunctionGraphBase
|
||||
*/
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPEvaluatedFunctionWithParamsGraphBase: public JKQTPEvaluatedFunctionGraphBase {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/** \brief class constructor */
|
||||
explicit JKQTPEvaluatedFunctionWithParamsGraphBase(JKQTBasePlotter* parent=nullptr);
|
||||
/** \brief class constructor */
|
||||
explicit JKQTPEvaluatedFunctionWithParamsGraphBase(JKQTPlotter* parent);
|
||||
/** \brief class destructor */
|
||||
virtual ~JKQTPEvaluatedFunctionWithParamsGraphBase();
|
||||
|
||||
|
||||
/** \brief sets the params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
|
||||
virtual void setParams(const QVector<double>& params);
|
||||
/** \brief sets the params from a copy of the given array of length \a N */
|
||||
void setCopiedParams(const double* params, int N);
|
||||
|
||||
/** \brief returns the currently set internal parameter vector */
|
||||
QVector<double> getInternalParams() const;
|
||||
/** \copydoc parameterColumn */
|
||||
int getParameterColumn() const;
|
||||
|
||||
/** \copydoc JKQTPGraph::usesColumn() */
|
||||
virtual bool usesColumn(int c) const override;
|
||||
|
||||
public slots:
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1} */
|
||||
void setParamsV(double p1);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2} */
|
||||
void setParamsV(double p1, double p2);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3} */
|
||||
void setParamsV(double p1, double p2, double p3);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4} */
|
||||
void setParamsV(double p1, double p2, double p3, double p4);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4,p5} */
|
||||
void setParamsV(double p1, double p2, double p3, double p4, double p5);
|
||||
|
||||
/** \copydoc parameterColumn */
|
||||
void setParameterColumn(int __value);
|
||||
/** \copydoc parameterColumn */
|
||||
void setParameterColumn (size_t __value);
|
||||
protected:
|
||||
/** \brief ensure that current function parameters for a plot function (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams */
|
||||
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 */
|
||||
int parameterColumn;
|
||||
|
||||
/** \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;
|
||||
};
|
||||
|
||||
|
||||
#endif // jkqtpevaluatedfunctionbase_H
|
||||
|
@ -29,22 +29,18 @@
|
||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||
#include "jkqtplotter/jkqtplotter.h"
|
||||
|
||||
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||||
|
||||
|
||||
|
||||
|
||||
JKQTPXYFunctionLineGraph::JKQTPXYFunctionLineGraph(JKQTBasePlotter* parent):
|
||||
JKQTPEvaluatedFunctionGraphBase(parent)
|
||||
JKQTPEvaluatedFunctionWithParamsGraphBase(parent)
|
||||
{
|
||||
tmin=0.0;
|
||||
tmax=1.0;
|
||||
params=nullptr;
|
||||
|
||||
initLineStyle(parent, parentPlotStyle);
|
||||
|
||||
parameterColumn=-1;
|
||||
|
||||
}
|
||||
|
||||
JKQTPXYFunctionLineGraph::JKQTPXYFunctionLineGraph(JKQTPlotter* parent):
|
||||
@ -166,19 +162,6 @@ jkqtpSimpleParametricCurveFunctionType JKQTPXYFunctionLineGraph::getSimplePlotFu
|
||||
return simplePlotFunction;
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setParams(void *__value)
|
||||
{
|
||||
if (this->params != __value) {
|
||||
this->params = __value;
|
||||
data.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void *JKQTPXYFunctionLineGraph::getParams() const
|
||||
{
|
||||
return this->params;
|
||||
}
|
||||
|
||||
|
||||
void JKQTPXYFunctionLineGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
@ -196,53 +179,6 @@ QColor JKQTPXYFunctionLineGraph::getKeyLabelColor() const {
|
||||
return getLineColor();
|
||||
}
|
||||
|
||||
bool JKQTPXYFunctionLineGraph::getXMinMax(double &minx, double &maxx, double &smallestGreaterZero)
|
||||
{
|
||||
if (data.size()==0) createPlotData();
|
||||
if (data.size()>0){
|
||||
bool start=true;
|
||||
minx=0;
|
||||
maxx=0;
|
||||
smallestGreaterZero=0;
|
||||
|
||||
for (auto const& d: data) {
|
||||
if (JKQTPIsOKFloat(d.x())) {
|
||||
if (start || d.x()>maxx) maxx=d.x();
|
||||
if (start || d.x()<minx) minx=d.x();
|
||||
double xvsgz;
|
||||
xvsgz=d.x(); SmallestGreaterZeroCompare_xvsgz();
|
||||
start=false;
|
||||
}
|
||||
}
|
||||
return !start;
|
||||
} else {
|
||||
smallestGreaterZero=minx=maxx=0; return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool JKQTPXYFunctionLineGraph::getYMinMax(double &miny, double &maxy, double &smallestGreaterZero)
|
||||
{
|
||||
if (data.size()==0) createPlotData();
|
||||
if (data.size()>0){
|
||||
bool start=true;
|
||||
miny=0;
|
||||
maxy=0;
|
||||
smallestGreaterZero=0;
|
||||
|
||||
for (auto const& d: data) {
|
||||
if (JKQTPIsOKFloat(d.y())) {
|
||||
if (start || d.y()>maxy) maxy=d.y();
|
||||
if (start || d.y()<miny) miny=d.y();
|
||||
double xvsgz;
|
||||
xvsgz=d.x(); SmallestGreaterZeroCompare_xvsgz();
|
||||
start=false;
|
||||
}
|
||||
}
|
||||
return !start;
|
||||
} else {
|
||||
smallestGreaterZero=miny=maxy=0; return false;
|
||||
}
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::createPlotData(bool collectParams) {
|
||||
#ifdef JKQTBP_AUTOTIMER
|
||||
@ -255,7 +191,7 @@ void JKQTPXYFunctionLineGraph::createPlotData(bool collectParams) {
|
||||
if (!plotFunction && !simplePlotFunction) return;
|
||||
|
||||
jkqtpSimpleParametricCurveFunctionType func;
|
||||
if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, params);
|
||||
if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, getInternalParams());
|
||||
else if (simplePlotFunction) func=simplePlotFunction;
|
||||
|
||||
jkqtpSimpleParametricCurveFunctionType fTransformedFunc= std::bind([&](const JKQTPPlotElement* plot, double t) -> QPointF { return plot->transform(func(t)); }, this, std::placeholders::_1);
|
||||
@ -265,33 +201,6 @@ void JKQTPXYFunctionLineGraph::createPlotData(bool collectParams) {
|
||||
data=JKQTPSimplyfyLineSegemnts(data, dataCleanupMaxAllowedAngleDegree);
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::collectParameters()
|
||||
{
|
||||
if (parent && parameterColumn>=0) {
|
||||
iparams.clear();
|
||||
JKQTPDatastore* datastore=parent->getDatastore();
|
||||
int imin=0;
|
||||
int imax=static_cast<int>(datastore->getRows(parameterColumn));
|
||||
|
||||
for (int i=imin; i<imax; i++) {
|
||||
double xv=datastore->get(parameterColumn,i);
|
||||
iparams<<xv;
|
||||
}
|
||||
//qDebug()<<"iparams_beforeclean:";
|
||||
//for (int i=0; i<iparams.size(); i++) qDebug()<<iparams[i];
|
||||
int i=iparams.size()-1;
|
||||
while (i>=0 && !JKQTPIsOKFloat(iparams[i])) {
|
||||
iparams.remove(i,1);
|
||||
i--;
|
||||
}
|
||||
|
||||
//qDebug()<<"iparams:";
|
||||
//for (i=0; i<iparams.size(); i++) qDebug()<<iparams[i];
|
||||
|
||||
params=&iparams;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JKQTPXYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||
#ifdef JKQTBP_AUTOTIMER
|
||||
@ -328,77 +237,6 @@ void JKQTPXYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setParams(const QVector<double> ¶ms)
|
||||
{
|
||||
iparams=params;
|
||||
setParams(&iparams);
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setCopiedParams(const double *params, int N)
|
||||
{
|
||||
QVector<double> v;
|
||||
for (int i=0; i<N; i++) { v<<params[i]; }
|
||||
setParams(v);
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setParamsV(double p1) {
|
||||
QVector<double> p;
|
||||
p<<p1;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setParamsV(double p1, double p2) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setParamsV(double p1, double p2, double p3) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2<<p3;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setParamsV(double p1, double p2, double p3, double p4) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2<<p3<<p4;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setParamsV(double p1, double p2, double p3, double p4, double p5) {
|
||||
QVector<double> p;
|
||||
p<<p1<<p2<<p3<<p4<<p5;
|
||||
setParams(p);
|
||||
}
|
||||
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setParameterColumn(int __value)
|
||||
{
|
||||
this->parameterColumn = __value;
|
||||
}
|
||||
|
||||
int JKQTPXYFunctionLineGraph::getParameterColumn() const
|
||||
{
|
||||
return this->parameterColumn;
|
||||
}
|
||||
|
||||
void JKQTPXYFunctionLineGraph::setParameterColumn(size_t __value) {
|
||||
this->parameterColumn = static_cast<int>(__value);
|
||||
}
|
||||
|
||||
|
||||
QVector<double> JKQTPXYFunctionLineGraph::getInternalParams() const {
|
||||
return iparams;
|
||||
}
|
||||
|
||||
|
||||
bool JKQTPXYFunctionLineGraph::usesColumn(int c) const
|
||||
{
|
||||
return (c==parameterColumn);
|
||||
}
|
||||
|
||||
double JKQTPXYFunctionLineGraph::getTMin() const
|
||||
{
|
||||
return tmin;
|
||||
|
@ -43,7 +43,7 @@
|
||||
influence its result. Parameters are given as a pointer to some memory location. The function has to
|
||||
know on its own how to interpret these.
|
||||
*/
|
||||
typedef std::function<QPointF(double, void*)> jkqtpParametricCurveFunctionType;
|
||||
typedef std::function<QPointF(double, const QVector<double>)> jkqtpParametricCurveFunctionType;
|
||||
|
||||
/*! \brief simplified type of functions (without parameters) that may be plotted by JKQTPXYFunctionLineGraph
|
||||
\ingroup jkqtplotter_functiongraphs
|
||||
@ -88,7 +88,7 @@ typedef std::function<QPointF(double)> jkqtpSimpleParametricCurveFunctionType;
|
||||
|
||||
\see \ref JKQTPlotterEvalCurves , JKQTPAdaptiveFunctionGraphEvaluator, JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph
|
||||
*/
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunctionGraphBase, public JKQTPGraphLineStyleMixin {
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunctionWithParamsGraphBase, public JKQTPGraphLineStyleMixin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@ -124,16 +124,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunc
|
||||
/** \brief returns the color to be used for the key label */
|
||||
virtual QColor getKeyLabelColor() const override;
|
||||
|
||||
/** \brief get the maximum and minimum x-value of the graph
|
||||
*
|
||||
* This functions returns 0 for both parameters, so that the plotter uses the predefined
|
||||
* min and max values.
|
||||
*/
|
||||
virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) override;
|
||||
/** \brief get the maximum and minimum y-value of the graph
|
||||
*/
|
||||
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
||||
|
||||
/** \brief sets a functor to be plotted
|
||||
*
|
||||
* \see plotFunction
|
||||
@ -159,41 +149,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunc
|
||||
/*! \copydoc simplePlotFunction */ \
|
||||
virtual jkqtpSimpleParametricCurveFunctionType getSimplePlotFunction () const;
|
||||
|
||||
/*! \copydoc params */
|
||||
virtual void setParams(void* __value);
|
||||
/*! \copydoc params */
|
||||
void* getParams() const;
|
||||
/** \brief sets the params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
|
||||
virtual void setParams(const QVector<double>& params);
|
||||
/** \brief sets the params from a copy of the given array of length \a N */
|
||||
void setCopiedParams(const double* params, int N);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1} */
|
||||
void setParamsV(double p1);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2} */
|
||||
void setParamsV(double p1, double p2);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3} */
|
||||
void setParamsV(double p1, double p2, double p3);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4} */
|
||||
void setParamsV(double p1, double p2, double p3, double p4);
|
||||
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4,p5} */
|
||||
void setParamsV(double p1, double p2, double p3, double p4, double p5);
|
||||
|
||||
/** \brief returns the currently set internal parameter vector */
|
||||
QVector<double> getInternalParams() const;
|
||||
|
||||
|
||||
|
||||
/*! \copydoc parameterColumn */
|
||||
void setParameterColumn(int __value);
|
||||
/*! \copydoc parameterColumn */
|
||||
int getParameterColumn() const;
|
||||
/*! \copydoc parameterColumn */
|
||||
void setParameterColumn (size_t __value);
|
||||
|
||||
|
||||
/** \copydoc JKQTPGraph::usesColumn() */
|
||||
virtual bool usesColumn(int c) const override;
|
||||
|
||||
|
||||
/*! \copydoc tmin */
|
||||
double getTMin() const;
|
||||
@ -216,21 +171,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunc
|
||||
double tmax;
|
||||
/** \brief fill the data array with data from the function plotFunction */
|
||||
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 */
|
||||
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 */
|
||||
int parameterColumn;
|
||||
|
||||
/** \brief the function to be plotted */
|
||||
jkqtpParametricCurveFunctionType plotFunction;
|
||||
/** \brief a simple function to be plotted, simplified form without parameters */
|
||||
jkqtpSimpleParametricCurveFunctionType simplePlotFunction;
|
||||
/** \brief pointer to the parameters supplied to the plotting funtion */
|
||||
void* params;
|
||||
|
||||
/** \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;
|
||||
};
|
||||
|
||||
#endif // jkqtpevaluatedparametriccurve_H
|
||||
|
@ -91,13 +91,10 @@ void JKQTPXParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
|
||||
}
|
||||
fdata.varcount=0;
|
||||
try {
|
||||
QVector<double>* parameters=static_cast<QVector<double>*>(params);
|
||||
if (parameters) {
|
||||
for (int i=0; i<parameters->size(); i++) {
|
||||
fdata.parser->addVariableDouble(std::string("p")+jkqtp_inttostr(fdata.varcount+1), parameters->at(i));
|
||||
for (const auto& p: getInternalParams()) {
|
||||
fdata.parser->addVariableDouble(std::string("p")+jkqtp_inttostr(fdata.varcount+1), p);
|
||||
fdata.varcount=fdata.varcount+1;
|
||||
}
|
||||
}
|
||||
fdata.parser->addVariableDouble(std::string("x"), 0.0);
|
||||
if (fdata.node) delete fdata.node;
|
||||
//qint64 t=timer.elapsed();
|
||||
@ -150,7 +147,7 @@ void JKQTPXParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
|
||||
}
|
||||
|
||||
|
||||
double JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunction(double x, void* /*data*/, JKQTPXParsedFunctionLineGraphFunctionData *fdata) {
|
||||
double JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunction(double x, const QVector<double>& /*data*/, JKQTPXParsedFunctionLineGraphFunctionData *fdata) {
|
||||
JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunctionData* d=fdata;//static_cast<JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunctionData*>(data);
|
||||
if (d && d->parser && d->node) {
|
||||
try {
|
||||
@ -267,13 +264,10 @@ void JKQTPYParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
|
||||
}
|
||||
fdata.varcount=0;
|
||||
try {
|
||||
QVector<double>* parameters=static_cast<QVector<double>*>(params);
|
||||
if (parameters) {
|
||||
for (int i=0; i<parameters->size(); i++) {
|
||||
fdata.parser->addVariableDouble(std::string("p")+jkqtp_inttostr(fdata.varcount+1), parameters->at(i));
|
||||
for (const auto& p: getInternalParams()) {
|
||||
fdata.parser->addVariableDouble(std::string("p")+jkqtp_inttostr(fdata.varcount+1), p);
|
||||
fdata.varcount=fdata.varcount+1;
|
||||
}
|
||||
}
|
||||
fdata.parser->addVariableDouble(std::string("x"), 0.0);
|
||||
fdata.parser->addVariableDouble(std::string("y"), 0.0);
|
||||
if (fdata.node) delete fdata.node;
|
||||
@ -327,7 +321,7 @@ void JKQTPYParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
|
||||
qDebug()<<"refined to "<<count<<" daatapoints";*/
|
||||
}
|
||||
|
||||
double JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunction(double x, void* /*data*/, JKQTPYParsedFunctionLineGraphFunctionData *fdata) {
|
||||
double JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunction(double x, const QVector<double> & /*data*/, JKQTPYParsedFunctionLineGraphFunctionData *fdata) {
|
||||
JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunctionData* d=fdata;//static_cast<JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunctionData*>(data);
|
||||
if (d && d->parser && d->node) {
|
||||
try {
|
||||
|
@ -97,7 +97,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXParsedFunctionLineGraph: public JKQTPXFunctio
|
||||
virtual void createPlotData(bool collectParams=true) override;
|
||||
|
||||
/** \brief implements the actual plot function */
|
||||
static double JKQTPXParsedFunctionLineGraphFunction(double x, void *data, JKQTPXParsedFunctionLineGraphFunctionData* fdata) ;
|
||||
static double JKQTPXParsedFunctionLineGraphFunction(double x, const QVector<double> &data, JKQTPXParsedFunctionLineGraphFunctionData* fdata) ;
|
||||
};
|
||||
|
||||
|
||||
@ -165,6 +165,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPYParsedFunctionLineGraph: public JKQTPYFunctio
|
||||
/** \brief fill the data array with data from the function plotFunction */
|
||||
virtual void createPlotData(bool collectParams=true) override;
|
||||
/** \brief implements the actual plot function */
|
||||
static double JKQTPYParsedFunctionLineGraphFunction(double x, void *data, JKQTPYParsedFunctionLineGraphFunctionData* fdata);
|
||||
static double JKQTPYParsedFunctionLineGraphFunction(double x, const QVector<double>& data, JKQTPYParsedFunctionLineGraphFunctionData* fdata);
|
||||
};
|
||||
#endif // jkqtpgraphsparsedfunction_H
|
||||
|
Loading…
Reference in New Issue
Block a user