/*!\file flame.c * * \author SOUPLET Antoine * \version 1.0 * \date 10-01-2012 * * \brief Fichier contenant les fonctions relatives à la structure Flame * */ #include "functionAdd.h" #include "flame.h" #include #include #include #include "postfix.h" #include #include "functionSdl.h" //Crée une structure Flame, alloue la mémoire nécéssaire, et l'initialise Flame* initFlame(SDL_Surface *surf_screen, Point* ppoint_pInit, Point *ppoint_pitch, char* pc_fileName, double *pd_zoom, int i_nbPoint){ Flame *flame_flame;//Un pointeur vers la structure Flame à initialiser flame_flame=myMalloc(sizeof(Flame)); (*flame_flame).surf_screen=surf_screen; (*flame_flame).pd_zoom = pd_zoom; (*flame_flame).ppoint_pInit=ppoint_pInit; (*flame_flame).ppoint_pitch=ppoint_pitch; (*flame_flame).pc_fileName=pc_fileName; (*flame_flame).i_nbPoint=i_nbPoint; (*flame_flame).i_maxColor=0; createTabColorFlame(flame_flame); (*flame_flame).pd_color=myMalloc(sizeof(double)*3); flame_flame->i_lockScreen=0; flame_flame->d_light=0.8; flame_flame->i_functionMode=1; flame_flame->i_currentColor=0; flame_flame->ppi_coloration=initColoration(); return (flame_flame);//retourne la structure Flamme après initialisation } //Libère la mémoire allouée à une structure Flame et à ses attributs void freeFlame(Flame* flame_flame) { int i;//variable de boucle //libération de la mémoire allouée au tableau à deux dimensions de couleur for (i = 0; i < flame_flame->surf_screen->w; i++) {free(flame_flame->ppi_tabColor[i]); } free(flame_flame->ppi_tabColor); //libération de la mémoire allouée à la surface écran SDL_FreeSurface(flame_flame->surf_screen); //libération de la mémoire allouée aux autres attributs de la structure Flame(pointeur vers point, pointeur vers zoom...) free(flame_flame->pd_color); free(flame_flame->pd_zoom); free(flame_flame->ppoint_pInit); free(flame_flame->ppoint_pitch); //libération de la mémoire allouée au pointeur vers la structure Flame free(flame_flame); } //Alloue la mémoire nécéssaire au tableau de couleurs des fractales de type Flame void createTabColorFlame(Flame* flame_flame) { int i;//variable de boucle int j;//variabme de boucle flame_flame->ppi_tabColor=myMalloc(sizeof(int*)*(flame_flame->surf_screen->w)); for (i = 0; i < flame_flame->surf_screen->w; i++) { flame_flame->ppi_tabColor[i]=myMalloc(2*sizeof(int*)*(flame_flame->surf_screen->h)); for (j = 0; j < 2*flame_flame->surf_screen->h+2; j++) { flame_flame->ppi_tabColor[i][j]=0; } } } //Rempli le tableau de couleurs Flamme lorsque le calcul des transformations n'est pas prédéfinit, est à été précisé par l'utilisateur dans un fichier traité par l'analyseur syntaxique void fillTabColorFlame(Flame* flame_flame,double* pd_tabProba, double** ppd_tabCoeff, char* pc_postfixX, char* pc_postfixY) { int i;//variable de boucle int i_aleat;//entier correspondant au nombre aléatoire représentant la fonction Ifs int i_functionNumber;//entier représentant la fonction Ifs SDL_Rect rect_position;//rectangle correspondant à la position du pixel à dessiner for (i = 21; i < flame_flame->i_nbPoint; ++i) { i_aleat=rand()%100; i_functionNumber=0; while(i_aleat=0&& rect_position.x>=0&& rect_position.xsurf_screen->w && rect_position.ysurf_screen->h) { (flame_flame->ppi_tabColor[rect_position.x][2*rect_position.y])++; (flame_flame->ppi_tabColor[rect_position.x][(2*rect_position.y)+1])=i_functionNumber; if(flame_flame->ppi_tabColor[rect_position.x][2*rect_position.y]>flame_flame->i_maxColor) { flame_flame->i_maxColor=flame_flame->ppi_tabColor[rect_position.x][2*rect_position.y]; } } if(10*(i+1)%(flame_flame->i_nbPoint)==0) { infoWindowFlame(flame_flame,(int) i); } } } //Rempli le tableau de couleurs Flamme lorsque le calcul des points flame est prédéfinit (l'utilisateur fait un choix dans le menu parmis les flammes prédéfinit) void fillTabColorFlameChoice(Flame* flame_flame,double* pd_tabProba, double** ppd_tabCoeff, int i_flameNumber) { int i;//variable de boucle int i_aleat;//entier permettant de choisir la fonction Ifs en fonction du tableau de probabilité int i_functionNumber;//entier représentant la fonction Ifs SDL_Rect rect_position;//rectangle correspondant à la position du pixel à dessiner for (i = 21; i < flame_flame->i_nbPoint; ++i) { i_aleat=rand()%100; i_functionNumber=0; while(i_aleat=0&& rect_position.x>=0&& rect_position.xsurf_screen->w && rect_position.ysurf_screen->h) { (flame_flame->ppi_tabColor[rect_position.x][2*rect_position.y])++; (flame_flame->ppi_tabColor[rect_position.x][(2*rect_position.y)+1])=i_functionNumber; if(flame_flame->ppi_tabColor[rect_position.x][2*rect_position.y]>flame_flame->i_maxColor) { flame_flame->i_maxColor=flame_flame->ppi_tabColor[rect_position.x][2*rect_position.y]; } } if(10*(i+1)%(flame_flame->i_nbPoint)==0) { infoWindowFlameChoice(flame_flame,(int) i); } } } //Calcule des transformations n'est pas prédéfinit, est à été précisé par l'utilisateur dans un fichier traité par l'analyseur syntaxique SDL_Rect computingNewPointFlame(Flame* flame_flame, double* pd_tabCoef, char* pc_postfixX, char* pc_postfixY){ double d_X;//réel correspondant à l'abscisse du point Ifs double d_Y;//réel correspondant à l'ordonnée du point Ifs double d_resX;//réel correspondant à l'abscisse du point flamme double d_resY;//réel correspondant à l'ordonnée du point flamme SDL_Rect rect_position;//Rectangle correspondant à la position du point à retourner et à dessiner(point flamme calculé auquel on effectue les ajustements liés au zoom et au déplacement) d_Y=(pd_tabCoef[2]*flame_flame->ppoint_pInit->x+pd_tabCoef[3]*flame_flame->ppoint_pInit->y+pd_tabCoef[5]); d_X=(pd_tabCoef[0]*flame_flame->ppoint_pInit->x+pd_tabCoef[1]*flame_flame->ppoint_pInit->y+pd_tabCoef[4]); d_resX=calculPostfix(pc_postfixX,d_X,d_Y);//Calcule de l'expression postfixe, correspondant à l'abscisse,convertie précèdement depuis l'expression infixe rentrée dans un fichier par l'utilisateur d_resY=calculPostfix(pc_postfixY,d_X,d_Y);//Calcule de l'expression postfixe, correspondant à l'ordonnée, convertie précèdement depuis l'expression infixe rentrée dans un fichier par l'utilisateur flame_flame->ppoint_pInit->x=d_X; flame_flame->ppoint_pInit->y=d_Y; rect_position.x=d_resX*40*(*(flame_flame->pd_zoom))+(flame_flame->surf_screen->w)/2+(*(flame_flame->ppoint_pitch)).x*(*(flame_flame->pd_zoom)); rect_position.y=d_resY*40*(*(flame_flame->pd_zoom))+(flame_flame->surf_screen->h)/2+(*(flame_flame->ppoint_pitch)).y*(*(flame_flame->pd_zoom)); return (rect_position); } //Calcul le point flamme lorsque la fractale de type flamme est prédéfinit (l'utilisateur fait un choix dans le menu parmis les flammes prédéfinit) SDL_Rect computingNewPointFlameChoice(Flame* flame_flame, double* pd_tabCoef, int i_flameNumber){ double d_X;//réel correspondant à l'abscisse du point Ifs calculé double d_Y;//réel correspondant à l'ordonnée du point Ifs calculé Point point_pointRes;//Point correspondant aux coordonnées du point Ifs après calcul des transformations flamme SDL_Rect rect_position;//Rectangle correspondant à la position du point à retourner et à dessiner(point flamme calculé auquel on effectue les ajustements liés au zoom et au déplacement) d_Y=(pd_tabCoef[2]*flame_flame->ppoint_pInit->x+pd_tabCoef[3]*flame_flame->ppoint_pInit->y+pd_tabCoef[5]); d_X=(pd_tabCoef[0]*flame_flame->ppoint_pInit->x+pd_tabCoef[1]*flame_flame->ppoint_pInit->y+pd_tabCoef[4]); point_pointRes=calculFlame(d_X,d_Y,i_flameNumber); flame_flame->ppoint_pInit->x=d_X; flame_flame->ppoint_pInit->y=d_Y; rect_position.x=point_pointRes.x*40*(*(flame_flame->pd_zoom))+(flame_flame->surf_screen->w)/2+(*(flame_flame->ppoint_pitch)).x*(*(flame_flame->pd_zoom)); rect_position.y=point_pointRes.y*40*(*(flame_flame->pd_zoom))+(flame_flame->surf_screen->h)/2+(*(flame_flame->ppoint_pitch)).y*(*(flame_flame->pd_zoom)); return (rect_position); } //bloque le redessinage de l'écran void testLockScreenFlame(Flame* flame_flame) { if(flame_flame->i_lockScreen) { flame_flame->i_lockScreen=0; } else { SDL_FillRect(flame_flame->surf_screen,NULL, 0x000000); } } //Teste si l'utilisateur à choisit la flamme depuis le menu ou en ligne de commande et concatène les numéro de fonction flamme et ifs à pc_fileName int isChoiceFileName(char* pc_fileName) { char* pc_fileCmp;// int i; pc_fileCmp=myMalloc(sizeof(char)*10); sprintf(pc_fileCmp,"%s","choice|"); for (i = 0; i < 7; i++) { if(pc_fileCmp[i]!=pc_fileName[i]) { free(pc_fileCmp); return (0); } } free(pc_fileCmp); return(1); } //Recherche le numéro de la fractale flamme depuis une chaine de caractère int findFlameNumberFromChoice(char* pc_fileName) { char* pc_number;//chaine de boucle correspondant au numéro de fractale flamme extrait de la chaine de caractère passée en paramètre int i;//variable de boucle int i_res;//le numéro de la fractale flamme pc_number=myMalloc(8*sizeof(char)); *pc_number='\0'; for (i = 7; i < strlen(pc_fileName) && pc_fileName[i]!= '/'; ++i) { sprintf(pc_number,"%s%c",pc_number, pc_fileName[i]); } i_res=atoi(pc_number); free(pc_number); return (i_res); } //Recherche le numéro de la fractale Ifs depuis une chaine de caractère int findIfsNumberFromChoice(char* pc_fileName) { char* pc_number;//chaine de boucle correspondant au numéro de fractale flamme extrait de la chaine de caractère passée en paramètre int i;//variable de boucle int i_res;//le numéro de la fractale flamme pc_number=myMalloc(2*sizeof(char)); *pc_number='\0'; for (i = strlen(pc_fileName)-2; i=0 && d_Y>=0) point_point=pointInit(d_X,d_Y); if(d_X<0 && d_Y>=0) point_point=pointInit(2*d_X,d_Y); if(d_X>=0 && d_Y<0) point_point=pointInit(d_X,d_Y/2); if(d_X<0 && d_Y<0) point_point=pointInit(2*d_X,d_Y/2); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 15 Point computeFlameV15(double d_X, double d_Y) { Point point_point;//Point à retourner après transformation flamme point_point=pointInit(d_X-0.15*sin(d_Y/(0.12*0.12)),d_Y+0.45*sin(d_X/(0.45*0.45))); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 16 Point computeFlameV16(double d_X, double d_Y) { double d_R;//Module de X,Y d_R=sqrt(d_Y*d_Y+d_X*d_X); Point point_point;//Point à retourner après transformation flamme point_point=pointInit((2/(d_R+1))*d_X,(2/(d_R+1))*d_Y); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 17 Point computeFlameV17(double d_X, double d_Y) { Point point_point;//Point à retourner après transformation flamme point_point=pointInit(d_X+0.23*sin(tan(3*d_Y)),d_Y-0.045*sin(tan(3*d_X))); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 18 Point computeFlameV18(double d_X, double d_Y) { Point point_point;//Point à retourner après transformation flamme point_point=pointInit(exp(d_X-1)*cos(PI*d_Y),exp(d_X-1)*sin(PI*d_Y)); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 19 Point computeFlameV19(double d_X, double d_Y) { double d_R;//Module de X,Y int i_aleat;//entier aleatoire i_aleat=rand()%2; d_R=sqrt(d_Y*d_Y+d_X*d_X); Point point_point;//Point à retourner après transformation flamme if(i_aleat) { point_point=pointInit(+pow(d_R,sin(atan(d_X/d_Y)))*cos(atan(d_X/d_Y)),pow(d_R,sin(atan(d_X/d_Y)))*sin(atan(d_X/d_Y))); } else { point_point=pointInit(-pow(d_R,sin(atan(d_X/d_Y)))*cos(atan(d_X/d_Y)),pow(d_R,sin(atan(d_X/d_Y)))*sin(atan(d_X/d_Y))); } return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 20 Point computeFlameV20(double d_X, double d_Y) { Point point_point;//Point à retourner après transformation flamme point_point=pointInit(cos(PI*d_X)*cosh(d_Y),-sin(PI*d_X)*sinh(d_Y)); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 27 Point computeFlameV27(double d_X, double d_Y) { double d_R;//Module de X,Y Point point_point;//Point à retourner après transformation flamme d_R=sqrt(d_Y*d_Y+d_X*d_X); point_point=pointInit((2/(d_R+1))*d_X,(2/(d_R+1))*d_Y); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 28 Point computeFlameV28(double d_X, double d_Y) { double d_R;//Module de X,Y Point point_point;//Point à retourner après transformation flamme d_R=sqrt(d_Y*d_Y+d_X*d_X); point_point=pointInit((4/(d_R*d_R+4))*d_X,(4/(d_R*d_R+4))*d_Y); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 29 Point computeFlameV29(double d_X, double d_Y) { Point point_point;//Point à retourner après transformation flamme point_point=pointInit(sin(d_X), d_Y); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 42 Point computeFlameV42(double d_X, double d_Y) { Point point_point;//Point à retourner après transformation flamme point_point=pointInit((sin(d_X)/cos(d_Y)),tan(d_Y)); return(point_point); } //Calcul des nouvelles coordonnées du point transformé par la variation 48 Point computeFlameV48(double d_X, double d_Y) { Point point_point;//Point à retourner après transformation flamme point_point=pointInit(sqrt(1/pow((d_X*d_X-d_Y*d_Y),2))*d_X,sqrt(1/pow((d_X*d_X-d_Y*d_Y),2))*d_Y); return(point_point); }