2020-09-05 05:41:23 +08:00
/*
2022-07-19 19:40:43 +08:00
Copyright ( c ) 2020 - 2022 Jan W . Krieger ( < jan @ jkrieger . de > )
2020-09-05 05:41:23 +08:00
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/>.
*/
2022-04-25 04:07:39 +08:00
# ifndef jkqtpevaluatedparametriccurve_H
# define jkqtpevaluatedparametriccurve_H
2020-09-05 05:41:23 +08:00
# include <QString>
# include <QPainter>
# include <QPair>
# include "jkqtplotter/graphs/jkqtpscatter.h"
# include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
# include "jkqtplotter/jkqtplotter_imexport.h"
# include "jkqtcommon/jkqtpgeometrytools.h"
2020-09-05 19:14:46 +08:00
# include "jkqtplotter/graphs/jkqtpevaluatedfunctionbase.h"
2020-09-05 05:41:23 +08:00
# include <functional>
2020-09-08 02:57:25 +08:00
/** \brief Base class for line plots where the data is taken from a user supplied function \f$ [x,y]=f(t) \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
*
* 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 JKQTPXYFunctionLineGraphBase for a concrete implementation with C + + - functors as functions
*/
class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraphBase : public JKQTPEvaluatedFunctionGraphBase , public JKQTPGraphLineStyleMixin {
Q_OBJECT
public :
/** \brief class constructor */
JKQTPXYFunctionLineGraphBase ( JKQTBasePlotter * parent = nullptr ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraphBase ( JKQTPlotter * parent ) ;
2020-09-09 02:15:33 +08:00
/** \brief class constructor */
JKQTPXYFunctionLineGraphBase ( double tmin_ , double tmax_ , JKQTBasePlotter * parent ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraphBase ( double tmin_ , double tmax_ , JKQTPlotter * parent ) ;
2020-09-08 02:57:25 +08:00
/** \brief class destructor */
virtual ~ JKQTPXYFunctionLineGraphBase ( ) override ;
/** \brief plots the graph to the plotter object specified as parent */
virtual void draw ( JKQTPEnhancedPainter & painter ) override ;
/** \brief plots a key marker inside the specified rectangle \a rect */
virtual void drawKeyMarker ( JKQTPEnhancedPainter & painter , QRectF & rect ) override ;
/** \brief returns the color to be used for the key label */
virtual QColor getKeyLabelColor ( ) const override ;
/** \brief returns the t-value range for \f$ [x,y]=f(t), t \in \left[t_\text{min}, t_\text{max}\right] \f$ */
QPair < double , double > getTRange ( ) const ;
/** \copydoc tmin */
double getTMin ( ) const ;
/** \copydoc tmax */
double getTMax ( ) const ;
2023-07-22 20:26:02 +08:00
public Q_SLOTS :
2020-09-08 02:57:25 +08:00
/** \copydoc tmin */
void setTMin ( double val ) ;
/** \copydoc tmax */
void setTMax ( double val ) ;
/** \brief set the t-value range for \f$ [x,y]=f(t), t \in \left[t_\text{min}, t_\text{max}\right] \f$ */
void setTRange ( double tmin_ , double tmax_ ) ;
/** \brief set the t-value range for \f$ [x,y]=f(t), t \in \left[t_\text{min}, t_\text{max}\right] \f$ */
void setTRange ( const QPair < double , double > & range ) ;
protected :
/** \brief lower 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 0
*
* \ see getTMin ( ) , getTMax ( ) , setTMin ( ) , setTMax ( ) , setTRange ( ) , getTRange ( ) */
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
*
* \ see getTMin ( ) , getTMax ( ) , setTMin ( ) , setTMax ( ) , setTRange ( ) , getTRange ( ) */
double tmax ;
} ;
2020-09-05 05:41:23 +08:00
2020-09-08 02:57:25 +08:00
/** \brief type of functions that may be plotted by JKQTPXYFunctionLineGraph
* \ ingroup jkqtplotter_functiongraphs
*
* This is the type of functions \ f $ [ x , y ] = f ( t , \ vec { p } ) \ f $ that may be plottet by JKQTPXYFunctionLineGraph .
* It is possible to supply parameters \ f $ \ vec { p } \ f $ to the function that
* 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 .
2020-09-05 05:41:23 +08:00
*/
2020-09-05 19:47:46 +08:00
typedef std : : function < QPointF ( double , const QVector < double > ) > jkqtpParametricCurveFunctionType ;
2020-09-05 05:41:23 +08:00
2020-09-08 02:57:25 +08:00
/** \brief simplified type of functions (without parameters) that may be plotted by JKQTPXYFunctionLineGraph
* \ ingroup jkqtplotter_functiongraphs
*
* This is the type of functions \ f $ [ x , y ] = f ( t ) \ f $ that may be plottet by JKQTPXYFunctionLineGraph
* and JKQTPYFunctionLineGraph .
2020-09-05 05:41:23 +08:00
*/
typedef std : : function < QPointF ( double ) > jkqtpSimpleParametricCurveFunctionType ;
2020-09-08 02:57:25 +08:00
/** \brief This implements line plots where the data is taken from a user supplied function \f$ [x,y]=f(t) \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
*
* \ see JKQTPXYFunctionLineGraphBase for details on the used plotting algorithm
*
* The following image shows a Lissajou ' s fugure drawn with this function
*
2022-08-29 04:48:14 +08:00
* \ image html JKQTPXYFunctionLineGraph . png
2020-09-08 02:57:25 +08:00
*
* The source code for this example is :
* \ code
* JKQTPXYFunctionLineGraph * func1 = new JKQTPXYFunctionLineGraph ( plot ) ;
* // here we define the C++-functor for [x,y]=f(t)
* func1 - > setPlotFunctionFunctor ( [ ] ( double t ) - > QPointF {
* const double a = 5 ;
* const double b = 4 ;
* const double delta = JKQTPSTATISTICS_PI / 4.0 ;
* return QPointF ( sin ( a * t + delta ) , sin ( b * t ) ) ;
* } ) ;
* // and define the range over which to evaluate
* func1 - > setTRange ( 0 , 2.0 * JKQTPSTATISTICS_PI ) ;
* \ endcode
*
* The source code for the same example , but using functions that also get a parameter vector :
* \ code
* JKQTPXYFunctionLineGraph * func1 = new JKQTPXYFunctionLineGraph ( plot ) ;
* // here we define the C++-functor for [x,y]=f(t)
* func1 - > setPlotFunctionFunctor ( [ ] ( double t , const QVector < double > & params ) - > QPointF {
* return QPointF ( 3.0 * sin ( params [ 0 ] * t + params [ 2 ] ) + 8.0 , 3.0 * sin ( params [ 1 ] * t ) ) ;
* } ) ;
* // now we define the 3 parameters of the function
* // parameters are a, b, delta, as in the example above (in that order)
* func1 - > setParamsV ( 5 , 4 , JKQTPSTATISTICS_PI / 4.0 ) ;
* // and define the range over which to evaluate
* func1 - > setTRange ( 0 , 2.0 * JKQTPSTATISTICS_PI ) ;
* \ endcode
*
* \ see \ ref JKQTPlotterEvalCurves , JKQTPAdaptiveFunctionGraphEvaluator , JKQTPXFunctionLineGraph , JKQTPYFunctionLineGraph
2020-09-05 05:41:23 +08:00
*/
2020-09-08 02:57:25 +08:00
class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph : public JKQTPXYFunctionLineGraphBase {
2020-09-05 05:41:23 +08:00
Q_OBJECT
public :
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( JKQTBasePlotter * parent = nullptr ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( JKQTPlotter * parent ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( const jkqtpSimpleParametricCurveFunctionType & f , const QString & title , double tmin_ = 0 , double tmax_ = 1 , JKQTBasePlotter * parent = nullptr ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( const jkqtpSimpleParametricCurveFunctionType & f , const QString & title , double tmin_ , double tmax_ , JKQTPlotter * parent ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( jkqtpSimpleParametricCurveFunctionType & & f , const QString & title , double tmin_ = 0 , double tmax_ = 1 , JKQTBasePlotter * parent = nullptr ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( jkqtpSimpleParametricCurveFunctionType & & f , const QString & title , double tmin_ , double tmax_ , JKQTPlotter * parent ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( const jkqtpParametricCurveFunctionType & f , const QString & title , double tmin_ = 0 , double tmax_ = 1 , JKQTBasePlotter * parent = nullptr ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( const jkqtpParametricCurveFunctionType & f , const QString & title , double tmin_ , double tmax_ , JKQTPlotter * parent ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( jkqtpParametricCurveFunctionType & & f , const QString & title , double tmin_ = 0 , double tmax_ = 1 , JKQTBasePlotter * parent = nullptr ) ;
/** \brief class constructor */
JKQTPXYFunctionLineGraph ( jkqtpParametricCurveFunctionType & & f , const QString & title , double tmin_ , double tmax_ , JKQTPlotter * parent ) ;
/** \brief class destructor */
virtual ~ JKQTPXYFunctionLineGraph ( ) override ;
/** \brief sets a functor to be plotted
*
* \ see plotFunction
*/
2020-09-08 02:57:25 +08:00
void setPlotFunctionFunctor ( jkqtpParametricCurveFunctionType & & __value ) ;
2020-09-05 05:41:23 +08:00
/** \brief sets a functor to be plotted
*
* \ see plotFunction
*/
2020-09-08 02:57:25 +08:00
void setPlotFunctionFunctor ( const jkqtpParametricCurveFunctionType & __value ) ;
2020-09-05 05:41:23 +08:00
/** \brief sets a functor to be plotted
*
* \ see simplePlotFunction
*/
2020-09-08 02:57:25 +08:00
void setPlotFunctionFunctor ( jkqtpSimpleParametricCurveFunctionType & & __value ) ;
2020-09-05 05:41:23 +08:00
/** \brief sets a functor to be plotted
*
* \ see simplePlotFunction
*/
2020-09-08 02:57:25 +08:00
void setPlotFunctionFunctor ( const jkqtpSimpleParametricCurveFunctionType & __value ) ;
/** \copydoc plotFunction
*
* \ see isSimplePlotFunction ( ) */
jkqtpParametricCurveFunctionType getPlotFunctionFunctor ( ) const ;
/** \copydoc simplePlotFunction
*
* \ see isSimplePlotFunction ( ) */
jkqtpSimpleParametricCurveFunctionType getSimplePlotFunction ( ) const ;
/** \brief returns whether the plot function was defined as a jkqtpSimpleParametricCurveFunctionType (\c true ) or
* a jkqtpParametricCurveFunctionType ( \ c false ) */
bool isSimplePlotFunction ( ) const ;
2020-09-05 05:41:23 +08:00
protected :
2020-09-08 02:57:25 +08:00
/** \copydoc JKQTPEvaluatedFunctionGraphBase::buildPlotFunctorSpec() */
virtual PlotFunctorSpec buildPlotFunctorSpec ( ) override ;
2020-09-05 05:41:23 +08:00
/** \brief the function to be plotted */
jkqtpParametricCurveFunctionType plotFunction ;
/** \brief a simple function to be plotted, simplified form without parameters */
jkqtpSimpleParametricCurveFunctionType simplePlotFunction ;
2020-09-05 19:14:46 +08:00
2020-09-05 05:41:23 +08:00
} ;
# endif // jkqtpevaluatedparametriccurve_H