#include "thread.h" #include #include #include #include #include #include "ifs.h" #include "flame.h" #include "mandelbrot.h" #include "functionSdl.h" #include "functionFile.h" #include "lSystem.h" #include "postfix.h" #include "functionAdd.h" #include "check.h" #include "mandelbrot.h" //Calcule et dessine la fractale de Mandelbrot void* threadMandelbrot(void *Data) { Mandelbrot* mand_mandel;//Pointeur vers une structure Mandelbrot double d_xmin;//réel permettant de délimiter les bordures de l'écran double d_xmax;//réel permettant de délimiter les bordures de l'écran double d_ymin;//réel permettant de délimiter les bordures de l'écran double d_ymax;//réel permettant de délimiter les bordures de l'écran int* pi_nbIt;//pointeur vers un entier représentant le nombre d'itérations parcourues int* pi_oldIt;//pointeur vers un entier représentant le nombre d'itérations parcourues à l'indice de boucle précédent mand_mandel = (Mandelbrot*)Data; pi_nbIt=myMalloc(sizeof(int)); pi_oldIt=myMalloc(sizeof(int)); d_xmin=-2.1/(*mand_mandel->pd_zoom)-(*mand_mandel->ppoint_pInit).x; d_xmax=2.1/(*mand_mandel->pd_zoom)-(*mand_mandel->ppoint_pInit).x; d_ymin=-1.2/(*mand_mandel->pd_zoom)-(*mand_mandel->ppoint_pInit).y; d_ymax=1.2/(*mand_mandel->pd_zoom)-(*mand_mandel->ppoint_pInit).y; *pi_nbIt=0; *pi_oldIt=0; loopMandelbrot(mand_mandel,pi_nbIt, pi_oldIt, d_xmin, d_xmax, d_ymin, d_ymax); free(pi_nbIt); freeThreadMandel(mand_mandel,pi_oldIt,pi_oldIt); return (NULL); } //Parcours la totalité de l'écran en calculant et dessinant la fractale de Mandelbrot void loopMandelbrot(Mandelbrot* mand_mandel, int* pi_nbIt, int* pi_oldIt,double d_xmin, double d_xmax, double d_ymin, double d_ymax) { double* pd_color;//Un pointeur vers un double int** ppi_tabColor;//Un tableau à deux dimensions de couleur int i_nbGradColor;//Un entier représentant le numéro de dégradé de couleur int i_px;//variable de boucle correspondant à l'abscisse d'un point sur l'écran int i_py;//variable de boucle correspondant à l'ordonnée d'un point sur l'écran double d_cX;//réel correspondant à la partie réelle du complexe C double d_cY;//réél correspondant à la partie imaginaire du complexe C double d_zX;//réel correspondant à la partie réelle du complexe Z double d_zY;//réel correspondant à la partie imaginaire du complexe Z double d_zX1;//réel correspondant à la partie réelle du complexe Z SDL_Rect rect_position;//Rectangle correspondant à la position du pixel a dessiner SDL_Surface *surf_pixel;//Pixel à dessiner surf_pixel=SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0, 0, 0, 0); i_nbGradColor=getNbGradColor(*mand_mandel->pi_numGradient); ppi_tabColor=createTabColor(*mand_mandel->pi_numGradient); pd_color=myMalloc(sizeof(double)*4); d_zX1=0; d_zX=0; d_zY=0; for (i_px = mand_mandel->i_minX; i_px < mand_mandel->i_maxX; ++i_px) { for (i_py = 1; i_py < mand_mandel->i_maxY; i_py=i_py+2) { rect_position.x=i_px; rect_position.y=i_py; d_cX=d_xmin+(((double)i_px/mand_mandel->surf_screen->w)*(d_xmax-d_xmin)); d_cY=d_ymin+(((double)i_py/mand_mandel->surf_screen->h)*(d_ymax-d_ymin)); iterationMandelbrot(pi_nbIt,*mand_mandel->pi_nbIter,d_zX,d_zY,d_cX,d_cY,d_zX1); colorAndPutPixel(surf_pixel, mand_mandel->pi_nbIter, pi_nbIt,pd_color, ppi_tabColor, i_nbGradColor); SDL_BlitSurface(surf_pixel, NULL, mand_mandel->surf_screen, &rect_position); rect_position.y=i_py-1; if((*pi_oldIt)!=(*pi_nbIt)) { iterationMandelbrot(pi_nbIt,*mand_mandel->pi_nbIter,d_zX,d_zY,d_cX,d_ymin+(((double)(i_py-1)/mand_mandel->surf_screen->h)*(d_ymax-d_ymin)),d_zX1); } colorAndPutPixel(surf_pixel, mand_mandel->pi_nbIter, pi_nbIt,pd_color, ppi_tabColor, i_nbGradColor); SDL_BlitSurface(surf_pixel, NULL, mand_mandel->surf_screen, &rect_position); *(pi_oldIt)=*(pi_nbIt); } } freeLoopMandelbrotJulia(surf_pixel, i_nbGradColor, pd_color, ppi_tabColor); } //Calcule le nombre d'itérations void iterationMandelbrot(int* pi_nbIt,int i_nbIter,double d_zX, double d_zY, double d_cX,double d_cY,double d_zX1){ *pi_nbIt=0; while ( *pi_nbIt<=i_nbIter && (d_zX*d_zX+d_zY*d_zY)<=4 ){ d_zX1=d_zX; d_zX=d_zX*d_zX-d_zY*d_zY+d_cX; d_zY=2*d_zX1*d_zY+d_cY; (*pi_nbIt)++; } } //Calcule est dessine la fractale de Julia void* threadJulia(void *Data) { Julia* jul_julia;//pointeur vers une structure Julia double d_xmin;//réel permettant de délimiter les bordures de l'écran double d_xmax;//réel permettant de délimiter les bordures de l'écran double d_ymin;//réel permettant de délimiter les bordures de l'écran double d_ymax;//réel permettant de délimiter les bordures de l'écran int* pi_nbIt;//pointeur vers un entier représentant le nombre d'itérations parcourues int* pi_oldIt;//pointeur vers un entier représentant le nombre d'itérations parcourues à l'indice de boucle précédent jul_julia = (Julia*)Data; pi_nbIt=myMalloc(sizeof(int)); pi_oldIt=myMalloc(sizeof(int)); d_xmin=-1.5/(*jul_julia->pd_zoom)-(*jul_julia->ppoint_pInit).x; d_xmax=1.5/(*jul_julia->pd_zoom)-(*jul_julia->ppoint_pInit).x; d_ymin=-1.5/(*jul_julia->pd_zoom)-(*jul_julia->ppoint_pInit).y; d_ymax=1.5/(*jul_julia->pd_zoom)-(*jul_julia->ppoint_pInit).y; *pi_nbIt=0; *pi_oldIt=0; if(*jul_julia->pi_reverse==0) { loopJulia(jul_julia, pi_nbIt, pi_oldIt,d_xmin,d_xmax,d_ymin,d_ymax); } else { loopJuliaReverse(jul_julia,d_xmin,d_xmax,d_ymin,d_ymax); } freeThreadJulia(jul_julia,pi_oldIt,pi_oldIt); free(pi_nbIt); return (NULL); } //Dessine une fractale de Julia en calculant les racines du nombre complexe void loopJuliaReverse(Julia* jul_julia, double d_xmin, double d_xmax, double d_ymin, double d_ymax) { SDL_Rect rect_position;//Position du pixel à dessiner SDL_Surface *surf_pixel;//Pixel à dessiner double d_za;//réel représentant la partie réelle du complexe d_z double d_zb;//réel représentant la partie imaginaire du complexe d_z double d_z1a;//réel représentant la partie réelle du complexe z1 double d_z1b;//réel représentant la partie imaginaire du complexe z1 int i;//variable de boucle int i_aleat;//entier représentant un nombre aléatoire double d_ca;//réel représentant la partie réelle du complexe c double d_cb;//réel représentant la partie imaginaire du complexe c surf_pixel=SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0, 0, 0, 0); d_ca=-jul_julia->ppoint_coeffC->x; d_cb=-jul_julia->ppoint_coeffC->y; SDL_FillRect(jul_julia->surf_screen,NULL, 0x000000); for(i=0;i<500000;++i) { i_aleat=(rand()%100)/50; d_za=d_za-d_ca; d_zb=d_zb-d_cb; d_z1a=sqrt((sqrt(d_za*d_za+d_zb*d_zb)+d_za)/2); if(d_zb<0) { d_z1b = -sqrt((sqrt(d_za*d_za+d_zb*d_zb)-d_za)/2); } else { d_z1b = sqrt((sqrt(d_za*d_za+d_zb*d_zb)-d_za)/2); } rect_position.x =0.6*(d_za)*(jul_julia->surf_screen->w / (d_xmax-d_xmin))-d_xmin*100+300; rect_position.y=0.6*(d_zb)*(jul_julia->surf_screen->h /(d_ymax-d_ymin))-d_ymin*100+120; SDL_FillRect(surf_pixel, NULL, SDL_MapRGB(surf_pixel->format, 0, 150 , 150)); if(i>20) { SDL_BlitSurface(surf_pixel, NULL,jul_julia->surf_screen, &rect_position); } if(i_aleat) { d_za=d_z1a; d_zb=d_z1b; } else { d_za=-d_z1a; d_zb=-d_z1b; } } } void loopJulia(Julia* jul_julia, int* pi_nbIt, int* pi_oldIt,double d_xmin, double d_xmax, double d_ymin, double d_ymax) { double* pd_color;//Un pointeur vers un double int** ppi_tabColor;//Un tableau à deux dimensions de couleur int i_nbGradColor;//Un entier représentant le numéro de dégradé de couleur int i_px;//variable de boucle correspondant à l'abscisse d'un point sur l'écran int i_py;//variable de boucle correspondant à l'ordonnée d'un point sur l'écran double d_zX;//réel correspondant à la partie réelle du complexe Z double d_zY;//réel correspondant à la partie imaginaire du complexe Z double d_zX1;//réel correspondant à la partie réelle du complexe Z SDL_Rect rect_position;//position du pixel à dessiner SDL_Surface *surf_pixel;//Pointeur vers le pixel à dessiner i_nbGradColor=getNbGradColor(*jul_julia->pi_numGradient); ppi_tabColor=createTabColor(*jul_julia->pi_numGradient); pd_color=myMalloc(sizeof(double)*4); pd_color[0]=0; surf_pixel=SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0, 0, 0, 0); d_zX1=0; for (i_px = jul_julia->i_minX; i_px < jul_julia->i_maxX; ++i_px) { for (i_py = 0; i_py < jul_julia->i_maxY; i_py=i_py+2) { rect_position.x=i_px; rect_position.y=i_py; d_zX=d_xmin+(((double)i_px/jul_julia->surf_screen->w)*(d_xmax-d_xmin)); d_zY=d_ymin+(((double)i_py/jul_julia->surf_screen->h)*(d_ymax-d_ymin)); iterationMandelbrot(pi_nbIt,*jul_julia->pi_nbIter,d_zX,d_zY,(*jul_julia->ppoint_coeffC).x,(*jul_julia->ppoint_coeffC).y,d_zX1); colorAndPutPixel(surf_pixel, jul_julia->pi_nbIter, pi_nbIt,pd_color, ppi_tabColor, i_nbGradColor); SDL_BlitSurface(surf_pixel, NULL, jul_julia->surf_screen, &rect_position); rect_position.y=i_py-1; if((*pi_oldIt)!=(*pi_nbIt)) { iterationMandelbrot(pi_nbIt,*jul_julia->pi_nbIter,d_zX,d_ymin+(((double)(i_py-1)/jul_julia->surf_screen->h)*(d_ymax-d_ymin)),(*jul_julia->ppoint_coeffC).x,(*jul_julia->ppoint_coeffC).y,d_zX1); } colorAndPutPixel(surf_pixel, jul_julia->pi_nbIter, pi_nbIt,pd_color, ppi_tabColor, i_nbGradColor); SDL_BlitSurface(surf_pixel, NULL, jul_julia->surf_screen, &rect_position); *pi_oldIt=*pi_nbIt; } } freeLoopMandelbrotJulia(surf_pixel, i_nbGradColor, pd_color, ppi_tabColor); } //Dessine un pixel suivant le dégradé et le nombre d'itérations void colorAndPutPixel(SDL_Surface *surf_pixel, int* pi_nbIter, int* pi_nFirst, double* pd_color, int** ppi_tabColor, int i_nbGradColor ) { if(*pi_nFirst>=*pi_nbIter){ SDL_FillRect(surf_pixel, NULL, SDL_MapRGB(surf_pixel->format,0,0,0)); } else{ pd_color[0]=(*pi_nFirst*1.0)/((*pi_nbIter+2)*1.0); pd_color=colorToRGB(pd_color, ppi_tabColor,1, i_nbGradColor); SDL_FillRect(surf_pixel, NULL, SDL_MapRGB(surf_pixel->format,pd_color[1], pd_color[2] , pd_color[3])); } } //Calcule et dessine les fractales de type Ifs void* threadIfs(void* pvoid_ifs) { Ifs* ifs_ifs;//Pointeur vers une structure Ifs int i;//variable de boucle double* pd_tabProba;//tableau de probabilité double** ppd_tabCoeff;//tableau de coefficient Ifs ifs_ifs= (Ifs*)pvoid_ifs; ppd_tabCoeff= getCoeffTabFromFile(ifs_ifs->pc_fileName); pd_tabProba=getTabProba(ppd_tabCoeff, numberOfLine(ifs_ifs->pc_fileName)); ifs_ifs->i_maxColor=0; testLockScreenIfs(ifs_ifs); for (i = 0; i < ifs_ifs->surf_screen->w; i++) { free(ifs_ifs->ppi_tabColor[i]); } ifs_ifs->pd_color=myMalloc(3*sizeof(double)); createTabColorIfs(ifs_ifs); fillTabColorIfs(ifs_ifs,pd_tabProba,ppd_tabCoeff); loopDrawIfs(ifs_ifs); SDL_Flip(ifs_ifs->surf_screen); freeSpaceOfThreadFlameIfs(ppd_tabCoeff, numberOfLine(ifs_ifs->pc_fileName), pd_tabProba); return (NULL); } //Calcule et dessine les fractales de type Flame void* threadFlame(void *pvoid_flame) { Flame* flame_flame;//Pointeur vers une structure Flame char* pc_fileIfs;//Nom du fichier ifs char* pc_functionX;//Fonction de transformation en abscisse char* pc_functionY;//Fonction de transformation en ordonnée char** ppc_tabInfo;//Tableau contenant les informations extraites depuis le fichier Flame char* pc_postfixeX;//Fonction de transformation en abscisse postfixée char* pc_postfixeY;//Fonction de transformation en ordonnée postfixée flame_flame= (Flame*)pvoid_flame; testLockScreenFlame(flame_flame); if(isChoiceFileName(flame_flame->pc_fileName)) { loopFlameChoice(flame_flame,findFlameNumberFromChoice(flame_flame->pc_fileName), searchFileIfsChoice(findIfsNumberFromChoice(flame_flame->pc_fileName))); } else { ppc_tabInfo=readFileOfFlame(flame_flame->pc_fileName); pc_fileIfs=ppc_tabInfo[0]; pc_functionX=removeChar(ppc_tabInfo[1], ' '); pc_functionY=removeChar(ppc_tabInfo[2], ' '); testCorrectFlameFunction(pc_functionX,flame_flame->pc_fileName,1); testCorrectFlameFunction(pc_functionY,flame_flame->pc_fileName,2); pc_postfixeX=infixToPostfix(pc_functionX); pc_postfixeY=infixToPostfix(pc_functionY); loopFlame(flame_flame,pc_postfixeX,pc_postfixeY,pc_fileIfs); free(pc_functionY); free(pc_functionX); free(pc_postfixeY); free(pc_postfixeX); free(ppc_tabInfo); } SDL_Flip(flame_flame->surf_screen); return (NULL); } //Calcul les points (et leur couleur associée) de la fractale flamme dans le cas de transformations non prédéfinies void loopFlame(Flame* flame_flame, char* pc_postfixX, char* pc_postfixY, char* pc_fileIfs){ int i;//variable de boucle double* pd_tabProba;//tableau de probabilités double** ppd_tabCoeff;//tableau de coefficients ppd_tabCoeff= getCoeffTabFromFile(pc_fileIfs); pd_tabProba=getTabProba(ppd_tabCoeff, numberOfLine(pc_fileIfs)); flame_flame->i_maxColor=0; for (i = 0; i < flame_flame->surf_screen->w; i++) { free(flame_flame->ppi_tabColor[i]); } free(flame_flame->ppi_tabColor); createTabColorFlame(flame_flame); fillTabColorFlame(flame_flame,pd_tabProba,ppd_tabCoeff,pc_postfixX,pc_postfixY); loopDrawFlame(flame_flame); SDL_Flip(flame_flame->surf_screen); freeSpaceOfThreadFlameIfs(ppd_tabCoeff, numberOfLine(pc_fileIfs), pd_tabProba); free(pc_fileIfs); } //Calcul les points ( et leur couleur associée) de la fractale flamme dans le cas de transformations prédéfinies void loopFlameChoice(Flame* flame_flame, int i_flameNumber,char* pc_fileIfs) { int i;//variable de boucle double* pd_tabProba;//tableau de probabilités double** ppd_tabCoeff;//tableau de coefficients ppd_tabCoeff= getCoeffTabFromFile(pc_fileIfs); pd_tabProba=getTabProba(ppd_tabCoeff, numberOfLine(pc_fileIfs)); flame_flame->i_maxColor=0; for (i = 0; i < flame_flame->surf_screen->w; i++) { free(flame_flame->ppi_tabColor[i]); } free(flame_flame->ppi_tabColor); createTabColorFlame(flame_flame); fillTabColorFlameChoice(flame_flame,pd_tabProba,ppd_tabCoeff,i_flameNumber); loopDrawFlame(flame_flame); SDL_Flip(flame_flame->surf_screen); freeSpaceOfThreadFlameIfs(ppd_tabCoeff, numberOfLine(pc_fileIfs), pd_tabProba); } //Dessine les points en parcourant un tableau de couleurs de la taille de l'écran rempli lors de la fonction loopFlame void loopDrawFlame(Flame* flame_flame) { int i_px;//variable de boucle correspondant à une abscisse sur l'écran int i_py;//variable de boucle correspondant à une ordonnée sur l'écran SDL_Rect rect_position;//Position du pixel à dessiner SDL_Surface *surf_pixel;//Pixel a dessiner surf_pixel=SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0, 0, 0, 0); for (i_px = 0; i_px < flame_flame->surf_screen->w; ++i_px) { for(i_py=0;i_pysurf_screen->h;++i_py) { if(flame_flame->ppi_tabColor[i_px][2*i_py] !=0 ) { rect_position.x=i_px; rect_position.y=i_py; computingColor(flame_flame->pd_color,flame_flame->ppi_tabColor,flame_flame->i_maxColor,rect_position, flame_flame->d_light,flame_flame->i_functionMode,flame_flame->ppi_coloration,flame_flame->i_currentColor); SDL_FillRect(surf_pixel, NULL, SDL_MapRGB(surf_pixel->format,flame_flame->pd_color[0],flame_flame->pd_color[1],flame_flame->pd_color[2])); SDL_BlitSurface(surf_pixel, NULL, flame_flame->surf_screen, &rect_position); } } } SDL_FreeSurface(surf_pixel); } //Dessine les points Ifs en parcourant un tableau de couleurs de la taille de l'écran rempli lors de la fonction loopIfs void loopDrawIfs(Ifs* ifs_ifs) { int i_px;//variable de boucle correspondant à une abscisse sur l'écran int i_py;//variable de boucle correspondant à une ordonnée sur l'écran SDL_Rect rect_position;//Position du pixel à dessiner SDL_Surface *surf_pixel;//Pixel a dessiner surf_pixel=SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0, 0, 0, 0); for (i_px = 0; i_px < ifs_ifs->surf_screen->w; ++i_px) { for(i_py=0;i_pysurf_screen->h;++i_py){ if(ifs_ifs->ppi_tabColor[i_px][2*i_py] !=0 ){ rect_position.x=i_px; rect_position.y=i_py; computingColor(ifs_ifs->pd_color,ifs_ifs->ppi_tabColor,ifs_ifs->i_maxColor,rect_position,ifs_ifs->d_light, ifs_ifs->i_functionMode,ifs_ifs->ppi_coloration,ifs_ifs->i_currentColor); SDL_FillRect(surf_pixel, NULL, SDL_MapRGB(surf_pixel->format,ifs_ifs->pd_color[0]*1,ifs_ifs->pd_color[1]*1,ifs_ifs->pd_color[2])); SDL_BlitSurface(surf_pixel, NULL, ifs_ifs->surf_screen, &rect_position); } } } SDL_FreeSurface(surf_pixel); } //Libère l'espace mémoire alloué pendant le dessin de la fractale Ifs ou Flame void freeSpaceOfThreadFlameIfs(double** ppd_tabCoeff, int i_numberOfLine, double* pd_tabProba) { int i;//variable de boucle for (i = 0; i < i_numberOfLine; i++) { free(ppd_tabCoeff[i]); } free(ppd_tabCoeff); free(pd_tabProba); }