Compte Rendu TP5 Barriga GUO
Compte Rendu TP5 Barriga GUO
Compte Rendu TP5 Barriga GUO
04/04/2020
1) Dessin d’une fractale :
1.1) Introduction :
Dans ce TP nous allons dessiner une image fractale pour introduire des éléments
nouveaux du langage C++ tels que les fonctions « friends », les nombres complexes,
la mesure du temps CPU, la programmation multi-coeurs.
Nous avons pris comme point de départ le projet Triangle Image. On a utilisé une
conversion linéaire pour passer du plan de pixel au plan réel, comme l’image ci-
dessous :
Ces deux méthodes vont permettre passer de x et y dans le domaine pixel au domaine réel.
Ensuite on déclare une variable complexe “z” en utilisant une classe prédéfinie dans la
bibliothèque std. On fait donc: std::complex<double> z(0,0);
De même on déclare la variable complexe 𝑐0 = 𝑥0 + 𝑖𝑦0. Où x0 et y0 sont les points du plan réel.
On doit satisfaire la condition Zn < 2 pour être dans l’ensemble de Mandelbrot. Ensuite on fait
une itération pour diminuer n qui est initialisé à 512. On va arrêter la boucle dans le cas où le
module de Zn est supérieur à 2 et donc on est dehors de l’ensemble de Mandelbrot. Si n est
négative on va peindre le pixel de couleur noire, et sinon on utilise la couleur : QColor(255, 218,
103). Cette logique est dans le code ci-dessous:
1. while(n--){
2. z=std::pow(z,2)+c0;
3. if(std::abs(z)>=2)
4. break;
5. }
6. if(n<0){
7. painter.setPen(QPen(QColor(0,0,0)));
8. painter.drawPoint(xp,yp);
9. }
10. else{
11. painter.setPen(QPen(QColor(255, 218, 103)));
12. painter.drawPoint(xp,yp);
13. }
Maintenant on veut une meilleure lisibilité du résultat. Pour cela on veut ajouter des séparateurs
pour les milliers. On va utiliser une classe appelé Commify. Celui-ci est un constructeur qui
retourne donc un objet de la classe. Cette objet est ensuite affiche avec l’opérateur <<.
On peut voir ci-dessous une partie de la classe Commify. On utilise la fonction-déclaration friend
pour donner une fonction à l’opérateur <<. Friend accorde à la classe Commify l'accès aux
membres privés et protège à la classe où la déclaration friend apparaît.
Nous allons construire un tableau de 2048 couleurs pour chaque spline(RVB). Ci-dessous on
montre le code pour créer le tableau du spline 1(rouge).
1. double sp1[2048];
2. double sp2[2048];
3. double sp3[2048];
4. //sp1 red
5. double x=-0.05;
6. for (int i=0; i<2048; i++){
7. if (spline1.get_value(x)>255){
8. sp1[i]=255;
9. }
10. else if (spline1.get_value(x)<0){
11. sp1[i]=0;
12. }
13. else {
14. sp1[i]=spline1.get_value(x);
15. }
16. x=x+(1.10/2048);
17. }
𝜈=log2(log2(|𝑧𝑛|2)) et 𝑖=1024⋅√(𝑛+5−𝜈)
1. double v=log(log(std::abs(z)*std::abs(z))/log(2))/log(2);
2. int i=1024*sqrt((Mandelbrot.getNmax()-n)+5-v);
3.
4. if(i>=2048) i=i%2048;
5. painter.setPen(QPen(QColor(sp1[i], sp2[i] , sp3[i])));
6. painter.drawPoint(xp,yp);
On présente ensuite notre class MandelbroImage. Cette class a comme attributs : height, widht,
xc,yc et n_max.
Dans cette partie on veut s’assurer que la fonction choisie représente une part significative du
temps total. Nous allons fait l’hypothèse que la boucle principale représente bien la majorité du
temps passé.
On a créé une fonction process_sub_image(int i, int m) qui réalisera une fraction de la boucle
principale.
1. std::vector<std::thread> threads;
2. for(int i=0;i<max_threads;i++){
3. threads.emplace_back([=](){
4. process_sub_image(i,max_threads);
5. });
6. }
Explication sur le paramètre de emplace_back()
Emplace_back() sert pour traiter les données séparés en parallèle. Chaque threads fait la
fonction de process_sub_image(i),max_threads). Pour cela on a utilisé une fonction anonyme [=]
qui capture tous les occurrences libres par copie et qui ne peuvent être modifiées.
On trace une courbe en faisant varier le nombre de threads et en voyant le temps d’exécution.
Temps d’exécution(s)
Nombre de threads
Dans cette partie on veut optimiser en codant explicitement le calcul des parties
réelles et imaginaires.
b) Image optimisée :
On peut remarquer qu’on obtient deux images identiques. L’amélioration de performance est
dans le temps de calcul.
On fait différents facteurs de zoom à notre image.
a) Zoom d= 10 e-15
b) Zoom d= 10 e-16
c) Zoom d= 10 e-17
Quand on zoom trop fort on voit que l’image se dégrade parce qu’on demande plus de détaille
et on est dans la limite de résolution car on est proche de la région de Mandelbrot.
5) Image Dynamique
Dans cette partie on va implémenter une variation à notre code pour passer d’un fractale de
Mandelbrot à une fractale de Julia.
Un fractale de Mandelbrot:
Un fractale de Julia: