2020-09-05 19:14:46 +08:00
|
|
|
/*
|
|
|
|
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"
|
|
|
|
|
2020-09-05 19:47:46 +08:00
|
|
|
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
2020-09-05 19:14:46 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
JKQTPEvaluatedFunctionGraphBase::JKQTPEvaluatedFunctionGraphBase(JKQTBasePlotter* parent):
|
2020-09-05 19:14:46 +08:00
|
|
|
JKQTPGraph(parent)
|
|
|
|
{
|
|
|
|
minSamples=50;
|
|
|
|
maxRefinementDegree=5;
|
|
|
|
slopeTolerance=0.005;
|
|
|
|
minPixelPerSample=32;
|
|
|
|
dataCleanupMaxAllowedAngleDegree=0.2;
|
|
|
|
displaySamplePoints=false;
|
|
|
|
data.clear();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
JKQTPEvaluatedFunctionGraphBase::JKQTPEvaluatedFunctionGraphBase(JKQTPlotter* parent):
|
|
|
|
JKQTPEvaluatedFunctionGraphBase(parent->getPlotter())
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
JKQTPEvaluatedFunctionGraphBase::~JKQTPEvaluatedFunctionGraphBase()
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
data.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
void JKQTPEvaluatedFunctionGraphBase::drawSamplePoints(JKQTPEnhancedPainter& painter, QColor graphColor) {
|
2020-09-05 19:14:46 +08:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
void JKQTPEvaluatedFunctionGraphBase::setMinSamples(const unsigned int &__value)
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
this->minSamples = __value;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
unsigned int JKQTPEvaluatedFunctionGraphBase::getMinSamples() const
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
return this->minSamples;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
void JKQTPEvaluatedFunctionGraphBase::setMaxRefinementDegree(const unsigned int &__value)
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
this->maxRefinementDegree = __value;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
unsigned int JKQTPEvaluatedFunctionGraphBase::getMaxRefinementDegree() const
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
return this->maxRefinementDegree;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
void JKQTPEvaluatedFunctionGraphBase::setSlopeTolerance(double __value)
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
this->slopeTolerance = __value;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
double JKQTPEvaluatedFunctionGraphBase::getSlopeTolerance() const
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
return this->slopeTolerance;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
void JKQTPEvaluatedFunctionGraphBase::setMinPixelPerSample(double __value)
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
this->minPixelPerSample = __value;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
double JKQTPEvaluatedFunctionGraphBase::getMinPixelPerSample() const
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
return this->minPixelPerSample;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
void JKQTPEvaluatedFunctionGraphBase::setDataCleanupMaxAllowedAngleDegree(double __value)
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
dataCleanupMaxAllowedAngleDegree=__value;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
double JKQTPEvaluatedFunctionGraphBase::getDataCleanupMaxAllowedAngleDegree() const
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
return dataCleanupMaxAllowedAngleDegree;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
void JKQTPEvaluatedFunctionGraphBase::setDisplaySamplePoints(bool __value)
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
this->displaySamplePoints = __value;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:16:26 +08:00
|
|
|
bool JKQTPEvaluatedFunctionGraphBase::getDisplaySamplePoints() const
|
2020-09-05 19:14:46 +08:00
|
|
|
{
|
|
|
|
return this->displaySamplePoints;
|
|
|
|
}
|
|
|
|
|
2020-09-05 19:47:46 +08:00
|
|
|
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--;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2020-09-05 19:14:46 +08:00
|
|
|
|
2020-09-05 19:47:46 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|