Fractale de Mandelbrot [Fermé]

Signaler
-
 LittDev -
Salut

J'ai programmé un petit générateur de fractales de mandelbrot avec la SDL, mais il prend beaucoup de temps pour calculer, malgré un nombre d’itérations assez faible, n'y aurait pas t-il des optimisations a faire dans le code ou des erreurs qui ralentissent le calcul ?

Pour ceux qui ne savent pas ce que c'est :
https://fr.wikipedia.org/wiki/Ensemble_de_Mandelbrot

#include <complex>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cmath>

#include <SDL/SDL.h>

#define X 899
#define Y 599

using namespace std;

//Structure simple pour les couleurs
typedef struct
{
    int r;
    int g;
    int b;
}Color;

void set_color(Color& color, int const& r, int const& g, int const& b)
{
    color.r = r;
    color.g = g;
    color.b = b;
}

//Fonction gaussienne
double gauss(long double const& x, long double const& var, long double const& moy)
{
    return exp(-1*((x-moy)*(x-moy))/var);
}

//Calcule la couleur en fonction de l'iteration en utilisant la fonction gaussienne
Color calculate_color(int const& iterations, int const& iter_max)
{
    Color result;

    if(iterations == iter_max)
    {
        set_color(result,0,0,0);
        return result;
    }

    double temp(static_cast <double>(iterations%768)/768), var(0.1);
    set_color(result, static_cast <int>(256*gauss(temp,0.25*var,0.5)),  static_cast <int>(256*gauss(temp,var,0.5)),  static_cast <int>(256*gauss(temp,0.5*var,0.5)));

    return result;
}

//La fonction qui permet de generer les termes de la suite en fonction de cst et du nombre d'iterations maximum
int mandelbrot_suite(complex <long double> const& cst, int iter_max)
{
    complex <long double> result(0,0);
    for(int i(0);i<iter_max;i++)
    {
        result = result*result + cst;
        if(norm(result)>2)
            return i;
    }

    return iter_max;
}

int main (int argc, char** argv)
{
    //Zoom : Nombre de pixels par unité (ex : 45000 par 1.5)
    long zoom = 30000;
    SDL_Surface* screen = SDL_SetVideoMode(X, Y, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
        return 1;

    atexit(SDL_Quit);

    SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 255, 255, 255));
    SDL_Flip(screen);

    bool done(false);
    
    SDL_Rect pos;
    pos.x = 0;
    pos.y = 0;
    pos.h = 1;
    pos.w = 1;

    while (!done)
    {
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
            case SDL_QUIT:
                done = true;
                break;
            case SDL_KEYDOWN:
                {
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                }
            }
        }

        //Transformation des points de l'ecran en nombre complexe, en fonction du zoom
        complex <long double> cst(static_cast <long double>(pos.x - (X+1)/2)/zoom - 0.11,static_cast <long double>(((Y+1)/2) - pos.y)/zoom + 0.895);
        //Calcul du nombre d'iterations
        int result(mandelbrot_suite(cst,768));
        //Choix de la couleur
        Color color(calculate_color(result,768));
        //Creation du pixel en fonction de la couleur choisie et de la position
        SDL_FillRect(screen,&pos,SDL_MapRGB(screen->format,color.r,color.g,color.b));

        if(pos.x < screen->w-1)
            pos.x++;
        else if(pos.y < screen->h-1)
        {
            pos.y++;
            pos.x=0;
        }
        else
            SDL_Flip(screen);
    }

    return 0;
}


Merci d'avance

1 réponse

Messages postés
14296
Date d'inscription
jeudi 24 décembre 2009
Statut
Membre
Dernière intervention
10 août 2017
1 103
Utilise un Profiler pour voir là où le programme passe du temps, je n'ai pas pu compiler ton code (j'utilise SDL2 et non SDL1)

Sache que c'est fortement parallélisable/vectorisable comme code, si tu veux te lancer là dedans :)

En plus, sauf si tu as besoin vraiment de précision étendue, double est bien plus rapide. Pour un GPU float sera encore plus rapide.
Merci de la réponse

J'ai tout changé, je suis passé à la SFML, j'ai bien revu la boucle du programme, bien factorisé le code, et j'ai trouvé des optimisations de calcul, et j'ai mainenant un resultat plutôt satisfaisant :)