LittDev
-
Modifié par LittDev le 25/07/2016 à 03:59
LittDev -
3 août 2016 à 08:38
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;
}
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 :)
3 août 2016 à 08:38
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 :)