Fractales de Koch et Mandelbrot

La page est créée Isabelle Georges
 
CONTINUER À LIRE
Fractales de Koch et Mandelbrot
Ensimag 1A – Projet C - Préparation 2012 - Exercice Fractales

                                 Fractales de Koch et Mandelbrot
                                    Ensimag 1A - Préparation au Projet C
                                        Année scolaire 2011 – 2012

Présentation
Le but de cet exercice est de se familiariser avec quelques points de base du langage C, à travers la mise en œuvre
de fractales.

Les objectifs de ce sujet, du point de vue du langage C, sont les suivants :
    • Programmation modulaire
    • Allocation dynamique, listes chainées
    • Utilisation des arguments argc et argv de la fonction main
    • Utilisation du préprocesseur C
    • Ecriture dans un fichier
    • Utilisation des types C99
    • Manipulation des opérateurs binaires , |, &
    • Utilisation de l’assertion pour la gestion des erreurs
    • Utilisation des fonctions de la librairie string (strcmp, …)
    • Utilisation du debugger ddd et de valgrind

L’appel aux programmes s'effectuera de plusieurs façons :
    • Programme koch sans arguments : la saisie de tous les paramètres sera demandée par le programme à
        l'utilisateur.
    • Programme koch avec arguments : les paramètres sont initialisés avec les arguments indiqués.
    • Programme mandelbrot : les paramètres sont lus dans un fichier de configuration.

Nous vous demandons de n’utiliser que des types C99 pour vos variables : uint32_t, uint16_t, int32_t, int16_t,
bool, etc…

Les exercices à traiter obligatoirement pour le livrable 1 sont les parties 1, 2 et 3.
Les extensions supplémentaires proposées en partie 4 donneront potentiellement des points de bonus.
Le debugger ddd sera utilisé pour tracer les erreurs du programme. Valgrind sera aussi utilisé pour vérifier
l’allocation correcte des données dynamiques du programme.

Le rendu du projet contiendra tous les fichiers constituant les programmes Test, Koch et Mandelbrot (fichiers .c, .h)
ainsi que des fichiers images résultats au format .ppm. Un makefile permettant de régénérer les 3 programmes sera
également fourni.
Le résultat de l’exécution des programmes via valgrind sera également fourni.
                                                                                                               1/8
Fractales de Koch et Mandelbrot
Ensimag 1A – Projet C - Préparation 2012 - Exercice Fractales

1) Préambule : Création d'une image ppm
Une même fonction permettra de créer les fichiers .ppm pour les 2 programmes Koch et Mandelbrot.
Les fonctions fopen, fwrite et fclose devront être utilisées pour la création du fichier de sortie.

1.1 Représentation interne de l'image
Il est demandé pour des raisons pédagogiques d’utiliser une variable de type uint32_t * pour la représentation
interne de l’image dans les programmes.
Chaque élément de ce tableau est composé de 4 octets, dont 3 serviront à stocker la valeur d’une composante (R, V
ou B) d’un pixel. Le dernier octet sera inutilisé.

En supposant qu’une variable de type uint32_t contienne dans ses trois octets de poids faible trois valeurs
représentant des intensités de couleurs dans l’ordre R, G, B (du poids le plus fort vers le poids le plus faible), on
pourra extraire les composantes R, G et B à l'aide des opérateurs binaires.

Exemple :
uint32_t * picture;
...
/* Exemple d'un élément/pixel du tableau picture initialisé avec une couleur codée en hexadécimal */
picture[...] = 0xF788AA;
/* Composante Rouge de la couleur du pixel : 0xF7 soit 247 en décimal */
/* Composante Verte de la couleur du pixel : 0x88 soit 136 en décimal */
/* Composante Bleue de la couleur du pixel : 0xAA soit 170 en décimal */
...

1.2 Création du fichier ppm
De manière à pouvoir visualiser le résultat, on se propose d’utiliser le format d’image ppm (Portable Pixel Map).
Ce format très simple consiste en un en-tête spécifiant le type d’image (ex : couleur ou noir et blanc) et ses
dimensions, puis la suite des pixels de l’image ligne par ligne, chaque pixel étant codé sur 3 octets : un pour le
rouge (R), un pour le vert (V) et un pour le bleu (B).
Il est possible d’aller voir à l’adresse http://netpbm.sourceforge.net/doc/ppm.html ou simplement le « man ppm »
pour plus de détails sur ce format. Néanmoins, dans le cadre du travail demandé, le fichier devra commencer par
l’en-tête suivant :
P6
LARGEUR HAUTEUR
255
où LARGEUR et HAUTEUR sont la largeur et la hauteur de l’image au format texte et 255 la valeur maximale
de chaque couleur (rouge, vert ou bleu)

Implémenter une fonction create_image ayant comme paramètres la variable image uint32_t *picture, la largeur
et la hauteur de l'image codées en int32_t et le nom du fichier de sortie codé sous forme de chaîne de caractères.

1.3 Test et visualisation du fichier ppm
Le format d’images ppm est visualisable par beaucoup de visionneurs, comme par exemple eog (eye of gnome)
sous linux/Unix.
Si vous souhaitez convertir vos fichiers ppm en images jpg, vous pouvez utiliser la commande ppmtojpg, avec
l’option - -smooth=30 pour lisser le résultat.
Un fichier objet test_create_image.o est fourni. Couplé avec votre module create_image.o, il devrait générer un
programme « test » permettant l'obtention de l'image suivante :

                                                                                                                  2/8
Ensimag 1A – Projet C - Préparation 2012 - Exercice Fractales

2 Programme : Fractale géométrique Flocon de Koch
2.2 Principe

Il s'agit de la première fractale inventée en 1904 par le mathématicien suédois Helge von Koch (1870 – 1924).
Pour tracer cette courbe, il faut:
     • Tracez un triangle équilatéral
     • Remplacer le tiers central de chaque côté par une pointe dont la longueur de chaque côté égale aussi au
          tiers du côté
     • Recommencer cette construction sur chaque côté des triangles ainsi formés.

Schéma des étapes successives :

Pour chaque segment [a,e], on peut calculer les coordonnées des points intermédiaires b,c et d de la façon suivante :

 xb = xa + (xe-xa)/3
 yb = ya + (ye-ya)/3
 xd = xa + 2 * (xe-xa)/3
 yd = ya + 2 * (ye-ya)/3
 xc = (xb+xd) * cos(60°) - (yd-yb) * sin(60°)
 yc = (yb+yd) * cos(60°) + (xd-xb) * sin(60°)

A l'itération suivante, on recommence sur les nouveaux segments créés.

                                                                                                              3/8
Ensimag 1A – Projet C - Préparation 2012 - Exercice Fractales

2.2 Objectifs
Le programme Flocon de Koch devra permettre de paramétrer les données suivantes :
    • La longueur (en pixels) d'un segment du triangle initial.
    • La taille en pixels (hauteur = largeur) du carré de l'image finale sera calculée automatiquement à partir de
       la longueur de segment précédente.
    • Le nombre d'itérations à effectuer
    • La couleur de tracé (qui pourra être codée sous la forme hexadécimale 0xRRVVBB, RR : rouge, VV : vert,
       BB : bleu)
    • La couleur de fond (qui pourra être aussi codée sous la forme 0xRRVVBB)
    • Le nom du fichier .ppm de destination
    • Une dernière option « all » indiquant qu'on veut tous les fichiers image intermédiaires entre le triangle de
       départ et le flocon de koch final. Si elle est omise, seul le fichier image final est généré.

Ces paramètres principaux de la fractale seront stockés dans une seule structure de données.

Les paramètres pourront être donnés en arguments de l’appel du programme en ligne de commandes :
    • Exemple de ligne de commande : koch 270 4 0xFF0000 0xFFFFFF koch.ppm all
    • Cet exemple lancera le programme en définissant la taille d'un segment du triangle initial à 270 pixels, le
        nombre d'itérations de calcul à 4, 5 fichiers de sortie .ppm (00_koch.ppm, 01_koch.ppm, 02_koch.ppm,
        03_koch.ppm, 04_koch.ppm,), les images seront rendues avec un tracé rouge sur fond blanc

Si aucun paramètre n’est passé en arguments de la ligne de commande ou si le nombre d’arguments attendus est
incomplet, le programme Koch demandera à l’utilisateur de saisir les paramètres.

2.3 Directives de programmation
   2.3.1 Programmation modulaire

Le programme Koch comportera au minimum 3 modules
    • Module principal (programme principal)
    • Module fonctions (les fonctions liées au traitement des données du programme : calcul, rendu,...)
    • Module ihm (l’interface homme machine contenant les fonctions liées à l’affichage et la saisie des
       données)

Chaque module sera découpé en fonctions élémentaires permettant une programmation simple, structurée et très
lisible du programme.

   2.3.2 Structure de données

Une liste chainée est imposée pour stocker tous les points calculés du flocon de Koch. Chaque élément de la liste
contiendra les coordonnées X et Y d'un point du flocon de Koch et un lien vers le point suivant.
Les coordonnées seront typées en entiers non signés uint16_t.

   2.3.3 Etapes de résolution

Il est demandé de procéder de la façon suivante :
     • Définition de la liste chaînée initiale des points définissant le triangle de départ.
     • Génération et calcul des points du flocon de Koch. Les nouveaux points seront insérés dynamiquement à la
         liste chainée initiale.
     • Rendu image par la méthode Bresenhem (détaillée ci-dessous). Cette méthode permettra de tracer des traits
         entre les points calculés du flocon de Koch. Comme expliqué au paragraphe 1), l'image générée sera
         stockée dans un tableau de type uint32_t * alloué dynamiquement en mémoire.
     • Ecriture de l'image mémoire uint32_t * dans le fichier .ppm de destination.

                                                                                                             4/8
Ensimag 1A – Projet C - Préparation 2012 - Exercice Fractales

   2.3.4 Méthode de tracé de ligne Bresehem

Documentation sur la méthode : http://en.wikipedia.org/wiki/Bresenham's_line_algorithm

On propose de mettre en œuvre la méthode générale simplifiée en se basant sur le pseudo code suivant :

/* Tracé de ligne entre 2 points de coordonnées (x0,y0) et (x1,y1) */
function line(x0, y0, x1, y1)
   dx := abs(x1-x0)
   dy := abs(y1-y0)
   if x0 < x1 then sx := 1 else sx := -1
   if y0 < y1 then sy := 1 else sy := -1
   err := dx-dy

   loop
        setPixel(x0,y0)
        if x0 = x1 and y0 = y1 exit loop
        e2 := 2 * err
        if e2 > -dy then
             err :=err – dy
             x0 := x0 + sx
        end if
        if e2 < dx then
             err := err + dx
             y0 := y0 +sy
        end if
   end loop

                                                                                                         5/8
Ensimag 1A – Projet C - Préparation 2012 - Exercice Fractales

3 Programme : Fractales de Mandelbrot
3.1 Principe général
Le fonctionnement de calcul pour ce type de fractale est le suivant :
    • On définit un plan complexe associant à chaque point (i, j) de l’image un nombre complexe z0.
    • On définit une fonction complexe f(z) ainsi que la suite associée zn+1 = f(zn)
    • Pour chaque point (i, j) de l’image, on prend le z0 associé dans le plan (ex : pour le point (0,1), la valeur
        complexe 0 + 1i)
    • On calcule ensuite les termes zn de la suite jusqu’à ce que |zn| atteigne une valeur de sortie choisie, ou que n
        atteigne une certaine profondeur donnée
    • Si la profondeur est atteinte, la suite converge ; tandis que si la valeur du module de sortie est atteinte, la
        suite diverge
    • Pour colorier l’image, on affiche pour chaque point divergeant une couleur associée à la profondeur atteinte

3.2 Fractale de base de Mandelbrot
On se propose tout d'abord de tracer une image représentant une partie de l’ensemble de Mandelbrot avec la
fonction f(z) = z2 + z0

Autrement dit, cet ensemble de Mandelbrot est l’ensemble des points c du plan complexe tels que la suite : zn+1 =
zn2 + c et z0 = 0 converge vers un point de C.

Dans cette partie, on demande de produire une image en noir et blanc de l’ensemble : un point est colorié en noir
s’il appartient à l’ensemble, et en blanc sinon. Les intervalles à utiliser sont [−2.2; 0.8] pour les abscisses, et [−1.5;
1.5] pour les ordonnées. L’image fournie devra être aux dimensions 300*300 pixels.

Pour déterminer si un point diverge ou converge, il est possible de s’arrêter après 1000 itérations.
Enfin, on pourra remarquer que si R(z)2 + I(z)2 ≥ 4, alors la suite diverge.

3.3 Tracé d’autres fractales de Mandelbrot
On souhaite désormais pouvoir spécifier d’autres valeurs pour le sous-ensemble à visualiser, ainsi que pouvoir
fournir des tailles d’images différentes. Comme on souhaite ne pas avoir de déformation dans l’image, les
paramètres sont les suivants :
    • Résolution horizontale (RESOL_X) et résolution verticale (RESOL_Y) de l’image
    • Coordonnées X et Y du centre du sous-ensemble (centre = CENTRE_X + i CENTRE_Y )
    • Intervalle horizontal du sous-ensemble (SPAN_X)
    • Nombre d’itérations maximal (NB_ITER_MAX)

Le nombre d’itérations maximal ne peut pas être connu à l’avance, mais est dépendant soit du zoom sur le sous-
ensemble, soit de l’intervalle horizontal représenté. Quelques exemples d’images sont donnés dessous (Tab. 1). Si
vous voulez en faire d’autres, à vous de trouver une valeur suffisamment grande, mais pas trop pour ne pas alourdir
inutilement le calcul.

Modifier votre code précédent pour prendre en compte ces paramètres. L’utilisation du programme s'effectuera
sous la forme : ./mandelbrot  
On lira les paramètres dans le fichier de configuration config_file. Le fichier outfile est le nom du fichier contenant
l’image à créer.
Plusieurs fichiers de configurations sont fournis dans le répertoire « configs ». Les fichiers intitulés
« config_fractale_1_nx.txt » correspondent aux fractales de Mandelbrot étudiées dans cette partie.

                                                                                                                    6/8
Ensimag 1A – Projet C - Préparation 2012 - Exercice Fractales

Le format de ces fichiers est le suivant :

            # Utilisé uniquement dans la partie 4.2

                      ou               ...      # Utilisé uniquement dans la partie 3.4
                                             *
                                             
Nota bene : les 3 dernières lignes des fichiers serviront ultérieurement pour la mise en couleur des fractales.

3.4 Utilisation de couleurs pour le tracé de la fractale
De manière à rendre les dessins plus jolis, on souhaite dans cette section utiliser des couleurs pour le tracé de la
fractale. L’approche est la suivante : on définit un petit nombre P de couleurs (par exemple jaune (#FFFF00), vert
(#00FF00), bleu (#0000FF) et rouge (#FF0000)), appelées paliers, et une valeur N correspondant au nombre de
couleurs entre deux paliers, de manière à obtenir une transition entre ces deux paliers. À partir de ces informations,
il faut générer toutes les couleurs correspondantes (au nombre de (P − 1) ∗ N ). Entre autres, il faut bien faire
attention à diviser les paliers selon les 3 composantes R, V et B.

Une fois toutes les couleurs obtenues, il suffit de colorier un point divergeant avec la couleur ayant pour indice le
numéro de l’itération ayant fait diverger la suite (modulo le nombre de couleurs total).

Implémenter cette fonctionnalité.
                                                                                                                  7/8
Ensimag 1A – Projet C - Préparation 2012 - Exercice Fractales

4 Extensions possibles
4.1 Extensions Koch :

    •   Figure de départ différente d'un triangle (figure à n segments : carré, hexagone, etc...).
    •   Variantes des courbes de Koch (http://fr.wikipedia.org/wiki/Flocon_de_Koch) :
        • Fractales Cesàro
        • Courbes de Koch quadratiques

4.2 Extensions Mandelbrot :

    •   Autres fonctions de génération f(z).
    •   Fonctions f(zn) à implémenter :
        • f(z) = sin(z) x z0 (fonction Mandelbrot numérotée 2 dans les fichiers de configurations)
        • f(z) = z2 + h, avec h = - 0.39492 + 0.59568i (fonction Julia numérotée 3 dans les fichiers de
             configurations)
        • f(z) = cos(z) x h, avec h = 4.72675 + 0.001456i (fonction Julia numérotée 4 dans les fichiers de
             configurations)
    •   3 fichiers de configurations sont fournis dans le répertoire « configs » pour tester ces fonctions :
        • config_fractale_2_n1.txt
        • config_fractale_3_n1.txt
        • config_fractale_4_n1.txt

NOTA BENE : On pourra utiliser la librairie C99 complex pour les calculs sur les nombres complexes liés à ces
autres fonctions.

                                                                                                               8/8
Vous pouvez aussi lire