glorbitalview.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                        glorbitalview.cpp  -  description
00003                              -------------------
00004     begin                : Thu Nov 4 2004
00005     copyright            : (C) 2004-2006 by Ben Swerts
00006     email                : bswerts@users.sourceforge.net
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00019 
00027 
00028 
00029 
00031 
00032 // C++ header files
00033 #include <cfloat>
00034 #include <cmath>
00035 
00036 // Qt header files
00037 #include <qapplication.h>
00038 #include <qcolor.h>
00039 #include <qfiledialog.h>
00040 #include <qimage.h>
00041 #include <qmessagebox.h>
00042 #include <qprogressdialog.h>
00043 #include <qstringlist.h>
00044 #include <qtimer.h>
00045 
00046 // Xbrabo header files
00047 #include "glorbitalview.h"
00048 #include <point3d.h>
00049 #include <quaternion.h>
00050 
00054 
00056 GLOrbitalView::GLOrbitalView(QWidget* parent, const char* name) : GLView(parent, name),
00057   colorPositive(QColor(0, 0, 255)),
00058   colorNegative(QColor(255, 0, 0)),
00059   maximumRadius(1.0f),
00060   scaleFactor(1.0f)
00062 {
00063 
00064 }
00065 
00067 GLOrbitalView::~GLOrbitalView()
00069 {
00070   
00071 }
00072 
00074 void GLOrbitalView::updateColors(QColor pos, QColor neg)
00076 {
00077   colorPositive = pos;
00078   colorNegative = neg;
00079 }
00080 
00082 std::vector<Point3D<float> >* GLOrbitalView::getCoordinates()
00084 {
00085   return &coords;
00086 }
00087 
00089 QMutex* GLOrbitalView::getMutex()
00091 {
00092   return &mutex;
00093 }
00094 
00096 void GLOrbitalView::setMaximumRadius(const double radius)
00101 {
00102   maximumRadius = radius;
00103   scaleFactor = 10.0f/maximumRadius; // scale the radius of the bounding sphere to 10.0f  
00104   zoomFit(false); // doesn't work correctly if called with (true), possibly calls updateGL() of base class
00105   updateGL(); 
00106 }
00107 
00108 /*//// updateValues ////////////////////////////////////////////////////////////
00109 void GLOrbitalView::updateValues(int atom, int n, int l, int m, QColor pos, QColor neg, int type, int resolution, float probability, int dots)
00110 {
00112   
00113   //qDebug("updating GLorbitalView with atom = %d, n = %d, l = %d, m = %d, type = %d, res = %d, prob = %f, dots = %d", atom, n, l, m, type, resolution, probability, dots);
00114   atomNumber = static_cast<unsigned int>(atom);
00115   qnPrincipal = static_cast<unsigned int>(n);
00116   qnOrbital = static_cast<unsigned int>(l);
00117   qnMomentum = static_cast<int>(m);
00118   ASSERT(qnOrbital - abs(qnMomentum) >= 0);
00119   ASSERT(qnPrincipal > qnOrbital);
00120   
00121   colorPositive = pos;
00122   colorNegative = neg;
00123 
00124   ASSERT(probability > 0.0f);
00125   ASSERT(type >= 0 && type < 5);
00126 
00128   unsigned int neededPrecision = PRECISION_UNKNOWN;
00129   if(type != 4)
00130   {
00132     // check whether the largest possible number ((4n)^n) can be represented by a float
00133     if(largestResult<float>(qnPrincipal, qnOrbital, qnMomentum, atomNumber) != HUGE_VAL)
00134     //if(powf(static_cast<float>(4 * atomNumber * qnPrincipal), qnPrincipal) != HUGE_VALF)
00135       neededPrecision = PRECISION_FLOAT;
00136     // by a double
00137     else if(pow(static_cast<double>(4 * atomNumber * qnPrincipal), qnPrincipal) != HUGE_VAL)
00138       neededPrecision = PRECISION_DOUBLE;
00139     // or by a long double
00140     else if(powl(static_cast<long double>(4 * atomNumber * qnPrincipal), qnPrincipal) != HUGE_VAL)
00141       neededPrecision = PRECISION_LONG_DOUBLE;
00142   }
00143   else
00144   {     
00146     // check whether the largest possible number ((2l)!) can be represented by a float
00147     if(factorial<float>(2*qnOrbital) != HUGE_VAL)
00148       neededPrecision = PRECISION_FLOAT;
00149     // by a double
00150     else if(factorial<float>(2*qnOrbital) != HUGE_VAL)
00151       neededPrecision = PRECISION_DOUBLE;
00152     // or by a long double
00153     else if(factorial<float>(2*l) != HUGE_VAL)
00154       neededPrecision = PRECISION_LONG_DOUBLE;
00155   }
00156   qDebug("required precision = %d", neededPrecision);
00157   if(neededPrecision == PRECISION_UNKNOWN)
00158   {
00159     // QMessageBox
00160     qDebug("exceeded long double limits");
00161     return;
00162   }
00163   if(neededPrecision != PRECISION_FLOAT)
00164   {
00165     qDebug("precision higher than float not implemented yet");
00166     return;
00167   }
00168 
00169   allowedToQuit = false;
00170   cancelRequested = false;
00171   qDebug("starting calc");    
00172 
00173   switch(type)
00174   {
00175     case 0: getIsoProbability(static_cast<float>(resolution), probability);
00176             break;
00177     case 1: getAccumulatedProbability(static_cast<float>(resolution), probability);
00178             break;
00179     case 2: getRandomDots(static_cast<unsigned int>(dots));
00180             break;
00181     case 3: getRadialPart(static_cast<float>(resolution));
00182             break;
00183     case 4: getAngularPart(static_cast<float>(resolution));
00184   }
00185   allowedToQuit = true;
00186   qDebug("maximum radius = %f (= %f n^2)", maximumRadius, maximumRadius/(n*n));
00187   if(maximumRadius < 0.1f) maximumRadius = 0.1f;
00188   scaleFactor = 10.0f/maximumRadius; // scale the radius of the bounding sphere to 10.0f  
00189   zoomFit(false); // doesn't work correctly if called with (true), possibly calls updateGL() of base class
00190   updateGL();  
00191 }
00192 */
00193 
00194 
00198 
00200 void GLOrbitalView::drawScene()
00203 {
00204   // scale if the boundaries exceed 100.0f (the far z-value)
00205   glScalef(scaleFactor, scaleFactor, scaleFactor);
00206   
00207   //*  
00209   glDisable(GL_LIGHTING);
00210 
00211   glBegin(GL_POINTS);
00212     mutex.lock();
00213     std::vector<Point3D<float> >::iterator it = coords.begin();
00214     while(it != coords.end())
00215     {
00216       if(it->id() == 1)
00217         qglColor(colorPositive);
00218       else
00219         qglColor(colorNegative);
00220       glVertex3f(it->x(), it->y(), it->z());
00221       it++;
00222     }
00223     mutex.unlock();
00224   glEnd();
00225   // no use in making a display list as the coordinates might be updated at any time
00226 
00227   /*// lines
00228   glBegin(GL_LINE_LOOP);
00229 
00230   // loop over the indices
00231   const unsigned int maxPoints = qnOrbital == 0 ? 2*qnPrincipal -1 : 2*(qnPrincipal - qnOrbital);
00232   const unsigned int resolution = 20;
00233   
00234   for(unsigned int i = 1; i <= maxPoints; i++)
00235   {
00236     // get 360/resolution phi's and draw a looped lines around them
00237     std::vector<float>::iterator itX = coordsX.begin();
00238     std::vector<float>::iterator itY = coordsY.begin();
00239     std::vector<float>::iterator itZ = coordsZ.begin();
00240     std::vector<bool>::iterator itP = phase.begin();
00241     std::vector<unsigned int>::iterator itI = index.begin();
00242 
00243     while(itX != coordsX.end())
00244     {
00245       glBegin(GL_LINE_LOOP);
00246       unsigned int numPoints = 0;
00247       while(numPoints < resolution && itX != coordsX.end())
00248       {
00249         if(*itI == i)
00250         {
00251           numPoints++;
00252           if(*itP)
00253             qglColor(QColor(255, 255, 0));
00254           else
00255             qglColor(QColor(0, 255, 255));
00256           glVertex3f(*itX, *itY, *itZ);
00257         }
00258         itX++;
00259         itY++;
00260         itZ++;
00261         itP++;        
00262         itI++;                
00263       }
00264       glEnd();
00265     }    
00266   }
00267   // other lines (180/resolution theta)
00268   for(unsigned int i = 1; i <= maxPoints; i++)
00269   {
00270     // fill some vectors with the data for the current point
00271     std::vector<float> lcoordsX, lcoordsY, lcoordsZ;
00272     std::vector<bool> lphase;
00273             
00274     std::vector<float>::iterator itX = coordsX.begin();
00275     std::vector<float>::iterator itY = coordsY.begin();
00276     std::vector<float>::iterator itZ = coordsZ.begin();
00277     std::vector<bool>::iterator itP = phase.begin();
00278     std::vector<unsigned int>::iterator itI = index.begin();
00279     while(itI != index.end())
00280     {
00281       if(*itI == i)
00282       {
00283         lcoordsX.push_back(*itX);
00284         lcoordsY.push_back(*itY);
00285         lcoordsZ.push_back(*itZ);
00286         lphase.push_back(*itP);        
00287       }
00288       itX++;
00289       itY++;
00290       itZ++;
00291       itP++;
00292       itI++;    
00293     }
00294 
00295     std::vector<float>::iterator itlX = lcoordsX.begin();
00296     std::vector<float>::iterator itlY = lcoordsY.begin();
00297     std::vector<float>::iterator itlZ = lcoordsZ.begin();
00298     std::vector<bool>::iterator itlP = lphase.begin();
00299     
00300     for(unsigned int startPoint = 0; startPoint < resolution; startPoint++)
00301     {
00302       // start at each point and draw the line
00303       std::vector<float>::iterator itlX2 = itlX;
00304       std::vector<float>::iterator itlY2 = itlY;
00305       std::vector<float>::iterator itlZ2 = itlZ;
00306       std::vector<bool>::iterator itlP2 = itlP;
00307       unsigned int numPoints = 0;
00308       glBegin(GL_LINE_LOOP);
00309       while(itlX2 != lcoordsX.end())
00310       {
00311         numPoints++;
00312         if(numPoints%resolution == 0)
00313         {
00314           if(*itlP2)
00315             qglColor(QColor(255, 255, 0));
00316           else
00317             qglColor(QColor(0, 255, 255));
00318           
00319           glVertex3f(*itlX2, *itlY2, *itlZ2);
00320         }
00321         itlX2++;
00322         itlY2++;
00323         itlZ2++;
00324         itlP2++;        
00325       }
00326       glEnd();
00327       itlX++;
00328       itlY++;
00329       itlZ++;
00330       itlP++;
00331       if(itlX == lcoordsX.end()) break;      
00332     }   
00333   }
00334   */      
00335 }
00336 
00338 float GLOrbitalView::boundingSphereRadius()
00340 {
00341   return static_cast<float>(maximumRadius*scaleFactor); 
00342 }
00343 

Generated on Fri May 19 14:31:54 2006 for Brabosphere by  doxygen 1.4.6-NO