Logo Search packages:      
Sourcecode: qliss3d version File versions  Download package

qliss3d.cpp

// This is Free Software
// See the GNU General Public License @ http://www.gnu.org/copyleft/gpl.html
// for details about the terms and conditions for using and distributing
// this piece of software.
// This software comes with absolutely NO WARRANTY!
// (c) 2003 by Daniel Gruen <daniel_gruen@web.de>

#include <qpainter.h>
#include <qpixmap.h>
#include <q3hbox.h>
#include <qslider.h>
#include <qlabel.h>
#include <qlcdnumber.h>
#include <qspinbox.h>
#include <qpushbutton.h>
#include <qpen.h>
#include <qcolor.h>
#include <qpalette.h>
#include <qcheckbox.h>
#include <qwidget.h>
#include <qsound.h>
//Added by qt3to4:
#include <QKeyEvent>
#include <QMouseEvent>
#include <QPaintEvent>

#include <cmath>
#include <ctime>
#include <cstdlib>
#include <iostream>

#include <unistd.h>

#include "qliss3d.h"

#include "include/fmplayer.h"


using namespace std;

// projects xyz-coords on xy
ddcoord xycoord(dddcoord a,float k) {
   ddcoord tmp;
   tmp.x = int(a.x) + (400 - int(a.x)) * (0.5-(k/(a.z+k)));
   tmp.y = int(a.y) + (300 - int(a.y)) * (0.5-(k/(a.z+k)));
   return tmp;
}

// turns xyz-coords around an axis
// special thanks to Mr. M. Deffner
dddcoord xzturn(dddcoord a , int W)
{
   float D=atan(a.x/a.z);             //                  { Ausgangswinkel }
   float G=D+(pi/180)*W;             //                    { Drehwinkel }
   if (a.z<0) G=G+(pi);
    float R=sqrt(a.z*a.z+a.x*a.x); //                          { Radius }
   a.z=int(R*cos(G));
   a.x=int(R*sin(G));
   return a;
}

dddcoord yzturn(dddcoord a , int W)
{
   float D=atan(a.y/a.z);             //                  { Ausgangswinkel }
   float G=D+(pi/180)*W;             //                    { Drehwinkel }
   if (a.z<0) G=G+(pi);
    float R=sqrt(a.z*a.z+a.y*a.y); //                          { Radius }
   a.z=int(R*cos(G));
   a.y=int(R*sin(G));
   return a;
}

// constructor of QLiss3D-Widget
QLiss3D::QLiss3D(QWidget *parent, const char *name) : QWidget(parent, name){
      xang = 0;  // viewing angle = 0
      yang = 0;
      ppf = 5000; // 5000 points per frame
      k   = 800;  // zoom = 800
      cr   = 0; // red = 0, green = 100, blue = 200
      cg   = 100;
      cb   = 200;
      b = c = d = df = 0.0; // pseudo-frequencies and density
      ls  = 1; // connect with lines
      is  = 0; // don't show any numbers
      msx = msy = 0; // mouse pointer coordinates when dragging
      really_repaint = 0;
      xp = yp = zp = 0; // phase shift = 0
      
      setFixedSize(800,600);
      srand(time((time_t *)NULL));
      setFocusPolicy(Qt::StrongFocus);
      setFocus();

      randomFigure();
      setDensity();
      
      connect(this,SIGNAL(xFreqChanged(int)),    SLOT(repaintMe()));
      connect(this,SIGNAL(yFreqChanged(int)),    SLOT(repaintMe()));
      connect(this,SIGNAL(zFreqChanged(int)),    SLOT(repaintMe()));
      connect(this,SIGNAL(xPhaseChanged(float)), SLOT(repaintMe()));
      connect(this,SIGNAL(yPhaseChanged(float)), SLOT(repaintMe()));
      connect(this,SIGNAL(zPhaseChanged(float)), SLOT(repaintMe()));
      connect(this,SIGNAL(kChanged(int)),        SLOT(repaintMe()));
      connect(this,SIGNAL(xAngleChanged(int)),   SLOT(repaintMe()));
      connect(this,SIGNAL(yAngleChanged(int)),   SLOT(repaintMe()));
      connect(this,SIGNAL(densityChanged(float)),SLOT(repaintMe()));
      connect(this,SIGNAL(PPFChanged(int)),      SLOT(repaintMe()));
      connect(this,SIGNAL(colorRChanged(int)),   SLOT(repaintMe()));
      connect(this,SIGNAL(colorGChanged(int)),   SLOT(repaintMe()));
      connect(this,SIGNAL(colorBChanged(int)),   SLOT(repaintMe()));
      connect(this,SIGNAL(PPFChanged(int)),      SLOT(setDensity()));
      connect(this,SIGNAL(xFreqChanged(int)),    SLOT(setDensity()));
      connect(this,SIGNAL(yFreqChanged(int)),    SLOT(setDensity()));
      connect(this,SIGNAL(zFreqChanged(int)),    SLOT(setDensity()));
      really_repaint = 1;
      repaintMe();
      help = new Q3VBox;
      Q3HBox *help2 = new Q3HBox(help);
      Q3VBox *help3 = new Q3VBox(help2);
      QLabel *l1  = new QLabel(tr("turn figure"),help3);
      QLabel *l2  = new QLabel(tr("reset angle"),help3);
      QLabel *l3  = new QLabel(tr("change red color value"),help3);
      QLabel *l4  = new QLabel(tr("change green color value"),help3);
      QLabel *l5  = new QLabel(tr("change blue color value"),help3);
      QLabel *l6  = new QLabel(tr("zoom"),help3);
      QLabel *l7  = new QLabel(tr("change density"),help3);
      QLabel *l8  = new QLabel(tr("x phase shift"),help3);
      QLabel *l9  = new QLabel(tr("y phase shift"),help3);
      QLabel *l10 = new QLabel(tr("z phase shift"),help3);
      QLabel *l11 = new QLabel(tr("toggle information"),help3);
      Q3VBox *help4 = new Q3VBox(help2);
      QLabel *c1  = new QLabel(tr("cursor keys, mouse dragging"),help4);
      QLabel *c2  = new QLabel(tr("page up / page down"),help4);
      QLabel *c3  = new QLabel(tr("r / t"),help4);
      QLabel *c4  = new QLabel(tr("g / h"),help4);
      QLabel *c5  = new QLabel(tr("b / n"),help4);
      QLabel *c6  = new QLabel(tr("+ / -"),help4);
      QLabel *c7  = new QLabel(tr("Ins / Del"),help4);
      QLabel *c8  = new QLabel(tr("y / x"),help4);
      QLabel *c9  = new QLabel(tr("a / s"),help4);
      QLabel *c10 = new QLabel(tr("q / w"),help4);
      QLabel *c11 = new QLabel(tr("i"),help4);

      if (!(l1  && l2  && l3  && l4  && l5  && l6  && l7  && l8  && l9  && l10 && l11
         && c1  && c2  && c3  && c4  && c5  && c6  && c7  && c8  && c9  && c10 && c11))
            return;


      help->setSpacing(20);
      help2->setSpacing(20);
      QPushButton *helpexit = new QPushButton(tr("E&xit"),help);
      connect(helpexit, SIGNAL(clicked()), help, SLOT(hide()));
      help->hide();
}

// set turning angles
void QLiss3D::setXAngle(int degrees){
      if(degrees>180)
            degrees=-180;
      if(degrees<-180)
            degrees=180;
      if(xang==degrees)
            return;
      xang = degrees;
      emit xAngleChanged(xang);
}

void QLiss3D::setYAngle(int degrees){
      if(degrees>180)
            degrees=-180;
      if(degrees<-180)
            degrees=180;
      if(yang==degrees)
            return;
      yang = degrees;
      emit yAngleChanged(yang);
}

// set colors
void QLiss3D::setColorR(int dr){
      if(dr>255)
            dr=255;
      if(dr<0)
            dr=0;
      if(cr==dr)
            return;
      cr = dr;
      emit colorRChanged(cr);
}

void QLiss3D::setColorG(int dg){
      if(dg>255)
            dg=255;
      if(dg<0)
            dg=0;
      if(cg==dg)
            return;
      cg = dg;
      emit colorGChanged(cg);
}

void QLiss3D::setColorB(int db){
      if(db>255)
            db=255;
      if(db<0)
            db=0;
      if(cb==db)
            return;
      cb = db;
      emit colorRChanged(cb);
}

// set some kind of zoom factor
void QLiss3D::setK(int dk){
      if(dk>2000)
            dk=2000;
      if(dk<50)
            dk=50;
      if(k==dk)
            return;
      k = dk;
      emit kChanged(k);
}

// points per frame
void QLiss3D::setPPF(int dppf){
      if(dppf>50000)
            dppf = 50000;
      if(dppf<1)
            dppf = 1;
      if(ppf==dppf)
            return;
      ppf=dppf;
      emit PPFChanged(ppf);
}

void QLiss3D::setDensity(){
      if(!(b&&c&&d)){
            df = 0.0;
            return;
      }

      float tr = ggt(b,c);
      tr = ggt(tr,d);
      tr = (360.0*pi180)/tr;
      if(df == tr/ppf*1.001)
            return;
      df = tr/ppf*1.001;
      emit densityChanged(df);
}

// paint the Lissajous figure
void QLiss3D::paintEvent(QPaintEvent *){

      QPixmap pix(800,600);
      pix.fill();

      QPainter p(&pix);
      p.setPen(QPen(QColor(cr,cg,cb),1));
      float ampx, ampy, ampaddx, ampaddy;
      ampx    = ampy    = 0.25;
      ampaddx = ampaddy = (1.0-2.0*ampy) / 2.0;

      int screenx, screeny, fluchtx, fluchty;
      screenx = 800;
      screeny = 600;
      fluchtx = 400;
      fluchty = 300;

      dddcoord a;
      ddcoord  e,eold;
      a.x = (sin(b*df+xp) + 1.0) * screenx * ampx + ampaddx * screenx;
      a.y = (sin(c*df+yp) + 1.0) * screeny * ampy + ampaddy * screeny;
      a.z =  sin(d*df+zp) * 100 + 70;
      a.x -= 400;
      a.z -= 50;
      a = xzturn(a, xang);
      a.x += 400;
      a.z += 240;
      a.y -= 300;
      a.z -= 250;
      a = yzturn(a, yang);
      a.y += 300;
      a.z += 440;

      eold = xycoord(a,k);

      for(int i = 1; i < ppf; i++){
           a.x = (sin(i*b*df+xp) + 1.0) * screenx * ampx + ampaddx * screenx;
           a.y = (sin(i*c*df+yp) + 1.0) * screeny * ampy + ampaddy * screeny;
           a.z =  sin(i*d*df+zp) * 100 + 70;

           a.x -= 400;
           a.z -= 50;
           a = xzturn(a, xang);
           a.x += 400;
           a.z += 240;

           a.y -= 300;
           a.z -= 250;
           a = yzturn(a, yang);
           a.y += 300;
           a.z += 440;

           e = xycoord(a,k);
           if(ls && 800 > e.x && e.x > 0 && 600 > e.y && e.y > 0 && 800 > eold.x && eold.x  > 0 && 600 > eold.y  && eold.y > 0)
            p.drawLine(int(e.x), int(e.y), int(eold.x), int(eold.y));
           else
            p.drawPoint(int(e.x), int(e.y));
           eold = e;
      }
      if(is){
            p.drawText(700,20,tr("x freq."));
            p.drawText(750,20,QString::number(b));
            p.drawText(700,35,tr("y freq."));
            p.drawText(750,35,QString::number(c));
            p.drawText(700,50,tr("z freq."));
            p.drawText(750,50,QString::number(d));

            p.drawText(700,70,tr("x angle"));
            p.drawText(750,70,QString::number(xang));
            p.drawText(700,85,tr("y angle"));
            p.drawText(750,85,QString::number(yang));

            p.drawText(700,105,tr("x phase"));
            p.drawText(750,105,QString::number(xp/pi180,'f',0));
            p.drawText(700,120,tr("y phase"));
            p.drawText(750,120,QString::number(yp/pi180,'f',0));
            p.drawText(700,135,tr("z phase"));
            p.drawText(750,135,QString::number(zp/pi180,'f',0));
      }
      p.end();
      p.begin(this);
      p.drawPixmap(0,0,pix);
}

void QLiss3D::keyPressEvent(QKeyEvent * e){
      switch(e->key()){
            case Qt::Key_Left:
                  setXAngle(xang+1);
                  break;
            case Qt::Key_Right:
                  setXAngle(xang-1);
                  break;
            case Qt::Key_Up:
                  setYAngle(yang+1);
                  break;
            case Qt::Key_Down:
                  setYAngle(yang-1);
                  break;
            case Qt::Key_PageUp:
                  setXAngle(0);
                  break;
            case Qt::Key_PageDown:
                  setYAngle(0);
                  break;
            case Qt::Key_R:
                  setColorR(cr+2);
                  break;
            case Qt::Key_T:
                  setColorR(cr-2);
                  break;
            case Qt::Key_G:
                  setColorG(cg+2);
                  break;
            case Qt::Key_H:
                  setColorG(cg-2);
                  break;
            case Qt::Key_B:
                  setColorB(cb+2);
                  break;
            case Qt::Key_N:
                  setColorB(cb-2);
                  break;
            case Qt::Key_X:
                  setXPhase(fmod(xp+pi180,2*pi));
                  break;
            case Qt::Key_Y:
                  setXPhase(fmod(xp-pi180,2*pi));
                  break;
            case Qt::Key_S:
                  setYPhase(fmod(yp+pi180,2*pi));
                  break;
            case Qt::Key_A:
                  setYPhase(fmod(yp-pi180,2*pi));
                  break;
            case Qt::Key_W:
                  setZPhase(fmod(zp+pi180,2*pi));
                  break;
            case Qt::Key_Q:
                  setZPhase(fmod(zp-pi180,2*pi));
                  break;
            case Qt::Key_Plus:
                  setK(k+10);
                  break;
            case Qt::Key_Minus:
                  setK(k-10);
                  break;
            case Qt::Key_Insert:
                  setPPF(ppf+5);
                  break;
            case Qt::Key_Delete:
                  setPPF(ppf-5);
                  break;
            case Qt::Key_F1:
                  help->show();
                  break;
            case Qt::Key_I:
                  setInfoState((!is)*2);
                  break;
            default:
                  e->ignore();
      }
}

void QLiss3D::mousePressEvent(QMouseEvent * e){
      msx = e->x();
      msy = e->y();
}

// turn it following the mouse
void QLiss3D::mouseMoveEvent(QMouseEvent * e){
      really_repaint = msy!=e->y() ? 0 : 1;
      setXAngle(xang-msx+e->x());
      really_repaint = 1;
      setYAngle(yang+msy-e->y());
      msx = e->x();
      msy = e->y();
}

// repaint with random frequencies
void QLiss3D::randomFigure(){
      really_repaint = 0;
      setXFreq(rand() % 100);
      setYFreq(rand() % 100);
      setZFreq(rand() % 100);
      emit xFreqChanged(int(b));
      emit yFreqChanged(int(c));
      emit zFreqChanged(int(d));
      repaint(FALSE);
      really_repaint = 1;
}


// play it using /dev/dsp
void QLiss3D::playWav(){
#ifdef HAVE_SYS_SOUNDCARD_H
#ifdef HAVE_FCNTL_H
#ifdef HAVE_SYS_IOCTL_H
#ifdef HAVE_UNISTD_H
      FMPlayer p;
      p.sound->setFreq(b*10);
      p.nextSound();
      p.sound->setFreq(c*10);
      p.nextSound();
      p.sound->setFreq(d*10);
      p.package->setTime(0.1);
      p.package->setRepeat(10);
      p.openFiles();
      p.compute();
      p.play();
#endif
#endif
#endif
#endif
}

// constructor for the menubar
QLiss3DObject::QLiss3DObject(QWidget *parent, const char *name) : Q3VBox(parent, name){
      Q3HBox * menu;
      menu = new Q3HBox(this, "Liss-Menu");
      menu->setSpacing(10);
      
      Q3VBox      * abox;
      abox   = new Q3VBox(menu, "Angle-Box");
      Q3HBox      * albox;
      albox  = new Q3HBox(abox, "Angle-Label-Box");
      QLabel     * alabel;
      alabel = new QLabel(tr("Angle:"),albox,"Angle-Label");
      QLCDNumber * xalcd;
      xalcd   = new QLCDNumber(4, albox, "xAngle-LCD");
      QLCDNumber * yalcd;
      yalcd   = new QLCDNumber(4, albox, "y-Angle-LCD");
      QSlider    * xangle;
      xangle  = new QSlider(-180, 180, 0, 0, Qt::Horizontal, abox, "xAngle-Slider");
      QSlider    * yangle;
      yangle  = new QSlider(-180, 180, 0, 0, Qt::Horizontal, abox, "yAngle-Slider");
      
      connect(xangle,SIGNAL(valueChanged(int)),xalcd,SLOT(display(int)));
      connect(yangle,SIGNAL(valueChanged(int)),yalcd,SLOT(display(int)));

      
      Q3VBox      * pbox;
      pbox   = new Q3VBox(menu, "pixel-Box");
      Q3HBox      * plbox;
      plbox  = new Q3HBox(pbox, "pixel-Label-Box");
      QLabel     * plabel;
      plabel = new QLabel(tr("Points:"),plbox,"pixel-Label");
      QSpinBox   * pixel;
      pixel  = new QSpinBox(2000, 50000, 10, pbox, "pixel-Slider");
      pixel->setValue(5000);
      
      
      /*QVBox      * kbox;
      kbox   = new QVBox(menu, "k-Box");
      QHBox      * klbox;
      klbox  = new QHBox(kbox, "k-Label-Box");
      QLabel     * klabel;
      klabel = new QLabel("Zoom:",klbox,"k-Label");
      QSpinBox   * kss;
      kss  = new QSpinBox(50, 2000, 10, kbox, "k-Slider");
      kss->setValue(800);*/

      Q3VBox *xfbox, *yfbox, *zfbox;
      xfbox = new Q3VBox(menu, "x-Freq-VBox");
      yfbox = new Q3VBox(menu, "y-Freq-VBox");
      zfbox = new Q3VBox(menu, "z-Freq-VBox");

      QLabel *xfl, *yfl, *zfl;
      xfl = new QLabel(tr("x-frequency:"),xfbox, "XFLabel");
      yfl = new QLabel(tr("y-frequency:"),yfbox, "XFLabel");
      zfl = new QLabel(tr("z-frequency:"),zfbox, "XFLabel");
      
      QSpinBox *xfreq, *yfreq, *zfreq;
      xfreq = new QSpinBox(1,100,1,xfbox,"x-Freq-Spinbox");
      yfreq = new QSpinBox(1,100,1,yfbox,"y-Freq-Spinbox");
      zfreq = new QSpinBox(1,100,1,zfbox,"z-Freq-Spinbox");
      
      QPushButton * rfigr;
      rfigr = new QPushButton(tr("&Random"),menu, "neue Figur - Button");

      QCheckBox * dolines;
      dolines = new QCheckBox(tr("&Connect"),menu,"Punkte verbinden - CheckBox");
      dolines->setChecked(TRUE);
      
      QPushButton * play;
      play = new QPushButton(tr("&Play"),menu, "playButton");
      
      
      QLiss3D * liss;
      liss = new QLiss3D(this, "Liss-Figur");
      connect(xangle, SIGNAL(valueChanged(int)), liss,  SLOT(setXAngle(int)))   ;
      connect(yangle, SIGNAL(valueChanged(int)), liss,  SLOT(setYAngle(int)))   ;
      connect(pixel,  SIGNAL(valueChanged(int)), liss,  SLOT(setPPF(int)))      ;
      //connect(kss,    SIGNAL(valueChanged(int)), liss,  SLOT(setK(int)))        ;
      connect(rfigr,  SIGNAL(clicked()),         liss,  SLOT(randomFigure()))   ;
      connect(dolines,SIGNAL(stateChanged(int)), liss,  SLOT(setLineState(int)));
      connect(xfreq,  SIGNAL(valueChanged(int)), liss,  SLOT(setXFreq(int)))    ;
      connect(yfreq,  SIGNAL(valueChanged(int)), liss,  SLOT(setYFreq(int)))    ;
      connect(zfreq,  SIGNAL(valueChanged(int)), liss,  SLOT(setZFreq(int)))    ;
      connect(play,   SIGNAL(clicked()),         liss,  SLOT(playWav()))        ;

      connect(liss,   SIGNAL(xAngleChanged(int)),xangle,SLOT(setValue(int)))    ;
      connect(liss,   SIGNAL(yAngleChanged(int)),yangle,SLOT(setValue(int)))    ;
      connect(liss,   SIGNAL(xFreqChanged(int)), xfreq, SLOT(setValue(int)))    ;
      connect(liss,   SIGNAL(yFreqChanged(int)), yfreq, SLOT(setValue(int)))    ;
      connect(liss,   SIGNAL(zFreqChanged(int)), zfreq, SLOT(setValue(int)))    ;
      //connect(liss,   SIGNAL(kChanged(int)),     kss,   SLOT(setValue(int)))    ;
      connect(liss,   SIGNAL(PPFChanged(int)),   pixel, SLOT(setValue(int)))    ;
      
      liss->randomFigure();
}


Generated by  Doxygen 1.6.0   Back to index