#include "functionAdd.h" #include "check.h" #include "lSystem.h" #include "drawGeo.h" #include "functionSdl.h" #include "stack.h" #include #include #include //Crée un pointeur vers une structure L-System, alloue la mémoire nécéssaire et initialise la structure Lsystem* initLsystem(SDL_Surface* surf_screen, double* pd_zoom, Point* ppoint_pInit, char* pc_fileName, int* pi_indice) { Lsystem* lsyst_lSystem;//le pointeur vers la structure à initialiser lsyst_lSystem=myMalloc(sizeof(Lsystem));//allocation mémoire nécéssaire à la structure Lsystem (*lsyst_lSystem).surf_screen=surf_screen; (*lsyst_lSystem).pd_zoom = pd_zoom; (*lsyst_lSystem).ppoint_pInit=ppoint_pInit; (*lsyst_lSystem).pc_fileName=pc_fileName; (*lsyst_lSystem).pi_indice=pi_indice; return (lsyst_lSystem);//retourne la structure après avoir été initialisée } //Libère l'espace mémoire alloué à la structure Lsystem et à ses attributs void freeLsystem(Lsystem* lsyst_lSystem) { int i;//variable de boucle SDL_FreeSurface(lsyst_lSystem->surf_screen); free(lsyst_lSystem->pd_zoom); free(lsyst_lSystem->pi_indice); free(lsyst_lSystem->ppoint_pInit); free(lsyst_lSystem->pc_tabFinal); for (i = 0; i < strlen(lsyst_lSystem->pc_tabVariable)/2+1; i++) { free(lsyst_lSystem->ppc_rules[i]); } free(lsyst_lSystem->pc_tabVariable); free(lsyst_lSystem->ppc_rules); free(lsyst_lSystem); } //Modifie des attributs de la structure lSystem void setLsystem(Lsystem *lsyst_lSystem, double d_angle, double d_longueur, char** ppc_rules, char* pc_tabVariable, char* pc_tabFinal) { (*lsyst_lSystem).d_angle = d_angle; (*lsyst_lSystem).d_longueur = d_longueur; (*lsyst_lSystem).pc_tabVariable = pc_tabVariable; (*lsyst_lSystem).pc_tabFinal = pc_tabFinal; (*lsyst_lSystem).ppc_rules = ppc_rules; } //Lance le traitement des fractales de type L-System void runLsystem(Lsystem* lsyst_lSystem) { int i;//variable de boucle int i_nbRules;//entier correspondant au nombre de règles char* pc_tabAngle;//chaine de caractère contenant l'angle char* pc_longueur;//chaine de caractère contenant la longueur char* pc_tabVariable;//chaine de caractère contenant les variables L-System char** ppc_rules;//tableau de chaines de caractères contenant toutes les règles associées aux variables L-System ainsi que l'axiome char** ppc_tabInfoFile;//tableau de chaines de caractères dans lequel on extrait les différentes informations contenues dans un fichier L-System ppc_tabInfoFile=readFileOfLsystem(lsyst_lSystem->pc_fileName);//extrait les informations du fichier L-System dans un tableau de chaines de caractères pc_tabAngle=ppc_tabInfoFile[1]; pc_longueur=ppc_tabInfoFile[2]; pc_tabVariable=ppc_tabInfoFile[0]; removeChar(pc_tabVariable,';'); i_nbRules=strlen(pc_tabVariable)/2; ppc_rules=myMalloc(100*sizeof(char*)); ppc_rules[0]=removeChar(ppc_tabInfoFile[3], ' '); for (i = 0; i < i_nbRules*2; i=i+2) { ppc_rules[i/2+1]=removeChar(ppc_tabInfoFile[i/2+4], ' '); } infoWindowLsystem(lsyst_lSystem, "en cours"); setLsystem(lsyst_lSystem, atof(pc_tabAngle),atof(pc_longueur),ppc_rules,pc_tabVariable, createFinalArray(ppc_rules, pc_tabVariable, *lsyst_lSystem->pi_indice)); free(pc_tabAngle); free(pc_longueur); free(ppc_tabInfoFile); drawFractalSystem(lsyst_lSystem);//Dessine la fractale L-System waitEventLSystem(lsyst_lSystem);//Attends un évènement } //Dessine les fractales de type L-Ssytem void drawFractalSystem(Lsystem* lsyst_lSystem) { int i;//variable de boucle int i_nbIter;//entier correspondant au nombre d'itérations double* pd_angleCurrent;//pointeur vers un réel correspondant à l'angle en cours Point* ppoint_pSec;//pointeur vers un point correspondant au point après calcul Point* ppoint_pInit;//pointeur vers un point correspondant au point avant calcul stack** st_saveCoordAndAngle;//pointeur vers une pile permettant la sauvegarde des coordonnées et de l'angle en cas de caractère '[' et ']' pd_angleCurrent=myMalloc(sizeof(double*)); *pd_angleCurrent=0; SDL_FillRect(lsyst_lSystem->surf_screen, NULL, SDL_MapRGB(lsyst_lSystem->surf_screen->format, 0, 0, 0)); ppoint_pInit=pointInitAndSetByPoint(*(lsyst_lSystem->ppoint_pInit)); ppoint_pSec=pointInitAndSet(0,0); st_saveCoordAndAngle=stack_new(); i_nbIter=strlen(lsyst_lSystem->pc_tabFinal); for (i=0;ipc_tabFinal[i], ppoint_pInit, ppoint_pSec, pd_angleCurrent)) { exitErrorGeneralSyntax(lsyst_lSystem->pc_fileName);//quitte le programme après avoir affiché un message d'erreur } } } infoWindowLsystem(lsyst_lSystem, "Terminé"); SDL_Flip(lsyst_lSystem->surf_screen); freeStack(st_saveCoordAndAngle); free(ppoint_pSec); free(ppoint_pInit); free(pd_angleCurrent); } //Cherche le parametre correspondant au caractère en cours de lecture et modifie l'angle courant ou les coordonnées des points en fonction en fonction du paramètre int checkCharAndSetParameters(Lsystem* lsyst_lSystem, int i_cpt, Point* ppoint_pInit, Point* ppoint_pSec, stack** st_saveCoordAndAngle, double* pd_angleCurrent) { char c_value;//caractère en cours de lecture c_value=lsyst_lSystem->pc_tabFinal[i_cpt]; if(c_value=='+') { *pd_angleCurrent = *pd_angleCurrent + lsyst_lSystem->d_angle; return (1); } else if(c_value=='-') { *pd_angleCurrent = *pd_angleCurrent - lsyst_lSystem->d_angle; return (1); } else if(c_value=='.') { *pd_angleCurrent = *pd_angleCurrent + 180; return (1); } else if(c_value==']') { if(*st_saveCoordAndAngle==NULL) { exitErrorSyntaxSym(lsyst_lSystem->pc_fileName); } (*ppoint_pInit).y=stack_pop(st_saveCoordAndAngle).d_value;//Dépile l'ordonnée du dernier point sauvegardé dans la pile (*ppoint_pInit).x=stack_pop(st_saveCoordAndAngle).d_value;//Dépile l'abscisse du dernier point sauvegardé dans la pile *pd_angleCurrent=stack_pop(st_saveCoordAndAngle).d_value;//Dépile le dernier angle sauvegardé dans la pile return (1); } else if(c_value=='[') { pushInStackValues(st_saveCoordAndAngle, ppoint_pInit, pd_angleCurrent);//Empile les coordonnées du point en cours et l'angle à sauvegarder return (1); } return (0); } //Empile les coordonnées du point en cours et l'angle à sauvegarder void pushInStackValues(stack** st_saveCoordAndAngle, Point* ppoint_point, double* pd_angleCurrent) { uCharDouble ucd_valueX;//L'abscisse du point à sauvegarder uCharDouble ucd_valueY;//L'ordonnée du point à sauvegarder uCharDouble ucd_valueAngle;//La valeur de l'angle à sauvegarder ucd_valueX.d_value=(*ppoint_point).x; ucd_valueY.d_value=(*ppoint_point).y; ucd_valueAngle.d_value=*pd_angleCurrent; stack_push(st_saveCoordAndAngle,ucd_valueAngle); stack_push(st_saveCoordAndAngle,ucd_valueX); stack_push(st_saveCoordAndAngle,ucd_valueY); } //Recherche la règle correspondant au caractère en train d'être lu int checkRulesAndSetParameters(Lsystem* lsyst_lSystem, char c_value, Point* ppoint_pInit, Point* ppoint_pSec, double* pd_angleCurrent) { int i;//variable de boucle for (i = 0; i < strlen(lsyst_lSystem->pc_tabVariable); i=i+2) { if (c_value==lsyst_lSystem->pc_tabVariable[i]) { *ppoint_pSec = pointInit((*ppoint_pInit).x + cos((*pd_angleCurrent)*PI/180)*lsyst_lSystem->d_longueur*(*lsyst_lSystem->pd_zoom), ((*ppoint_pInit).y)-sin((*pd_angleCurrent)*PI/180)*lsyst_lSystem->d_longueur*(*lsyst_lSystem->pd_zoom)); if(lsyst_lSystem->pc_tabVariable[i+1]=='~') { drawLine(lsyst_lSystem->surf_screen,(*ppoint_pInit).x,(*ppoint_pInit).y,(*ppoint_pSec).x,(*ppoint_pSec).y); } *ppoint_pInit = pointInit((*ppoint_pSec).x, (*ppoint_pSec).y); return (1); } } return (0); } //Crée le tableau de caractère correspondant à l'axiome et aux règles, que l'on développe jusqu'au rang passé en paramètre char* createFinalArray(char** ppc_rules, char* pc_tabVariable, int i_indice) { char* pc_tabTmp;//chaine de caractère correspondant à un tableau de caractère temporaire char* pc_tabFinal;//chaine de caractère correspondant au tableau de caractère à retourner int i;//variable de boucle int j;//variable de boucle pc_tabTmp=myMalloc((i_tabSize)*sizeof(char)); strcpy(pc_tabTmp, ppc_rules[0]); pc_tabFinal=myMalloc(sizeof(char)*i_tabSize); *pc_tabFinal='\0';//efface tous les caractères for (j = 0; j < i_indice; j++) { if(strlen(pc_tabFinal)!=0) { strcpy(pc_tabTmp,pc_tabFinal); *pc_tabFinal='\0';//efface tous les caractères } for (i = 0; i < i_tabSize && pc_tabTmp[i] != '\0'; i++) { concatCharToString(pc_tabTmp[i], pc_tabVariable, pc_tabFinal, ppc_rules); } } free(pc_tabTmp); return (pc_tabFinal); } //Concatène au tableau final le caractère en cours de lecture void concatCharToString(char c_value, char* pc_tabVariable, char* pc_tabFinal, char** ppc_rules) { int i;//variable de boucle if (c_value=='+') { strcat(pc_tabFinal,"+"); } else if (c_value=='-') { strcat(pc_tabFinal,"-"); } else if (c_value=='.') { strcat(pc_tabFinal,"."); } else if (c_value=='[') { strcat(pc_tabFinal,"["); } else if (c_value==']') { strcat(pc_tabFinal,"]"); } else { for(i=0 ; i