Commit ca4ab0d5 authored by Fredrik Edemar's avatar Fredrik Edemar

* Optimzed and cleaned the integral-drawing. Now a drawing takes <1 second,...

* Optimzed and cleaned the integral-drawing. Now a drawing takes <1 second, before it took >3 sometimes.
* KMinMax doesn't crash anymore when it is shown.
* Cleaned some code in the add-function classes.

CCMAIL:kdmoeller@foni.net
CCMAIL:bmlmessmer@web.de

svn path=/trunk/kdeedu/kmplot/; revision=348257
parent 86e484a3
......@@ -296,14 +296,14 @@ void View::plotfkt(Ufkt *ufkt, QPainter *pDC)
if ( p_mode == 3)
{
if ( ufkt->integral_use_precision )
dx = ufkt->integral_precision*(dmax-dmin)/(area.width()*10);
else
dx=dx/10;
dx = ufkt->integral_precision*(dmax-dmin)/area.width();
progressbar->progress->reset();
progressbar->progress->setTotalSteps ( (int)double((dmax-dmin)/dx)/2 );
progressbar->show();
x = ufkt->startx; //the initial x-point
x = ufkt->oldx = ufkt->startx; //the initial x-point
ufkt->oldy = ufkt->starty;
ufkt->oldyprim = ufkt->integral_precision;
paintEvent(0);
}
else
x=dmin;
......@@ -336,13 +336,11 @@ void View::plotfkt(Ufkt *ufkt, QPainter *pDC)
break;
case 3:
{
y=m_parser->fkt(ufkt, x);
m_parser->euler_method(x, y,ufkt);
y = m_parser->euler_method(x, ufkt);
if ( int(x*100)%2==0)
{
KApplication::kApplication()->processEvents(); //makes the program usable when drawing a complicated integral function
progressbar->increase();
paintEvent(0);
}
break;
}
......@@ -391,12 +389,15 @@ void View::plotfkt(Ufkt *ufkt, QPainter *pDC)
if (x>dmax && p_mode== 3)
{
forward_direction = false;
x = ufkt->startx;
x = ufkt->oldx = ufkt->startx;
ufkt->oldy = ufkt->starty;
ufkt->oldyprim = ufkt->integral_precision;
paintEvent(0);
mflg=2;
}
}
else
x=x-dx; // go backwards
x=x-dx; // go backwards
}
else
x=x+dx;
......@@ -1215,12 +1216,15 @@ void View::findMinMaxValue(Ufkt *ufkt, char p_mode, bool minimum, double &dmin,
stop_calculating = false;
progressbar->progress->reset();
if ( ufkt->integral_use_precision )
dx = ufkt->integral_precision*(dmax-dmin)/(area.width()*10);
else
dx=stepWidth*(dmax-dmin)/(area.width()*10); //the stepwidth must be small for Euler's metod
dx = ufkt->integral_precision*(dmax-dmin)/area.width();
else
dx = stepWidth*(dmax-dmin)/area.width();
progressbar->progress->setTotalSteps ( (int)double((dmax-dmin)/dx)/2 );
progressbar->show();
x = ufkt->startx; //the initial x-point
x = ufkt->oldx = ufkt->startx; //the initial x-point
ufkt->oldy = ufkt->starty;
ufkt->oldyprim = ufkt->integral_precision;
paintEvent(0);
}
else
{
......@@ -1259,13 +1263,11 @@ void View::findMinMaxValue(Ufkt *ufkt, char p_mode, bool minimum, double &dmin,
}
case 3:
{
y=m_parser->fkt(ufkt, x);
m_parser->euler_method(x, y, ufkt);
y = m_parser->euler_method(x, ufkt);
if ( int(x*100)%2==0)
{
KApplication::kApplication()->processEvents(); //makes the program usable when drawing a complicated integral function
progressbar->increase();
paintEvent(0);
}
break;
}
......@@ -1298,7 +1300,10 @@ void View::findMinMaxValue(Ufkt *ufkt, char p_mode, bool minimum, double &dmin,
if (x>dmax && p_mode== 3)
{
forward_direction = false;
x = ufkt->startx;
x = ufkt->oldx = ufkt->startx;
ufkt->oldy = ufkt->starty;
ufkt->oldyprim = ufkt->integral_precision;
paintEvent(0);
}
}
else
......@@ -1362,9 +1367,9 @@ void View::getYValue(Ufkt *ufkt, char p_mode, double x, double &y, QString &str
double dx;
if ( ufkt->integral_use_precision )
dx = ufkt->integral_precision*(dmax-dmin)/(area.width()/10);
else
dx=stepWidth*(dmax-dmin)/(area.width()/10); //the stepwidth must be small for Euler's metod
dx = ufkt->integral_precision*(dmax-dmin)/area.width();
else
dx=stepWidth*(dmax-dmin)/area.width();
stop_calculating = false;
isDrawing=true;
......@@ -1373,16 +1378,17 @@ void View::getYValue(Ufkt *ufkt, char p_mode, double x, double &y, QString &str
progressbar->progress->reset();
progressbar->progress->setTotalSteps ((int) double((dmax-dmin)/dx)/2 );
progressbar->show();
x = ufkt->startx; //the initial x-point
x = ufkt->oldx = ufkt->startx; //the initial x-point
ufkt->oldy = ufkt->starty;
ufkt->oldyprim = ufkt->integral_precision;
paintEvent(0);
while (x>=dmin && !stop_calculating && !target_found)
{
y=m_parser->fkt( ufkt, x );
m_parser->euler_method( x, y,ufkt );
y = m_parser->euler_method( x, ufkt );
if ( int(x*100)%2==0)
{
KApplication::kApplication()->processEvents(); //makes the program usable when drawing a complicated integral function
progressbar->increase();
paintEvent(0);
}
if ( (x+dx > target && forward_direction) || ( x+dx < target && !forward_direction)) //right x-value is found
......@@ -1396,7 +1402,10 @@ void View::getYValue(Ufkt *ufkt, char p_mode, double x, double &y, QString &str
if (x>dmax)
{
forward_direction = false;
x = ufkt->startx;
x = ufkt->oldx = ufkt->startx;
ufkt->oldy = ufkt->starty;
ufkt->oldyprim = ufkt->integral_precision;
paintEvent(0);
}
}
else
......@@ -1585,7 +1594,7 @@ void View::areaUnderGraph( Ufkt *ufkt, char const p_mode, double &dmin, double
}
if(dmin==dmax) //no special plot range is specified. Use the screen border instead.
{
{
dmin=xmin;
dmax=xmax;
}
......@@ -1609,13 +1618,21 @@ void View::areaUnderGraph( Ufkt *ufkt, char const p_mode, double &dmin, double
{
stop_calculating = false;
if ( ufkt->integral_use_precision )
dx = ufkt->integral_precision*(dmax-dmin)/(area.width()*10);
else
dx=stepWidth*(dmax-dmin)/(area.width()*10); //the stepwidth must be small for Euler's metod
dx = ufkt->integral_precision*(dmax-dmin)/area.width();
else
dx = stepWidth*(dmax-dmin)/area.width();
progressbar->progress->reset();
progressbar->progress->setTotalSteps ( (int)double((dmax-dmin)/dx)/2 );
progressbar->show();
x = ufkt->startx; //the initial x-point
x = ufkt->oldx = ufkt->startx; //the initial x-point
ufkt->oldy = ufkt->starty;
ufkt->oldyprim = ufkt->integral_precision;
//paintEvent(0);
/*QPainter p;
p.begin(this);
bitBlt( this, 0, 0, &buffer, 0, 0, width(), height() );
p.end();*/
}
else
{
......@@ -1626,7 +1643,7 @@ void View::areaUnderGraph( Ufkt *ufkt, char const p_mode, double &dmin, double
int const origoy = dgr.Transy(0.0);
int const rectwidth = dgr.Transx(dx)- dgr.Transx(0.0)+1;
setCursor(Qt::WaitCursor );
isDrawing=true;
......@@ -1664,13 +1681,11 @@ void View::areaUnderGraph( Ufkt *ufkt, char const p_mode, double &dmin, double
}
case 3:
{
y=m_parser->fkt(ufkt, x);
m_parser->euler_method(x, y, ufkt);
y = m_parser->euler_method(x, ufkt);
if ( int(x*100)%2==0)
{
KApplication::kApplication()->processEvents(); //makes the program usable when drawing a complicated integral function
progressbar->increase();
paintEvent(0);
}
break;
}
......@@ -1722,7 +1737,10 @@ void View::areaUnderGraph( Ufkt *ufkt, char const p_mode, double &dmin, double
if (x>dmax && p_mode== 3)
{
forward_direction = false;
x = ufkt->startx;
x = ufkt->oldx = ufkt->startx;
ufkt->oldy = ufkt->starty;
ufkt->oldyprim = ufkt->integral_precision;
paintEvent(0);
}
}
else
......
......@@ -111,7 +111,7 @@ void EditFunction::setWidgets()
{
Ufkt *ufkt = &m_parser->ufkt[ m_parser->ixValue(m_id) ];
editfunctionpage->equation->setText( ufkt->extstr );
editfunctionpage->hide->setChecked( ufkt->f_mode == 0 );
editfunctionpage->hide->setChecked( !ufkt->f_mode);
editfunctionpage->lineWidth->setValue( ufkt->linewidth );
editfunctionpage->color->setColor( ufkt->color );
if ( ufkt->dmin != ufkt->dmax )
......@@ -257,10 +257,6 @@ void EditFunction::accept()
tmp_ufkt.integral_precision = editintegralpage->precision->value();
tmp_ufkt.integral_linewidth = editintegralpage->lineWidth->value();
/*if( editfunctionpage->hide->isChecked() )
tmp_ufkt.f_mode = 0;
else
tmp_ufkt.f_mode = 1;*/
tmp_ufkt.f_mode = !editfunctionpage->hide->isChecked();
if( editfunctionpage->useSlider->isChecked() )
......@@ -282,19 +278,11 @@ void EditFunction::accept()
}
if( editderivativespage->showDerivative1->isChecked() )
tmp_ufkt.f1_mode = 1;
else
tmp_ufkt.f1_mode = 0;
tmp_ufkt.f1_mode = editderivativespage->showDerivative1->isChecked();
tmp_ufkt.f1_linewidth = editderivativespage->lineWidthDerivative1->value();
tmp_ufkt.f1_color = editderivativespage->colorDerivative1->color().rgb();
if( editderivativespage->showDerivative2->isChecked() )
tmp_ufkt.f2_mode = 1;
else
tmp_ufkt.f2_mode = 0;
tmp_ufkt.f2_mode = editderivativespage->showDerivative2->isChecked();
tmp_ufkt.f2_linewidth = editderivativespage->lineWidthDerivative2->value();
tmp_ufkt.f2_color = editderivativespage->colorDerivative2->color().rgb();
......@@ -347,6 +335,7 @@ void EditFunction::accept()
}
added_ufkt = &m_parser->ufkt.last();
}
//save all settings in the function now when we know no errors have appeared
added_ufkt->f_mode = tmp_ufkt.f_mode;
added_ufkt->f1_mode = tmp_ufkt.f1_mode;
added_ufkt->f2_mode = tmp_ufkt.f2_mode;
......
......@@ -76,7 +76,7 @@ void KEditParametric::setWidgets()
kLineEditXFunction->setText( expression );
splitEquation( m_parser->ufkt[ m_y_id ].extstr, name, expression );
kLineEditYFunction->setText( expression );
checkBoxHide->setChecked( ufkt->f_mode == 0 );
checkBoxHide->setChecked( !ufkt->f_mode );
if ( ufkt->dmin != ufkt->dmax )
{
checkBoxRange->setChecked(true);
......@@ -105,10 +105,7 @@ void KEditParametric::accept()
Ufkt tmp_ufkt;
if( checkBoxHide->isChecked() )
tmp_ufkt.f_mode = 0;
else
tmp_ufkt.f_mode = 1;
tmp_ufkt.f_mode = !checkBoxHide->isChecked();
if( checkBoxRange->isChecked() )
{
......@@ -190,7 +187,7 @@ void KEditParametric::accept()
added_ufkt = &m_parser->ufkt.last();
}
//save all settings in the function now when we now no errors have appeared
//save all settings in the function now when we know no errors have appeared
added_ufkt->f_mode = tmp_ufkt.f_mode;
added_ufkt->f1_mode = tmp_ufkt.f1_mode;
added_ufkt->f2_mode = tmp_ufkt.f2_mode;
......
......@@ -71,7 +71,7 @@ void KEditPolar::setWidgets()
QString function = ufkt->extstr;
function = function.right( function.length()-1 );
kLineEditYFunction->setText( function );
checkBoxHide->setChecked( ufkt->f_mode == 0 );
checkBoxHide->setChecked( !ufkt->f_mode);
if ( ufkt->dmin != ufkt->dmax )
{
checkBoxRange->setChecked( true );
......@@ -93,12 +93,8 @@ void KEditPolar::accept()
else
m_parser->fixFunctionName(f_str, XParser::Polar);
Ufkt tmp_ufkt; //all settings are saved here until we know that no errors have appeared
if( checkBoxHide->isChecked() )
tmp_ufkt.f_mode = 0;
else
tmp_ufkt.f_mode = 1;
tmp_ufkt.f_mode = !checkBoxHide->isChecked();
if( checkBoxRange->isChecked() )
{
tmp_ufkt.str_dmin = min->text();
......@@ -177,7 +173,7 @@ void KEditPolar::accept()
}
added_ufkt = &m_parser->ufkt.last();
}
//save all settings in the function now when we now no errors have appeared
//save all settings in the function now when we know no errors have appeared
added_ufkt->f_mode = tmp_ufkt.f_mode;
added_ufkt->f1_mode = tmp_ufkt.f1_mode;
added_ufkt->f2_mode = tmp_ufkt.f2_mode;
......
......@@ -375,26 +375,22 @@ void KMinMax::list_highlighted(QListBoxItem* item)
p_mode = 3;
function.at(0) = function.at(0).lower();
}
QString fname, fstr;
//bool stop=false;
QString sec_function = function.section('(',0,0);
//for ( ix = 0; ix < (int)m_view->parser()->ufkt.count() && !stop; ++ix )
QValueVector<Ufkt>::iterator it = m_view->parser()->ufkt.begin();
for( int ix=0; it!=m_view->parser()->ufkt.end(); ++it)
QString const sec_function = function.section('(',0,0);
for(QValueVector<Ufkt>::iterator it = m_view->parser()->ufkt.begin(); it!=m_view->parser()->ufkt.end(); ++it)
{
if ( it->extstr.section('(',0,0) == sec_function)
break;
++ix;
{
if ( it->str_parameter.count() == 0)
cmdParameter->hide();
else
cmdParameter->show();
if (parameter.isEmpty() )
parameter = it->str_parameter.first();
break;
}
}
--it;
if ( it->str_parameter.count() ==0)
cmdParameter->hide();
else
cmdParameter->show();
if (parameter.isEmpty() )
parameter = it->str_parameter.first();
}
void KMinMax::cmdParameter_clicked()
{
......@@ -417,23 +413,19 @@ void KMinMax::cmdParameter_clicked()
p_mode = 3;
function.at(0) = function.at(0).lower();
}
QString fname, fstr;
bool stop=false;
QString sec_function = function.section('(',0,0);
QValueVector<Ufkt>::iterator it = m_view->parser()->ufkt.begin();
//for ( ix = 0; ix < (int)m_view->parser()->fktext.count() && !stop; ++ix )
for( int ix=0; it!=m_view->parser()->ufkt.end(); ++it)
QString const sec_function = function.section('(',0,0);
for(QValueVector<Ufkt>::iterator it = m_view->parser()->ufkt.begin() ; it!=m_view->parser()->ufkt.end(); ++it)
{
if ( it->extstr.section('(',0,0) == sec_function)
stop=true;
if ( it->extstr.section('(',0,0) == sec_function)
{
bool ok;
QStringList result = KInputDialog::getItemList( i18n("Choose Parameter"), i18n("Choose a parameter to use:"), it->str_parameter, QStringList(parameter),false,&ok,this );
if ( ok)
parameter = result.first();
break;
}
}
--it;
bool ok;
QStringList result = KInputDialog::getItemList(i18n("Choose Parameter"), i18n("Choose a parameter to use:"), it->str_parameter, QStringList(parameter),false,&ok);
if ( ok)
parameter = *result.begin();
}
void KMinMax::list_doubleClicked(QListBoxItem *)
......
......@@ -188,35 +188,13 @@ void XParser::fixFunctionName( QString &str, int const type, int const id)
}
}
void XParser::euler_method(const double x, double &y, const QValueVector<Ufkt>::iterator it)
double XParser::euler_method(const double x, const QValueVector<Ufkt>::iterator it)
{
// y == the old yprim-value
if (x == it->startx ) //the first point we should draw
{
it->oldy = it->starty;
it->oldyprim = it->integral_precision;
/*kdDebug() << "*******************" << endl;
kdDebug() << " start-x: " << x << endl;
kdDebug() << " start-y: " << itf->starty << endl;
kdDebug() << "*******************" << endl;*/
it->oldx = x;
y=it->starty;
return;
}
else
{
double const yprim = y;
double const h = x-it->oldx;
y = it->oldy + (h * it->oldyprim);
it->oldy = y;
it->oldx = x;
it->oldyprim = yprim;
return;
}
double const y = it->oldy + ((x-it->oldx) * it->oldyprim);
it->oldy = y;
it->oldx = x;
it->oldyprim = fkt( it, x ); //yprim;
return y;
}
QRgb XParser::defaultColor(int function)
......
......@@ -51,7 +51,7 @@ public:
/// Evaluates the 2nd dreivative of the function with intex \a ix
double a2fkt( Ufkt *, double, double h = 1e-3 );
/// calculate euler's method when drawing a numeric prime-function
void euler_method(const double, double &, const QValueVector<Ufkt>::iterator);
double euler_method(const double, const QValueVector<Ufkt>::iterator);
/// Line width default
int linewidth0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment