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

00001 #include "ImageTiler.h"
00002 #include "ImageCalculator.h"
00003 
00004 ImageTiler::ImageTiler(QImage *d, QRectF w, QSize r, fractale *f, char e, int s, int ste, int i):destination(d), window(w), size(r), frac(f), exhaustivite(e), start(s), step(ste), id(i){
00005         maxValue = 0;
00006 }
00007         
00008         
00009 void ImageTiler::run(){
00010         fractale *f = frac->clone();
00011         maxValue = 0;
00012 
00013         // quel est le pas continu de nos itérations ?
00014         double pasX = window.width() / size.width();
00015         double pasY = window.height() / size.height();
00016         
00017         // dessine-t-on une partie supérieure ou inférieure ? 
00018         bool superior =  (window.top() >= -window.bottom());
00019 
00020         for (int x = start;  x < size.width(); x+=step){        
00021                 for (int y = 0; y < size.height(); y++){                
00022 
00023                         // trouver les coordonnées complexes du point (x,y)                     
00024                         float tmpY = window.top() + y*pasY;                                             
00025                         // pas la peine de tout calculer en double si on est sûr d'avoir la symétrie verticale ou centrale      
00026                         if (superior && (f->isVerticalSymetric() || f->isImpair()) && tmpY >= pasY)
00027                                 break;
00028                         else
00029                         if (!superior && (f->isVerticalSymetric() || f->isImpair()) && tmpY <= 0)
00030                                 continue;
00031 
00032                         float tmpX = window.left() + x*pasX;
00033 
00034                         // déroulage de la suite fractale
00035                         std::complex<float> start(tmpX, tmpY);
00036                         std::complex<float> tmp(tmpX, tmpY);
00037                         f->setStart(start);
00038                         QVector<std::complex<float> > serie;
00039 
00040                         serie.push_back(start);
00041 
00042                         for (int i=0; i<f->getMaxIterations(); i++){
00043                                 tmp = f->next(tmp);     
00044 
00045                                 if (!f->stop())
00046                                         serie.push_back(tmp);
00047                                 else{   
00048                                         // si la condition de fin de la suite fractale est atteinte, on analyse le résultat
00049                                                                                                                         
00050                                         // maitenant on peut vider la serie fractale
00051                                         QVector<std::complex<float> >::iterator ii = serie.begin();
00052                                         while (ii != serie.end()){
00053                                                 std::complex<float> destinationPoint = f->renderingDestination(*ii);
00054 
00055                                                 // retrouver les coordonnées pixels
00056                                                 int xx =  (destinationPoint.real() - window.left()) / pasX;
00057                                                 int yy =  (destinationPoint.imag() - window.top()) / pasY;
00058 
00059                                                 if (yy == 255)
00060                                                         destinationPoint.real();
00061 
00062                                                 // incrémenter l'image au point destination 
00063                                                 if (xx >= 0 && xx < size.width() && yy >= 0  && yy < size.height()){
00064                                                         // on récupère la valeur (x,y) sur l'image, et on incrémente                                    
00065                                                         QRgb r = destination->pixel(xx,yy);
00066                                                         long value = ImageCalculator::RGBAToInt(r)+1;
00067 
00068                                                         destination->setPixel(xx,yy,  ImageCalculator::intToRGBA(value));
00069 
00070                                                         // incrémenter l'anti-point
00071                                                         if (f->isVerticalSymetric()){
00072                                                                 // on évite de doubler l'axe des x
00073                                                                 if ( fabs(destinationPoint.imag()) > 0){
00074                                                                         int antiYY =  (-destinationPoint.imag() - window.top()) / pasY;
00075                                                                         
00076                                                                         if (antiYY >= 0 && antiYY < size.height()){
00077                                                                                 r = destination->pixel(xx,antiYY);
00078                                                                                 destination->setPixel(xx,antiYY,  ImageCalculator::intToRGBA( 
00079                                                                                                 ImageCalculator::RGBAToInt(r)+1
00080                                                                                 ));
00081                                                                         }
00082                                                                 }
00083                                                         }else
00084                                                         if (f->isImpair()){
00085                                                                 int antiYY =  (-destinationPoint.imag() - window.top()) / pasY;
00086                                                                 if ( fabs(destinationPoint.imag()) > 0){
00087                                                                         if (antiYY >= 0 && antiYY < size.height()){
00088                                                                                 int antiXX = (-destinationPoint.real() - window.left()) / pasX;
00089                                                                                 if (antiXX >= 0 && antiXX < size.width()){
00090                                                                                         r = destination->pixel(antiXX,antiYY);
00091                                                                                         destination->setPixel(antiXX,antiYY,  ImageCalculator::intToRGBA( 
00092                                                                                                         ImageCalculator::RGBAToInt(r)+1
00093                                                                                         ));
00094                                                                                 }
00095                                                                         }
00096                                                                 }
00097                                                         }
00098 
00099 /*
00100                                                         // on évite les dépassements de 2^32 sinon ça n'aura plus le même sens visuellement
00101                                                         if (value >= 4294967296)
00102                                                                 value = 4294967295;
00103 */
00104                                                         if (value > maxValue)
00105                                                                 maxValue = value;                                                                                                                                                                                       
00106                                                 }
00107                                                 ii++;
00108                                         }                                       
00109 
00110                                         serie.clear();
00111                                         break;
00112                                 }
00113                         }
00114                         
00115                         serie.clear();
00116                 }
00117                 emit processed();
00118         }
00119 
00120         destination->save(QString("./result%1.bmp").arg(id));
00121 
00122         delete f;       
00123 }

Generated on Sat Feb 6 16:30:54 2010 for BuddhaBrot by  doxygen 1.4.6-NO