C:/sources/c++/buddhabrot/buddhabrot/imagetiler.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright 2010 Pierre SCHWARTZ
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
00005 documentation files (the "Software"), to deal in the Software without restriction, including without 
00006 limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
00007 of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following 
00008 conditions: The above copyright notice and this permission notice shall be included in all copies or 
00009 substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00010 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
00011 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00012 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 
00013 OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
00014 */
00015 
00023 #include "imagetiler.h"
00024 #include "imagecalculator.h"
00025 
00026 ImageTiler::ImageTiler(QVector<QVector<long> >& result, QMutex& mutex, QRectF w, QSize r, fractale *f, bool type, long nbRandom, int start, int step, int id):destinationArray(result), mutex(mutex), window(w), size(r), frac(f), displayRandomPoints(type), nbRandom(nbRandom), start(start), step(step), id(id){
00027         maxValue = 0;
00028 }
00029 
00030 ImageTiler::~ImageTiler(){
00031 }       
00032         
00033 void ImageTiler::run(){
00034         fractale *f = frac->clone();
00035         maxValue = 0;
00036 
00037         // quel est le pas continu de nos itérations ?
00038         double pasX = window.width() / size.width();
00039         double pasY = window.height() / size.height();
00040         
00041         if (displayRandomPoints){
00042                 for (long i=0; i<nbRandom; i++){
00043                         float tmpX = window.left() + window.width() * qrand() / RAND_MAX;       
00044                         float tmpY = window.top() + window.height() * qrand() / RAND_MAX;       
00045                         std::complex<float> start(tmpX, tmpY);
00046                         processSinglePoint(start, f, pasX, pasY);
00047                         emit processed();
00048                 }
00049         }else{
00050 
00051                 // dessine-t-on une partie supérieure ou inférieure ? 
00052                 bool superior =  (window.top() <= -window.bottom());
00053 
00054                 for (int x = start;  x < size.width(); x+=step){        
00055                         for (int y = 0; y < size.height(); y++){                                        
00056                                 // trouver les coordonnées complexes du point (x,y)                     
00057                                 float tmpY = window.top() + y*pasY;                                             
00058                                 // pas la peine de tout calculer en double si on est sûr d'avoir la symétrie verticale ou centrale      
00059                                 if (superior && (f->isVerticalSymetric() || f->isImpair()) && tmpY >= pasY)
00060                                         continue;
00061                                 else
00062                                 if (!superior && (f->isVerticalSymetric() || f->isImpair()) && tmpY <= 0)
00063                                         continue;
00064 
00065                                 float tmpX = window.left() + x*pasX;    
00066 
00067                                 // déroulage de la suite fractale
00068                                 std::complex<float> start(tmpX, tmpY);
00069 
00070                                 processSinglePoint(start, f, pasX, pasY);
00071                         }
00072                         emit processed();
00073                 }
00074         }       
00075 
00076         delete f;       
00077 }
00078 
00079 
00083 void ImageTiler::processSinglePoint(std::complex<float>& start, fractale *f, float pasX, float pasY){
00084         std::complex<float> tmp = start;
00085         f->setStart(start);
00086         QVector<std::complex<float> > serie;
00087 
00088         serie.push_back(start);
00089 
00090         for (int i=0; i<f->getMaxIterations(); i++){
00091                 tmp = f->next(tmp);     
00092 
00093                 if (!f->stop())
00094                         serie.push_back(tmp);
00095                 else{   
00096                         // si la condition de fin de la suite fractale est atteinte, on analyse le résultat
00097                                                                                                         
00098                         // maitenant on peut vider la serie fractale
00099                         QVector<std::complex<float> >::iterator ii = serie.begin();
00100                         while (ii != serie.end()){
00101                                 std::complex<float> destinationPoint = f->renderingDestination(*ii);
00102 
00103                                 // retrouver les coordonnées pixels
00104                                 int xx =  (destinationPoint.real() - window.left()) / pasX;
00105                                 int yy =  (destinationPoint.imag() - window.top()) / pasY;
00106                                 int antiXX = -1;
00107                                 int antiYY = -1;
00108                                 long value;
00109 
00110                                 if (xx >=0 && xx < size.width()){
00111 
00112                                         // incrémenter l'image au point destination 
00113                                         if (yy >= 0  && yy < size.height()){
00114                                                 // on récupère la valeur (x,y) sur l'image, et on incrémente                                                                                    
00115                                                 mutex.lock();
00116                                                 value = destinationArray[xx][yy] + 1;
00117                                                 destinationArray[xx][yy] = value;
00118                                                 mutex.unlock();
00119                                         }
00120 
00121                                         // traiter l'anti point                                         
00122                                         if (f->isVerticalSymetric()){
00123                                                 // on évite de doubler l'axe des x
00124                                                 if ( fabs(destinationPoint.imag()) > 0){
00125                                                         antiYY = (-destinationPoint.imag() - window.top()) / pasY;
00126 
00127                                                         if (antiYY >= 0 && antiYY < size.height()){
00128                                                                 mutex.lock();
00129                                                                 value = destinationArray[xx][antiYY] + 1;
00130                                                                 destinationArray[xx][antiYY] = value;
00131                                                                 mutex.unlock();
00132                                                         }
00133                                                 }
00134                                         }else
00135                                         if (f->isImpair()){
00136                                                 antiYY =  (-destinationPoint.imag() - window.top()) / pasY;
00137                                                 if ( fabs(destinationPoint.imag()) > 0){
00138                                                         if (antiYY >= 0 && antiYY < size.height()){
00139                                                                 antiXX = (-destinationPoint.real() - window.left()) / pasX;
00140                                                                 if (antiXX >= 0 && antiXX < size.width()){
00141                                                                         mutex.lock();
00142                                                                         value = destinationArray[antiXX][antiYY] + 1;
00143                                                                         destinationArray[antiXX][antiYY] = value;
00144                                                                         mutex.unlock();
00145                                                                 }
00146                                                         }
00147                                                 }
00148                                         }
00149 
00150                                         if (value > maxValue)
00151                                                 maxValue = value;       
00152                                 }
00153 
00154                                 ii++;
00155                         }                                       
00156 
00157                         serie.clear();
00158                         break;
00159                 }
00160         }
00161                         
00162         serie.clear();
00163 }

Generated on Fri Feb 26 21:07:52 2010 for BuddhaBrot by  doxygen 1.4.6-NO