------------------------------------------------------------------------------------------------ -- Nom : Power_Tools / fait partie du programme Power Fractal -- -- -- -- Auteurs : Gregory Burri & Adrien Crivelli -- ------------------------------------------------------------------------------------------------ -- But : Outils de hauts niveau pour le tracage, le recadrage et le centrage -- -- sur la fractal a l'Ecran. -- ------------------------------------------------------------------------------------------------ with Ada.Text_IO; use Ada.Text_IO; with Power_Calculator; with Power_Colors; with Power_Draw; use Power_Draw; with Spider; with Spider.Draw; with Spider.User; use Spider.User; --Enfant gerant la souris et le clavier with Power_List; with Ada.Numerics; use Ada.Numerics; with Ada.Numerics.Generic_Elementary_Functions; package body Power_Tools is ------------------------------------------------------------------------------------------------ -- Nom : Dessiner_Fractal -- -- But : Dessiner la fracal a l'ecran -- -- -- -- Parametres ---------------------------------------------------------------------------------- -- In : * La fractal a dessiner -- -- -- ------------------------------------------------------------------------------------------------ procedure Dessiner_Fractal (Fractal : in Cara_Fractal; X, Y : Natural := 0; Largeur_Zone : Natural := Largeur_Ecran; Hauteur_Zone : Natural := Hauteur_Ecran) is use Power_Calculator; use Power_Colors; Degrade : T_Tab_Couleur(1 .. Fractal.Nb_Iteration_Max); --Le deegrade de couleur -------------------------------------------tests---------------------------------------- --2 si la matrice doit etre calcule quatre fois plus grande sinon 1 Quadruple : Natural := Boolean'Pos(Fractal.Antialiasing) + 1; --les dimensions de la zone de calcul, elles sont double si l'antialiasing est active Largeur_Zone_Anti : Natural := Largeur_Zone * Quadruple + Boolean'Pos(Fractal.Antialiasing); Hauteur_Zone_Anti : Natural := Hauteur_Zone * Quadruple + Boolean'Pos(Fractal.Antialiasing); -- --La matrice d'iteration Matrice_Iteration : T_Matrice_Iteration (0..Largeur_Zone_Anti, 0..Hauteur_Zone_Anti); begin -- Dessiner_Fractal New_Line; Put(" Matrix... "); --Si la fractal est de type mandelbrot alors if Fractal.Ensemble = Mandelbrot then --Calcul la fractal sur l'ensemble de mandelbrot Matrice_Iteration := Mandel_Gen (Largeur_Zone_Anti, Hauteur_Zone_Anti, Fractal); else --sinon (Julia) --Calcul la fractal sur l'ensemble de julia Matrice_Iteration := Julia_Gen (Largeur_Zone_Anti, Hauteur_Zone_Anti, Fractal); end if; --Si la procedure a ete appelle avec les parametres par defaut if Largeur_Zone = Largeur_Ecran and Hauteur_Zone = Hauteur_Ecran then --Si l'antialiasing est active alors if Fractal.Antialiasing then --Utilise la matrice qui fait le quadruple de taille de l'ecran Matrice_Iteration_Global := (True, Matrice_Iteration); else --Utilise la matrice normale Matrice_Iteration_Global := (False, Matrice_Iteration); end if; else --sinon (dimension arbitraire) --Si l'antialiasing est actif alors if Fractal.Antialiasing then --Copie la 'petite' matrice dans la grande globale --Le coin de la petite est au coordonnees xy for I in Matrice_Iteration'range(1) loop for J in Matrice_Iteration'range(2) loop --Dessine la sous matrice calcule de la matrice tampon sur l'ecran Matrice_Iteration_Global.Matrice_Iteration_Anti(I + 2 * X, J + 2 * Y) := Matrice_Iteration(I, J); end loop; end loop; else --Copie la 'petite' matrice dans la grande globale --Le coin de la petite est au coordonnees xy for I in Matrice_Iteration'range(1) loop for J in Matrice_Iteration'range(2) loop Matrice_Iteration_Global.Matrice_Iteration(I + X, J + Y) := Matrice_Iteration(I, J); end loop; end loop; end if; end if; Put_Line("OK"); -- Put(" Colors... "); -- Creer_Degrade(Fractal, Degrade, Fractal.Nb_Iteration_Max); --Calcul le degrade -- Put_Line("OK"); Put(" Conversion... "); --Si l'antialiasing est active alors if Fractal.Antialiasing then --Calcul la matrice de sortie avec antialiasing Matrice_Tampon_Ecran :=Calcul_Antialiasing(Conversion_Couleur (Matrice_Iteration_Global.Matrice_Iteration_Anti, fractal)); else --Calcul la matrice de sortie (sans antialiasing) Matrice_Tampon_Ecran := Conversion_Couleur (Matrice_Iteration_Global.Matrice_Iteration, fractal); end if; --Si l'affichage du degrade est actif alors if Fractal.Dessine_Degrade and Largeur_Zone = Largeur_Ecran and Hauteur_Zone = Hauteur_Ecran then Affiche_Degrade(Fractal); --Affiche le degrade (dans le tampon) end if; Put_Line("OK"); Put(" Drawing... "); -- Parcours chaque colonne de l'ecran for I in Largeur_Zone / 2 + X..Largeur_Zone + X loop --Dessine un colonne depuis le tampon a droite du cantre Ligne_Matrice_Vert (Y, Y + Hauteur_Zone, I); --Dessine un colonne depuis le tampon a gauche du centre Ligne_Matrice_Vert (Y, Y + Hauteur_Zone, 2 * X - I + Largeur_Zone); end loop; Put_Line("OK"); end Dessiner_Fractal; ------------------------------------------------------------------------------------------------ -- Nom : Rafraichir_couleur -- -- But : Mets a jour les couleur et dessinne la fractal -- -- -- -- Parametres ---------------------------------------------------------------------------------- -- In : * La fractal a dessiner -- -- -- ------------------------------------------------------------------------------------------------ procedure Rafraichir_Couleur (Fractal : in Cara_Fractal) is use Power_Calculator; use Power_Colors; Degrade : T_Tab_Couleur(1 .. Fractal.Nb_Iteration_Max); --Le deegrade de couleur begin -- Rafraichir_Couleur New_Line; -- Put(" Colors... "); -- Creer_Degrade(Fractal, Degrade, Fractal.Nb_Iteration_Max); --Calcul le degrade -- Put_Line("OK"); Put(" Conversion... "); --Si l'antialiasing est active alors if Fractal.Antialiasing then --Calcul la matrice de sortie avec antialiasing Matrice_Tampon_Ecran := Calcul_Antialiasing (Conversion_Couleur(Matrice_Iteration_Global.Matrice_Iteration_Anti, fractal)); else --Calcul la matrice de sortie (sans antialiasing) Matrice_Tampon_Ecran := Conversion_Couleur (Matrice_Iteration_Global.Matrice_Iteration, fractal); end if; --Si l'affichage du degrade est actif alors if Fractal.Dessine_Degrade then Affiche_Degrade(Fractal); --Affiche le degrade (dans le tampon) end if; Put_Line("OK"); Put(" Drawing... "); -- Parcours chaque colonne de l'ecran for X in Largeur_Ecran / 2..Largeur_Ecran loop --Dessine un colonne depuis le tampon a droite du cantre Ligne_Matrice_Vert (0, Hauteur_Ecran, X); --Dessine un colonne depuis le tampon a gauche du centre Ligne_Matrice_Vert (0, Hauteur_Ecran, Largeur_Ecran - X); end loop; Put_Line("OK"); end Rafraichir_Couleur; ------------------------------------------------------------------------------------------------ -- Nom : Zoom_Souris -- -- But : Tracer un cadre a la souris pour zoomer -- -- et clic-droit pour dezoomer (recentre au coordonnees de la sourris) -- -- -- -- -- Parametres ---------------------------------------------------------------------------------- -- In : * la fractal sur laquelle zoomer -- -- -- ------------------------------------------------------------------------------------------------ procedure Zoom_Souris(Fractal : in out Cara_Fractal) is --La distance [px] entre le haut de la croix et l'arete superieur du cadre de zoom --si cette distance est inferieur a une certaine valeur alors efface la croix, sinon affiche --la croix Distance_Visible : constant := 10 + Rayon_Ext_Croix; X1, Y1, --Coordonnees du centre du cadre X2, Y2, --Coordonnees de la souris lors du tracage du cadre X2_Avant, Y2_Avant : Integer := 0; --Pour sauvegarder des coordonnees Clic_Droit : Boolean; --Si un clic droit a lieu Clic_Gauche : Boolean; --Si un clic Gauche a lieu Clic_Clavier : Boolean; --Si une touche est pressee Touche : Character; --La touche presse X1_Float, Y1_Float , --Les coordonnees du centre par rapport au unite reel --Les coordonnees du coin inferieur droit ou gauche du cadre de zoom en unite reel X2_Float, Y2_Float : Long_Float; --La Largeur et la longueur en float (evite de devoir faire plusieurs fois la convertion Largeur_Zone_Tmp_Float : Long_Float := Long_Float(Largeur_Ecran); Hauteur_Zone_Tmp_Float : Long_Float := Long_Float(Hauteur_Ecran); -- Pre_Calcul : Long_Float; --Precalcul d'un partie du calcul Croix : Boolean; --Pour savoir si la croix est affiche ou non begin -- Zoom_Souris --Boucle pour pouvoir zoomer ou dezoomer plusieur fois de suite sans taper la commande loop --Initialise les flags pour le clavier et la souris Touche := Vide; Clic_Clavier := False; Clic_Droit := False; Clic_Gauche := False; -- Croix := False; --ne dessine pas la croix --Boucle s'executant jusqu'a qu'un clic soit fait ou que la touche ESC soit presses while not Clic_Droit and not Clic_Gauche and not (Clic_Clavier and Touche = Echape) loop Right_Clic(X2, Y2, Clic_Droit); --Lorsque un clic-droit arrive Left_Clic(X1, Y1, Clic_Gauche); --Lorsque un clic-gauche arrive Key_Pressed(Touche, Clic_Clavier); --Lorsque une touche est presse Sleep(10); --Redonne la main au systeme pendant 10ms end loop; --Si il y a eu la touche ESC presse alors quitte la procedure if Clic_Clavier and Touche = Echape then return; end if; Clic_Clavier := False; --Remet a faux le flag du clavier --Si un clic gauche a est effectue if Clic_Gauche then Clic_Gauche := False; --Remet a faux le flag du clic gauche Spider.Move_To(X1, Y1); --Lit les coordonnees de la souris --Copie des coordonnees de la souris dans XY2 X2 := X1; Y2 := Y1; --Sauvegarde Les coordonnees XY2 X2_Avant := X2; Y2_Avant := Y2; --Attends un autre clic-Gauche while not Clic_Gauche loop Mouse(X2, Y2); --Lit les coordonnees de la souris --Calcul Y2 en fonction de X1 en tenant compte des proportion de la zone de dessin Y2 := Y1 + ((X2-X1) * Hauteur_Ecran / Largeur_Ecran); --Si le cadre vient a depasser de l'ecran (impossible a afficher) alors if X2 not in 0..Largeur_Ecran or (-X2 + 2*X1) not in 0..Largeur_Ecran or Y2 not in 0..Hauteur_Ecran or (-Y2 + 2*Y1) not in 0..Hauteur_Ecran then --Remets les coordonnes du passage precedant Y2 := Y2_Avant; X2 := X2_Avant; -- end if; --Si le bord superieur est plus bas que la hauteur de la croix + 'Distance_Visible' --et que la croix est affichee alors if Y2 in (Y1 - Distance_Visible)..(Y1 + Distance_Visible) and Croix then Efface_Croix(X1, Y1); --Efface la croix Croix := False; --La croix n'est pas affichee --Si le bord superieur est plus haut que la hauteur de la croix + 'Distance_Visible' --et que la croix n'est pas affichee alors elsif Y2 not in (Y1 - Distance_Visible)..(Y1 + Distance_Visible) and not Croix then Dessin_Croix(X1, Y1); --Efface la croix Croix := True; --La croix est affichee end if; --------------------------------- --Dessine une boite : avec le point XY1 au centre Boite((-X2 + 2*X1), (-Y2 + 2*Y1), X2, Y2, Couleur_Cadre); --Si les lignes verticales du cadre ont bougees --par rapport au passage d'avant alors if X2 /= X2_Avant then --Efface les lignes verticales au coordonnees d'avant (XY2_Avant) Ligne_Matrice_Vert((-Y2_Avant + 2*Y1),Y2_Avant, X2_Avant); Ligne_Matrice_Vert((-Y2_Avant + 2*Y1),Y2_Avant, (-X2_Avant + 2*X1)); end if; --Si les lignes horizontales du cadre ont bougees --par rapport au passage d'avant alors if Y2 /= Y2_Avant then --Efface les lignes horizontales au coordonnees d'avant (XY2_Avant) Ligne_Matrice_Hori((-X2_Avant + 2*X1),X2_Avant, Y2_Avant); Ligne_Matrice_Hori((-X2_Avant + 2*X1),X2_Avant, (-Y2_Avant + 2*Y1)); end if; Sleep(10); --Redonne la main au system pendant 10ms --Sauvegarde les coordonnees courantes X2_Avant := X2; Y2_Avant := Y2; -- Key_Pressed(Touche, Clic_Clavier); --Lorsqu'une touche est pressee --Si la touche ESC est pressee if Clic_Clavier and Touche = Echape then --Efface le cadre Ligne_Matrice_Hori((-X2 + 2*X1),X2, Y2); Ligne_Matrice_Hori((-X2 + 2*X1),X2, (-Y2 + 2 * Y1)); Ligne_Matrice_Vert((-Y2 + 2*Y1),Y2, X2); Ligne_Matrice_Vert((-Y2 + 2*Y1),Y2, (-X2 + 2 * X1)); -- --Si la croix est presente a l'ecran alors l'efface if Croix then Efface_Croix(X1, Y1); end if; return; --Sort de la procedure end if; Left_Clic(X2, Y2, Clic_Gauche); --Lorsque un clic-gauche arrive end loop; --Les coordonnees XY1 sont ajuste au coin superieur droit au gauche X1 := (-X2 + 2 * X1); Y1 := (-Y2 + 2 * Y1); --Si la largeur du cadre est nulle alors reajuste X1 if X1 = X2 then X1 := X1 + 1; end if; --Si la largeur du cadre est nulle alors reajuste X1 if Y1 = Y2 then Y1 := Y1 + 1; end if; end if; Pre_Calcul := (2.0 * Largeur_Zone_Tmp_Float) * Fractal.Zoom; --Convertie la valeur X2 du point a l'ecran(pixel) en valeur reel sur la fractal --Voir la doc pour plus d'informations X2_Float := ( (Long_Float(X2) / Largeur_Zone_Tmp_Float) - 0.5 ) / Fractal.Zoom + Fractal.Centre.X ; --Convertie la valeur Y2 du point a l'ecran(pixel) en valeur reel sur la fractal --Voir la doc pour plus d'informations Y2_Float := (-2.0 * Long_Float(Y2) + Hauteur_Zone_Tmp_Float) / Pre_Calcul + Fractal.Centre.Y; -- de 0 a 1 --Corrige les valeurs par rapport a l'angle (fractal.angle) Power_Calculator.Change_Angle(X2_Float, Y2_Float, Fractal); --Si le bouton droit de la souris a ete presse => dezoom if Clic_Droit then --Ajuste le centre de la fractal a l'endroit clique Fractal.Centre.X := X2_Float; Fractal.Centre.Y := Y2_Float; --Si le nouveau zoom n'est pas inferieur a la limte alors if Fractal.Zoom / Facteur_Zout >= Zoom_Min then --Calcul le nouveau zoom Fractal.Zoom := Fractal.Zoom / Facteur_Zout; else --si il depasse la limite Fractal.Zoom := Zoom_Min; --le remene au zoom minimum end if; else --sinon (c'est le bouton de gauche qui a ete presse) --Convertie la valeur X2 du point a l'ecran(pixel) en valeur reel sur la fractal --Voir la doc pour plus d'informations X1_Float := ( (Long_Float(X1) / Largeur_Zone_Tmp_Float) - 0.5 ) / Fractal.Zoom + Fractal.Centre.X ; --Convertie la valeur Y1 du point a l'ecran(pixel) en valeur reel sur la fractal --Voir la doc pour plus d'informations Y1_Float := (-2.0 * Long_Float(Y1) + Hauteur_Zone_Tmp_Float) / Pre_Calcul + Fractal.Centre.Y; --Corrige les valeurs par rapport a l'angle (fractal.angle) Power_Calculator.Change_Angle(X1_Float, Y1_Float, Fractal); --Le nouveau zoom est egal au rapport entre la fenetre total est le cadre trace Fractal.Zoom := Fractal.Zoom * abs(Largeur_Zone_Tmp_Float / Long_Float(X2 - X1)); --Le centre est egal au centre du cadre Fractal.Centre.X := (X1_Float + X2_Float) / 2.0; Fractal.Centre.Y := (Y1_Float + Y2_Float) / 2.0; end if; Dessiner_Fractal(Fractal); --Dessine la fractale end loop; end Zoom_Souris; ------------------------------------------------------------------------------------------------ -- Nom : Centrer -- -- But : Recentrer le point choisi a l'aide de la souris -- -- -- -- Parametres ---------------------------------------------------------------------------------- -- In out : * La fractal -- -- -- ------------------------------------------------------------------------------------------------ procedure Centrer (Fractal : in out Cara_Fractal) is Clic_Clavier : Boolean := False; --Savoir si une touche du clavier a ete presse Clic_Souris : Boolean := False; --Savoir si il y a eu un clic de souris Touche : Character := Vide; --La touche presse X, Y , --Coordonnees de la souris (avant le clic) X_Clic, Y_Clic : Natural := 0; --Coordonnees de la souris au moment du clic --Sauvegarde des coordonnees de la souris (pour pouvoir effacer la croix) X_Avant, Y_Avant : Natural := 0; Pre_Calcul : Long_Float; --Un precalcul Centre : T_Centre; --Centre du zoom sans le calcul de l'angle begin -- Centrer --Boucle s'executant jusqu'a qu'un clic soit fait ou que la touche ESC soit presses while not Clic_Souris and not (Clic_Clavier and Touche = Echape) loop Mouse(X, Y); --Lit la position de la souris Dessin_Croix(X, Y); --Dessine une croix a l'emplacement de la souris Key_Pressed(Touche, Clic_Clavier); --Lit si une touche est presse --Dessine une croix au milieu de l'ecran Dessin_Croix(Largeur_Ecran / 2, Hauteur_Ecran / 2); Sleep(10); --Redonne la main au systeme pendant 10ms --Si la souris a bougee par rapport a la position precedante alors --efface la croix a la position precedante if X /= X_Avant or Y /= Y_Avant then Efface_Croix(X_Avant, Y_Avant); end if; --Sauvegarde la position courante X_Avant := X; Y_Avant := Y; --Si un clic est fait => sauvegarde les coordonnees du clic dans X_Clic et Y_Clic --Et Clic_Souris devient vrai (true) Left_Clic(X_Clic, Y_Clic, Clic_Souris); end loop; --Si la touche ESC du clavier a ete presse alors if Touche = Echape and Clic_Clavier then Efface_Croix(X, Y); --Efface la croix sous la souris --Efface la croix au milieu de l'ecran Efface_Croix(Largeur_Ecran / 2, Hauteur_Ecran / 2); return; --Sort de la procedure end if; Pre_Calcul := (2.0 * Long_Float(Largeur_Ecran)) * Fractal.Zoom; --Convertie la valeur x du point a l'ecran(pixel) en valeur reel sur la fractal --Voir la doc pour plus d'informations Centre.X := (Long_Float(X_Clic) / Long_Float(Largeur_Ecran) - 0.5) / Fractal.Zoom + Fractal.Centre.X; --Convertie la valeur y du point a l'ecran(pixel) en valeur reel sur la fractal --Voir la doc pour plus d'informations Centre.Y := (-2.0 * Long_Float(Y_Clic) + Long_Float(Hauteur_Ecran)) / Pre_Calcul + Fractal.Centre.Y; --Corrige les valeurs par rapport a l'angle (fractal.angle) Power_Calculator.Change_Angle(Centre.X, Centre.Y, Fractal); Fractal.Centre.X := Centre.X; Fractal.Centre.Y := Centre.Y; Dessiner_Fractal(Fractal); --Dessine la fractal a l'ecran end Centrer; ------------------------------------------------------------------------------------------------ -- Nom : Choix_Mosaic -- -- But : Choisir a l'aide la souris la fractal courante -- -- -- -- Parametres ---------------------------------------------------------------------------------- -- In : * La liste des farctals a dessiner en vue du chois de l'utilisateur -- -- -- -- return : * Le numeros de la fractal -- -- -- ------------------------------------------------------------------------------------------------ function Choix_Mosaic (Liste_Fractals : Power_Types.T_Liste_Fractals) return Natural is ---------------a enlever apres--------------- --Nb_Fractals_Max : Positive := 200; --------------------------------------------- use Power_Types; use Power_List; --Pour les fonctions avancees sur le type float package Elementary_Functions_Long_Float is new Ada.Numerics.Generic_Elementary_Functions (Long_Float); use Elementary_Functions_Long_Float; -- use Spider.User; Nb_Fractals : Natural := 0; --Initialise le nombre de farctals dessine a 0 Nb_Case_X : Positive; --Le nombre de colonne Nb_Case_Y : Positive; --Le nombre de ligne Largeur_Case : Long_Float; --La largeur des colonnes Hauteur_Case : Long_Float; --la hauteur des lignes X, Y : Long_Float := 0.0; --Pour parcourir toute les cases Clic_Souris : Boolean := False; --Savoir si le bouton de la souris a ete presse X_Souris, Y_Souris : Natural; --Les coordonnees de la souris au moment du clic No_Fractal : Positive; --Le numeros de la fractal selectionne lors du clic begin --Choix_Mosaic --Calcul le nombre de colonne en fonction du nombre de fractals de la liste Nb_Case_X := Integer(Sqrt(Long_Float(Liste_Fractals.Nb_Fractals))) + 1; --Calcul le nombre de ligne en fonction du nombre de frctals de la liste Nb_Case_Y := Integer(Long_Float'Truncation(Sqrt(Long_Float(Liste_Fractals.Nb_Fractals)))); --Calcul la largeur des colonne Largeur_Case := Long_Float(Largeur_Ecran) / Long_Float(Nb_Case_X); --calcul la hauteur des lignes Hauteur_Case := Long_Float(Hauteur_Ecran) / Long_Float(Nb_Case_Y); --Reinitialise le contenue de la fenetre graphique Spider.Draw.Set_Color_Background(Spider.Draw.Black); Spider.Clear_Window; -- --Parcour les lignes while Y <= Long_Float(Hauteur_Ecran) - Hauteur_Case / 2.0 loop X:= 0.0; --Parcours les colonnes et sort si le nombre de fractal affiche --correspond au nombre de fractal de la liste while X <= Long_Float(Largeur_Ecran) - Largeur_Case / 2.0 and Nb_Fractals /= Liste_Fractals.Nb_Fractals loop Nb_Fractals := Nb_Fractals + 1; --incremente le nombre de fractal dessine --Dessine la fractal a la bonne place Dessiner_Fractal (Fractal_Num(Liste_Fractals, Nb_Fractals).Fractal , Integer(X), Integer(Y), Integer(Largeur_Case)-1, Integer(Hauteur_Case)-1); --Affiche en haut a gauche de la case son numeros Spider.Draw.Set_Color_Text(Couleur_Numeros); Spider.Move_To(Integer(X), Integer(Y)); Spider.Draw.Display_Text(Integer'Image(Nb_Fractals)); X := X + Largeur_Case; --Increment la valeur x end loop; Y := Y + Hauteur_Case; --Increment la valeur y end loop; -------------------------------souris clic----------------------- New_Line; Put_Line(" Choose one of them"); --Boucle qui se repete si l'utilisateur a clique la ou il n'y avait pas de fractal affiche loop --Attends par une boucle le clic de souris loop Left_Clic(X_Souris, Y_Souris, Clic_Souris); --Si un clic-gauche survient exit when Clic_Souris; --Sort si un clic-gauche est survenu --Redonne la main au system pendant 10 ms (il ne faut pas saturer le proc pour rien) Sleep(10); end loop; --Calcul la colonne cliquee X_Souris := Integer(Long_Float'Truncation(Long_Float(X_Souris * Nb_Case_X) / Long_Float(Largeur_Ecran))) + 1; --Calcul la Ligne cliquee Y_Souris := Integer(Long_Float'Truncation(Long_Float(Y_Souris * Nb_Case_Y) / Long_Float(Hauteur_Ecran))) + 1; --Calcul le numeros de la case correspondant a la colonne et a la ligne No_Fractal := X_Souris + (Y_Souris - 1) * Nb_Case_X; --Si la case existe alors if No_Fractal <= Liste_Fractals.Nb_Fractals then return No_Fractal;--retourne le numeros de la fractal choisie end if; end loop; end Choix_Mosaic; end Power_Tools;