#include "easypap.h" #include #include // Les données disponibles sont les suivantes // Attention lors du lancement à bien signaler la taille pour que l'image générée soit correcte // Par exemple pour la dalle grd il faudra ajouter -s 1025 à votre ligne de lancement // Il y a également une valeur cst qui permet de générer une image relative aux flots d'accumulation. //static char* filename = "data/mnt/petit.txt"; // ce fichier correspond à l'exemple de la fiche ipynb 6x6 //static int cst = 100; //static char* filename = "data/mnt/jeu_essai.txt"; // ce fichier correspond à un extrait 32 x 32 de la dalle grd //static int cst = 100; //static char* filename = "data/mnt/grd_618360_6754408.txt"; // ce fichier correspond à la dalle grd complète 1025x1025 //static int cst = 10000; static char* filename = "data/mnt/alpes.txt"; // ce fichier correspond aux données sur les alpes 1024x1024 static int cst = 10000; static float no_value; static int no_dir_value = -9; static int no_bassin_value = -10; static int nb_lignes; static int nb_cols; // Les tableaux pour constuire le terrain à partir du mnt et calculer les directions. // Attention terrain est défini avec 2 lignes supplémentaires pour permettre des ghosts static float* terrain; static int* direction; static int* accumulation; static int* bassin; // Tableaux prédéfinis pour tester si un voisinage se déverse dans // une cellule. Trois cas pour gérer le cas général et les 2 bords (droit et gauche) static int dir_bord1[5]={5,6,7,8,1}; static int dir_bord2[5]={1,2,3,4,5}; static int dir_general[8]={5,6,7,8,1,2,3,4}; // Cette fonction permet de lire le fichier, d'initialiser nb_lignes, nb_cols et de construire terrain. void lecture_mnt(char* nom); // La fonction pour calculer les directions est déjà implémentée // Elle prend en paramètre un terrain (paramètre data) et elle renvoie les directions dans le tableau dir. // Attention data est de taille (n_l+2) x n_c afin de prendre en compte les ghosts. // Ce n'est pas nécessaire en séquentiel mais cette fonction sera disponible également pour votre parallélisation. // dir est de taille n_l x n_c void calcul_direction(float *data, int *dir, int n_l, int n_c); int f_bord1(float ref, float* tab, float no_value); int f_bord2(float ref, float* tab, float no_value); int f(float ref, float* tab, float no_value); // la fonction conversion est une proposition pour convertir les directions // en une couleur pour visualiser les directions calculées int conversion(int val); // la fonction conversion_acc est une proposition pour convertir les flots d'accumulation // en une couleur int conversion_acc(int val); // la fonction conversion_bassin est une proposition pour convertir le n° d'un bassin par une couleur. int conversion_bassin(int val); // Les fonctions pour échanger les ghosts (une fonction pour des floats et une pour les int) void echange_ghosts(float* data, int n_l, int n_c); void echange_ghosts_int(int* data, int n_l, int n_c); // Les 2 fonctions pour le calcul des flots d'accumulation // calcul_accumulation réalise une itération du calcul et // renvoie une valeur indiquant si des cellules ont été mises // et donc s'il faut poursuivre les itérations. // f_acc calcule le flot d'accumulation d'une cellule c à partir // de tab qui stocke le voisinage suivi des directions impliquées // dir_bord est un tableau permettant de tester si une cellule // du voisinage se déverse dans c. unsigned calcul_accumulation(int *dir, int *acc, int n_l, int n_c); int f_acc(int* tab, int no_value, int* dir_bord, int l); // Pour le bassin versant void calcul_bassin(int *bassin, int *dir, int n_l, int n_c); int f_bassin(int* bassin, int *dir, int n_l, int n_c, int i, int j); static int num = 100; //////////////////////////////////// // Les trois fonctions EasyPAP pour la partie séquentielle void mnt_init (void) { PRINT_DEBUG ('u', "Image size is %dx%d\n", DIM, DIM); PRINT_DEBUG ('u', "Block size is %dx%d\n", TILE_W, TILE_H); PRINT_DEBUG ('u', "Press to pause/unpause, to quit.\n"); } int mnt_do_tile_default (int x, int y, int width, int height) { for (int i = y; i < y + height; i++) for (int j = x; j < x + width; j++) cur_img (i, j) = conversion(direction[(i+1)*DIM+j]); return 0; } int mnt_do_tile_accumulation (int x, int y, int width, int height) { for (int i = y; i < y + height; i++) for (int j = x; j < x + width; j++) cur_img (i, j) = conversion_acc(accumulation[(i+1)*DIM+j]); return 0; } int mnt_do_tile_bassin (int x, int y, int width, int height) { for (int i = y; i < y + height; i++) for (int j = x; j < x + width; j++) cur_img (i, j) = conversion_bassin(bassin[i*DIM+j]); return 0; } // Attention afin de ne pas avoir trop de cas particulier // La version séquentielle utilise les fonctions proposées // pour la version paralléle et donc travaille sur des matrices // qui ont deux lignes supplémentaires (comme si on gérait déjà des // ghosts. unsigned mnt_compute_seq(unsigned nb_iter) { for (unsigned it = 1; it <= nb_iter; it++) { lecture_mnt(filename); calcul_direction(terrain, direction + nb_cols, nb_lignes, nb_cols); // Pour utiliser une fonction disponible pour la version parallèle // il y a deux lignes supplémentaires dans direction // la première est mise à 1 pour indiquer que la cellule correspondante // se déverse vers le haut // la dernière est mise à 5 pour indiquer que la cellule correspondante // se déverse vers le bas for (int i = 0; i < nb_cols; i++) { direction[i] = 1; direction[(nb_lignes + 1) * nb_cols + i] = 5; } // Pour les flots d'accumulations les 2 lignes supplémentaires sont // mises à 0. Mais via la convention de la matrice direction // on n'utilisera pas ces lignes dans le calcul. for (int i = 0; i < nb_cols; i++) { accumulation[i] = 0; accumulation[(nb_lignes + 1) * nb_cols + i] = 0; } // Le reste de la matrice est initialisée à -1 pour non marqué. for (int i = 0; i < nb_lignes; i++) for (int j = 0; j < nb_cols; j++) accumulation[(i + 1) * nb_cols + j] = -1; int stop = 0; while (stop != 1) { stop = calcul_accumulation(direction, accumulation, nb_lignes, nb_cols); } bassin = (int*) malloc(nb_lignes*nb_cols* sizeof(int)); for (int i=0; i255) color = rgba(255,0,0,255); else color = rgba((int)(test*cst),0,0,255); } return color; } int conversion_bassin(int val) { static unsigned couleur0[4] = {0,127,0,255}; static unsigned couleur1[4] = {255,0,0,255}; static unsigned couleur2[4] = {127,255,0,255}; static unsigned couleur3[4] = {255,127,0,255}; static unsigned couleur4[4] = {127,255,127,255}; static unsigned couleur5[4] = {0,0,255,255}; static unsigned couleur6[4] = {0,255,127,255}; static unsigned couleur7[4] = {255,255,255,255}; static unsigned couleur8[4] = {127,127,127,255}; static unsigned couleur9[4]= {0,255,0,255}; int v = val%10; if (val ==-10) return rgba(0,0,0,255); else { switch (v) { case 0: return rgba(couleur0[0], couleur0[1], couleur0[2], couleur0[3]); case 1: return rgba(couleur1[0], couleur1[1], couleur1[2], couleur1[3]); case 2: return rgba(couleur2[0], couleur2[1], couleur2[2], couleur2[3]); case 3: return rgba(couleur3[0], couleur3[1], couleur3[2], couleur3[3]); case 4: return rgba(couleur4[0], couleur4[1], couleur4[2], couleur4[3]); case 5: return rgba(couleur5[0], couleur5[1], couleur5[2], couleur5[3]); case 6: return rgba(couleur6[0], couleur6[1], couleur6[2], couleur6[3]); case 7: return rgba(couleur7[0], couleur7[1], couleur7[2], couleur7[3]); case 8: return rgba(couleur8[0], couleur8[1], couleur8[2], couleur8[3]); case 9: return rgba(couleur9[0], couleur9[1], couleur9[2], couleur9[3]); } } return rgba(50,50,50,255); }