TD02b Mandelbrot

Mandelbrot

Qu’est-ce qu’on apprend

  1. Comment utiliser une boucle while.
  2. Comment décomposer un problème en plusieurs parties en utilisant des fonctions (oui, de nouveau, mais c’est très important) avec une valeur de retour.
  3. Comment utiliser des bibliothèques logicielles et compiler un programme qui utilise une bibliothèque (ici: math).
  4. Comment utiliser des fonctions mathématiques en C.

Lecture…

Si vous rencontrez des problèmes (bugs, le programme ne marche pas, …), vous pouvez trouver des astuces sur le débogage :

En cas de besoin, rafraichissez votre mémoire sur les sujets suivants.

Compilation:


Au boulot…

Vous allez de nouveau utiliser les fichiers paint.h, paint.c, paint_demo.c. Merci de télécharger ces fichiers ici.

L’ensemble Mandelbrot est un ensemble de points \((x,y)\) qui sont définis en utilisant la séquence suivante. En partant des valeurs \(a=0,b=0,c=0,k=0\), on applique l’itération Mandelbrot

\[\begin{aligned} c &:= ab\\ a &:= a^2 - b^2 + x\\ b &:= 2c + y\\ k &:= k + 1 \end{aligned}\]

tant que \(a^2+b^2 \leq 4\) est satisfait (sinon, on arrête). L’ensemble Mandelbrot est constitué des points \((x,y)\) pour lesquels \(k \rightarrow \infty\). Dans l’image en haut de la page, l’ensemble Mandelbrot est dessiné en noir. Chaque pixel de l’image est alors associé à une valeur \((x,y)\) et il est noir si \(k \rightarrow \infty\) pour cette valeur de \((x,y)\). Pour obtenir des couleurs, on associe à chaque valeur de \(k\) (la dernière valeur de la séquence) une couleur. Pour des raisons pratiques, on limite les nombres d’itérations à une valeure maximale, par exemple \(k_{max}=100\).

IMPORTANT: Donnez votre prénom et nom au début du fichier de réponse, sous forme de commentaire. Ajoutez également les réponses aux questions dans votre programme, sous forme de commentaires. Exemple:

/* Jeanne LAGAFFE */
#include <stdio.h>
int main () {
   printf("Hello World !!\n");
}
/* 
Q1: Ceci est la réponse à la question 1.
Q2: Voilà la réponse à la question 2.
*/

Q1:

Ecrivez une fonction

int compter_iterations(double x, double y, int max_iter)

qui calcule la valeur final de $k$ quand on applique l’itération de Mandelbrot un maximum de max_iter fois (bien entendu, on itère seulement tant que \(a^2+b^2 \leq 4\)). La fonction donne en valeur de retour le nombre d’itérations effectuées, donc la valeur de \(k\).

Astuce: Vous pouvez calculer \(a^2\) simplement avec l’instruction a*a.

Q2:

Testez la fonction avec un programme qui l’appelle pour un point x=1,y=0 et affiche le nombre d’itérations pour max_iter=100. Donnez la fonction main pour ce test.

Q3:

Combien d’itérations pour le point x=1,y=0?

Q4:

Combien d’itérations pour le point x=-1,y=0?

Q5:

Combien d’itérations pour le point x=0,y=0.75?

Q6:

Vous allez dessiner l’ensemble Mandelbrot sur une image de taille width x height qui représente les valeurs de \((x,y)\) sur un rectangle dont le coin en haut à gauche est à (x_left,y_top) et qui a une largeur de x_width et une hauteur de y_height=x_width*height/width.

Commencez avec les valeurs width = 600, height = 400, x_left = -2, y_top = 1, x_width = 3.

Chaque pixel (i,j) est associé par interpolation linéaire à une coordonnée (x,y) où i est le nombre de ligne et j le nombre de colonne. On attribuera au pixel (0,0) la coordonnée (x_left,y_top) et au pixel (width-1,height-1) la coordonnée (x_left+x_width,y_top-y_height).

Donnez les instructions pour calculer x et y à partir de i et j.

Q7:

Pour dessiner l’image, vous allez utiliser les fonctions suivantes, disponibles dans les fichiers paint.h et paint.c téléchargés (rappelez vous du TD02a).

Complétez le programme pour qu’il appelle la fonction compter_iterations pour chaque pixel de l’image et le colorie avec la couleur définie par les valeurs (r,g,b) suivantes :

r=255*nb_iterations/max_iter
g=0
b=255-r

Si nb_iterations est égal à max_iter, il faut colorier le pixel en noir.

Q8:

Modifiez le calcul des couleurs pour avoir un image plus attractif. Soyez créatif!

Astuce: Appliquer une transformation nonlinéaire (sqrt,sin) marche bien. Pour utiliser ces fonctions mathématiques, ajoutez

#include <math.h>

et compilez avec l’option -lm à la fin:

gcc -Wall -Werror -Wfatal-errors mandelbrot.c paint.c -lm 

Q9:

Appliquez une translation de dx,dy à votre image (dx=0.1,dy=0.02). Pour cela, vous pouvez simplement modifier les valeurs de x et y avant d’appeler compter_iterations:

x = x + dx;
y = y + dy;

Q10:

Appliquez une rotation de g=-0.1 (en radians) à votre image. Pour cela, vous pouvez utiliser

xr = x*cos(g)+y*sin(g);
y = -x*sin(g)+y*cos(g);
x = xr;

Pourquoi ça ne marche pas si on fait directement x = x*cos(g)+y*sin(g);, sans passer par xr?

Validez:

Nommez le fichier T02b.c et envoyez-le à votre chargé de TD

Bonus

Executez votre code 100x plus vite sur un GPU (optionnel): Voici une squelette où vous pouvez copier-coller votre code du TD02 pour faire le calcul sur un GPU.