Logo Search packages:      
Sourcecode: labplot version File versions

FunctionDialog.cc

//LabPlot : FunctionDialog.cc

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream>

#ifdef USE_SOLARIS
#include <ieeefp.h>
#endif

#include <qlabel.h>
#include <qhbox.h>
#include <qcolordialog.h>
#include <qprogressdialog.h>
#include <qtabwidget.h>
#include <klocale.h>
#include <kdebug.h>
#include "FunctionDialog.h"
#include "Plot2DSurface.h"
#include "PlotQWT3D.h"
#include "defs.h"

#ifdef HAVE_GSL
#include <gsl/gsl_math.h>
#endif

using namespace std;

/*! newtype -> new 3D Plot type*/
FunctionDialog::FunctionDialog(Worksheet *p, const char *name, ListDialog *l, int item, PType newtype)
      : Dialog(p, name), l(l), item(item)
{
      mw = p->getMainWin();
      
      Plot *plot = p->getPlot(p->API());
      if (plot != 0)
            type = plot->Type();
      else
            type = newtype;

      kdDebug()<<"FunctionDialog"<<endl;
      kdDebug()<<"Type = "<<type<<endl;

      QString caption;
      if (type == P2D)
            caption=i18n("2D Function Dialog");
      else if (type == P3D)
            caption=i18n("3D Function Dialog");
      else if (type == PQWT3D)
            caption=i18n("3D QWT Function Dialog");
      else if (type == PSURFACE)
            caption=i18n("2D Surface Function Dialog");
      else if (type == PPOLAR)
            caption=i18n("2D Polar Function Dialog");
      caption += i18n(" : ")+QString(name);
      setCaption(caption);

      Style style;
      Symbol symbol;
      LRange rx, ry;
      GRAPHType s = GRAPH2D;
      int nrx = 0, nry = 0;

      if(type == PPOLAR) {
            symbol.setType(1);
      }

      // default style and symbol for polar plots
      if (item == -1) { // new graph
            graph = 0;
      }
      else {
            GraphList *graphlist = plot->getGraphList();
            graph = graphlist->getGraph(item);
            s = graphlist->getStruct(item);

            style = graph->getStyle();
            symbol = graph->getSymbol();
            kdDebug()<<"Struct : "<<s<<endl;

            if (s == GRAPH2D) {
                  Graph2D *g = graphlist->getGraph2D(item);
                  rx = g->Range(0);
                  nrx = graph->Number();
            }
            else if (s == GRAPH3D) {
                  Graph3D *g = graphlist->getGraph3D(item);
                  rx = g->Range(0);
                  ry = g->Range(1);
                  nrx = g->NX();
                  nry = g->NY();
            }
            else if (s == GRAPHM) {
                  GraphM *g = graphlist->getGraphM(item);
                  rx = g->Range(0);
                  ry = g->Range(1);
                  nrx = g->NX();
                  nry = g->NY();
            }
      }

      QTabWidget *tw = new QTabWidget(vbox);
      QVBox *tab1 = new QVBox(tw);

      QString fun("sin(x)");
      if (type == P3D || type == PSURFACE || type == PQWT3D)
            fun = QString("sin(x+y)");
      if (graph != 0) fun = graph->Name();
      new QLabel(i18n("Function :"),tab1);
      funle = new KLineEdit(fun,tab1);

      QHBox *hb = new QHBox(tab1);
      if (graph !=0) {
            reread = new QCheckBox(i18n("Recreate Function"),hb);
            reread->setChecked(0);
      }
      else
            reread=0;

      QString label = fun;
      if (graph != 0) label = graph->Label();
      new QLabel(i18n("Label :"),tab1);
      hb = new QHBox(tab1);
      labelle = new KLineEdit(label,hb);
      KPushButton *setLabel = new KPushButton(i18n("Set Label"),hb);
      QObject::connect(setLabel,SIGNAL(clicked()),SLOT(setLabel()));

      new QLabel(i18n("Range :"),tab1);
      hb = new QHBox(tab1);
      new QLabel(QString("x = "),hb);

      double x1 = 0, x2 = 1;
      if (type == PSURFACE) {
            x1=0;
            x2=1;
      }
      if (graph != 0) {
            x1 = rx.rMin();
            x2 = rx.rMax();
      }
      xmin = new KLineEdit(QString::number(x1),hb);
      new QLabel(QString(" .. "),hb);
      xmax = new KLineEdit(QString::number(x2),hb);
      if (type == P3D || type == PSURFACE || type == PQWT3D) {
            new QLabel(QString(" y = "),hb);

            double y1 = 0, y2 = 1;
            if (type == PSURFACE) {
                  y1=0;
                  y2=1;
            }
            if (graph != 0) {
                  x1 = rx.rMin();
                  x2 = rx.rMax();
                  y1 = ry.rMin();
                  y2 = ry.rMax();
            }
            ymin = new KLineEdit(QString::number(y1),hb);
            new QLabel(QString(" .. "),hb);
            ymax = new KLineEdit(QString::number(y2),hb);
      }
      new QLabel(i18n("Number of Points :"),tab1);
      hb = new QHBox(tab1);
      new QLabel(QString("NX = "),hb);
      if(type == P2D || type == PPOLAR) {
            if (graph == 0) nrx = 100;
            nx = new KLineEdit(QString::number(nrx),hb);
            nx->setValidator(new QIntValidator(nx));
      }
      else if (type == P3D || type == PSURFACE || type == PQWT3D){
            if (graph == 0) {
                  nrx = 10;
                  nry = 10;
            }
            nx = new KLineEdit(QString::number(nrx),hb);
            nx->setValidator(new QIntValidator(nx));
            new QLabel(QString("NY = "),hb);
            ny = new KLineEdit(QString::number(nry),hb);
            ny->setValidator(new QIntValidator(ny));
      }

      tw->addTab(tab1,i18n("Parameter"));

      QVBox *styletab, *annotatetab;
      if(type == PQWT3D) {
            // TODO
      }
      if (type == PSURFACE) {
            styletab = surfaceStyle(tw);
            tw->addTab(styletab,i18n("Style"));
      }
      else {
            styletab = simpleStyle(tw,graph, &style, &symbol);
            annotatetab = annotateValuesTab(tw,graph);
            tw->addTab(styletab,i18n("Style"));
            tw->addTab(annotatetab,i18n("Annotate Values"));
      }
      
      QObject::connect(ok,SIGNAL(clicked()),SLOT(ok_clicked()));
      QObject::connect(apply,SIGNAL(clicked()),SLOT(agree()));

      setMinimumWidth(vbox->minimumSizeHint().width());
      setMinimumHeight(gbox->minimumSizeHint().height()+vbox->minimumSizeHint().height());
      resize((int)(1.5*minimumSize().width()),minimumSize().height());
}

int FunctionDialog::agree() {
      kdDebug()<<"FunctionDialog::agree()"<<endl;
      QString label = labelle->text();
      int status=0;
      if (reread == 0 || reread->isChecked()) {
            status = addFunction();
      }
      else {
            if(type == PSURFACE) {
                  if (p != 0) {
                        Plot2DSurface *plot = (Plot2DSurface *)p->getPlot(p->API());

                        if (plot != 0) {
                              plot->enableDensity(dcb->isChecked());
                              plot->enableContour(ccb->isChecked());
                              plot->setNumber(numberle->text().toInt());
                              plot->setPalette(pcb->currentItem());
                              plot->setContourColor(contourcolor->color());
                              plot->setColoredContour(coloredcb->isChecked());
                              plot->setMesh(meshcb->isChecked());
                              plot->setRelative(relativecb->isChecked());
                              plot->setBrush(dbrushcb->currentItem());
                              plot->setThreshold(thresholdle->text().toDouble());
                        }
                  }
            }
            else {
                  Style style(cb2->currentItem(),color->color(),filled->isChecked(),
                        fcolor->color(),widthle->text().toInt(),
                        pencb->currentItem(),brushcb->currentItem());
                  Symbol symbol((SType)symbolcb->currentItem(),scolor->color(),ssize->text().toInt(),
                              (FType)symbolfillcb->currentItem(),sfcolor->color(),sbrushcb->currentItem());
                  AnnotateValues av(typecb->currentItem(),positioncb->currentItem(),distancele->text().toInt());
                  graph->setStyle(style);
                  graph->setSymbol(symbol);
                  graph->setAnnotateValues(av);
            }
            graph->setLabel(label);
      }

      if(l) l->updateList();
      p->updatePixmap();

      kdDebug()<<"FunctionDialog::agree() OK"<<endl;
      return status;
}

int FunctionDialog::addFunction() {
      kdDebug()<<"addFunction()"<<endl;
      QString fun = funle->text().lower();
      QString label = labelle->text();
      int NX = (nx->text()).toInt();
      int NY = 0;
      if (type == P3D || type == PSURFACE || type == PQWT3D)
            NY = (ny->text()).toInt();

      QProgressDialog progress( "Creating function ...", "Cancel", NX,this, "progress", TRUE );
      progress.setMinimumDuration(2000);
      if (type == P2D || type == PPOLAR) {
            Point *ptr = new Point[NX];

            double ymin=0, ymax=1;
            double xmi = parse((char *) (xmin->text()).latin1());
            double xma = parse((char *) (xmax->text()).latin1());
            for(int i = 0;i < NX;i++) {
                  if(i%100 == 0) progress.setProgress( i );
                  qApp->processEvents();

                  double x = (xma-xmi)*i/(double)(NX-1)+xmi;
                  QString tmp(fun);
                  if (tmp.length()==1) tmp += " ";          // "x"

                  tmp = mw->parseExpression(tmp, x, 23);    // "x"
                  
                  double y = parse((char *) tmp.latin1());

                  if (!finite(y))
                        y=0;

                  if (i == 0) ymin=ymax=y;
                  y<ymin?ymin=y:0;
                  y>ymax?ymax=y:0;

                  ptr[i].setPoint(x,y);
                  if ( progress.wasCancelled() )
                        return 1;
            }
            if(graph != 0)
                  p->getPlot(p->API())->getGraphList()->delGraph(item);

            if(ymax-ymin == 0) {
                  ymin -= 1;
                  ymax += 1;
            }

            if(type == PPOLAR) {
                  xmi = 0;
                  xma = 2*M_PI;
            }
            
            LRange range[2];
            range[0] = LRange(xmi,xma);
            range[1] = LRange(ymin,ymax);
            Style style(cb2->currentItem(),color->color(),filled->isChecked(),
                  fcolor->color(),widthle->text().toInt(),
                  pencb->currentItem(),brushcb->currentItem());
            Symbol symbol((SType)symbolcb->currentItem(),scolor->color(),ssize->text().toInt(),
                  (FType)symbolfillcb->currentItem(),sfcolor->color(),sbrushcb->currentItem());

            kdDebug()<<"range[0]="<<range[0].rMin()<<","<<range[0].rMax()<<endl;
            kdDebug()<<"range[1]="<<range[1].rMin()<<","<<range[1].rMax()<<endl;
            kdDebug()<<"sfc = "<<sfcolor->color().name()<<endl;

            Graph2D *g = new Graph2D(fun,label,range,SFUNCTION,type,style,symbol,ptr,NX);
            
            AnnotateValues av(typecb->currentItem(),positioncb->currentItem(),distancele->text().toInt());
            g->setAnnotateValues(av);
            p->addGraph2D(g);
      }
      else if (type == PSURFACE || type == PQWT3D) {
            kdDebug() << "\"surface\" or \" qwt 3d \" selected"<<endl;
            kdDebug()<<"NX = "<<NX<<"/ NY = "<<NY<<endl;

            double *a = new double[NY*NX];

            double xmi=0, xma=1, ymi=0, yma=1, zmin=0, zmax=1;
            for (int i=0;i<NY;i++) {
                  if(i%10==0)progress.setProgress( i );
                  qApp->processEvents();
                  xmi = parse((char *) (xmin->text()).latin1());
                  xma = parse((char *) (xmax->text()).latin1());
                  ymi = parse((char *) (ymin->text()).latin1());
                  yma = parse((char *) (ymax->text()).latin1());
                  
                  QString tmp(fun);
                  if (tmp.length()==1) tmp += " ";
                  
                  tmp = mw->parseExpression(tmp,(yma-ymi)*i/(double)(NY-1)+ymi,24);
                  
                  for (int j=0;j<NX;j++) {
                        QString tmp2 = mw->parseExpression(tmp,(xma-xmi)*j/(double)(NX-1)+xmi,23);
                        
                        double z = parse((char *) tmp2.latin1());
                        if (!finite(z)) z=0;

                        //kdDebug()<<"z = "<<z<<" (i/j = "<<i<<'/'<<j<<")\n";

                        if (i == 0 && j == 0) {
                              zmin=z;
                              zmax=z;
                        }

                        z<zmin?zmin=z:0;
                        z>zmax?zmax=z:0;
                        
                        a[j+NX*i] = z;
                  }
                  if ( progress.wasCancelled() )
                        return 1;
            }

            if(type == PSURFACE) {
                  Plot2DSurface *plot = (Plot2DSurface *)p->getPlot(p->API());

                  // edit graph
                  if(graph != 0)
                        plot->getGraphList()->delGraph(item);

                  if (plot != 0) {
                        plot->enableDensity(dcb->isChecked());
                        plot->enableContour(ccb->isChecked());
                        plot->setNumber(numberle->text().toInt());
                        plot->setPalette(pcb->currentItem());
                        plot->setContourColor(contourcolor->color());
                        plot->setColoredContour(coloredcb->isChecked());
                        plot->setMesh(meshcb->isChecked());
                        plot->setRelative(relativecb->isChecked());
                        plot->setBrush(dbrushcb->currentItem());
                        plot->setThreshold(thresholdle->text().toDouble());
                  }
            }
            else if (type == PQWT3D) {
                  kdDebug() << "\"qwt 3d \" selected"<<endl;
                  // TODO
                  //PlotQWT3D *plot = (PlotQWT3D *)p->getPlot(p->API());
            }

            if(zmax-zmin == 0) {
                  zmin -= 1;
                  zmax += 1;
            }

            LRange range[3];
            range[0] = LRange(0,NX);
            range[1] = LRange(0,NY);
            range[2] = LRange(zmin,zmax);

            kdDebug()<<"zmin : "<<zmin<<"/ zmax : "<<zmax<<endl;
            kdDebug()<<"range : "<<range[0].rMin()<<' '<<range[0].rMax()<<endl;
            kdDebug()<<"range : "<<range[1].rMin()<<' '<<range[1].rMax()<<endl;
            kdDebug()<<"range : "<<range[2].rMin()<<' '<<range[2].rMax()<<endl;
            /*for(int i=0;i<NX;i++) {
                  for(int j=0;j<NY;j++) {
                        kdDebug()<<" ("<<j+NY*i<<')'<<a[j+NY*i]<<endl;
                  }
                  kdDebug()<<endl;
            }*/

            Style style(0);
            Symbol symbol(SNONE);
            GraphM *g = new GraphM(fun,label,range,SFUNCTION,type,style,symbol,a,NX,NY);
            p->addGraphM(g,type);
      }
      else if (type == P3D) {
            kdDebug() << "\"3d\" selected"<<endl;

            Point3D *ptr = new Point3D[NX*NY];

            double xmi=(xmin->text()).toDouble(), xma=(xmax->text()).toDouble();
            double ymi=(ymin->text()).toDouble(), yma=(ymax->text()).toDouble();
            double zmin=0, zmax=1;
            for(int i = 0;i < NY;i++) {
                  if(i%100==0)progress.setProgress( i );
                  qApp->processEvents();

                  QString tmp(fun);
                  if (tmp.length()==1) tmp += " ";
                  
                  double y = (yma-ymi)*i/(double)(NY-1)+ymi;
                  tmp = mw->parseExpression(tmp,y,24);
                  
                  for (int j = 0;j < NX;j++) {
                        double x = (xma-xmi)*j/(double)(NX-1)+xmi;
                        QString tmp2 = mw->parseExpression(tmp,x,23);
                        
                        double z = parse((char *) tmp2.latin1());
                        if (!finite(z)) z=0;

                        //kdDebug()<<"z = "<<z<<endl;

                        if (i == 0 && j==0 ) zmin=zmax=z;
                        z<zmin?zmin=z:0;
                        z>zmax?zmax=z:0;

                        ptr[i*NX+j].setPoint(x,y,z);
                  }
                  if ( progress.wasCancelled() )
                        return 1;
            }

            if(graph != 0)
                  p->getPlot(p->API())->getGraphList()->delGraph(item);

            if(zmax-zmin == 0) {
                  zmin -= 1;
                  zmax += 1;
            }

            LRange range[3];
            range[0] = LRange(xmi,xma);
            range[1] = LRange(ymi,yma);
            range[2] = LRange(zmin,zmax);

            kdDebug()<<"Z RANGE = "<<zmin<<' '<<zmax<<endl;

            Style style(cb2->currentItem(),color->color(),filled->isChecked(),fcolor->color(),widthle->text().toInt(),
                  pencb->currentItem(),brushcb->currentItem());
            Symbol symbol((SType)symbolcb->currentItem(),scolor->color(),ssize->text().toInt(),
                        (FType)symbolfillcb->currentItem(),sfcolor->color(),sbrushcb->currentItem());

            Graph3D *g = new Graph3D(fun,label,range,SFUNCTION,P3D,style,symbol,ptr,NX,NY);
            AnnotateValues av(typecb->currentItem(),positioncb->currentItem(),distancele->text().toInt());
            g->setAnnotateValues(av);
            p->addGraph3D(g);
      }

      return 0;
}

Generated by  Doxygen 1.6.0   Back to index