/**
* Générateur de fractale de Mandelbrot
*/
#include <stdio.h>
#include <stdlib.h>
// Nombre de couleurs
const unsigned int MAX_ITERATION = 142;
// Taille de l'image de sortie
const unsigned int OUTPUT_WIDTH = 1920;
const unsigned int OUTPUT_HEIGHT = 1080;
// Point de départ de la fenêtre de dessin dans le plan réel / complexe de mandelbrot
const double START_X = -0.75;
const double START_Y = 0.0;
const double ZOOM = 0.8;
// Tableaux de couleurs (142 couleurs, tirées d'un nuancier trouvé sur le web)
const unsigned int COLOR_TABLE[] = {
0xf7df, 0xff5a, 0x07ff, 0x7ffa, 0xf7ff, 0xf7bb, 0xff38, 0xff59, 0x001f, 0x895c,
0xa145, 0xddd0, 0x5cf4, 0x7fe0, 0xd343, 0xfbea, 0x64bd, 0xffdb, 0xd8a7, 0x07ff,
0x0011, 0x0451, 0xbc21, 0xad55, 0x0320, 0xbdad, 0x8811, 0x5345, 0xfc60, 0x9999,
0x8800, 0xecaf, 0x8df1, 0x49f1, 0x2a69, 0x067a, 0x901a, 0xf8b2, 0x05ff, 0x6b4d,
0x1c9f, 0xd48e, 0xb104, 0xffde, 0x2444, 0xf81f, 0xdefb, 0xffdf, 0xfea0, 0xdd24,
0x8410, 0x0400, 0xafe5, 0xf7fe, 0xfb56, 0xcaeb, 0x4810, 0xfffe, 0xf731, 0xe73f,
0xff9e, 0x7fe0, 0xffd9, 0xaedc, 0xf410, 0xe7ff, 0xffda, 0xd69a, 0x9772, 0xfdb8,
0xfd0f, 0x2595, 0x867f, 0x839f, 0x7453, 0xb63b, 0xfffc, 0x07e0, 0x3666, 0xff9c,
0xf81f, 0x8000, 0x6675, 0x0019, 0xbaba, 0x939b, 0x3d8e, 0x7b5d, 0x07d3, 0x4e99,
0xc0b0, 0x18ce, 0xf7ff, 0xff3c, 0xff36, 0xfef5, 0x0010, 0xffbc, 0x8400, 0x6c64,
0xfd20, 0xfa20, 0xdb9a, 0xef55, 0x9fd3, 0xaf7d, 0xdb92, 0xff7a, 0xfed7, 0xcc27,
0xfe19, 0xdd1b, 0xb71c, 0x8010, 0xf800, 0xbc71, 0x435c, 0x8a22, 0xfc0e, 0xf52c,
0x2c4a, 0xffbd, 0xa285, 0xc618, 0x867d, 0x6ad9, 0x7412, 0xffdf, 0x07ef, 0x4416,
0xd5b1, 0x0410, 0xddfb, 0xfb08, 0x471a, 0xec1d, 0xd112, 0xf6f6, 0xffff, 0xf7be,
0xffe0, 0x9e66, 0x0000
};
int main(void) {
// Ouvre le fichier pour l'image de sortie
FILE *fp = fopen("output.ppm", "wb");
if (fp == NULL) {
puts("Impossible d'ouvrir le ficher de sortie");
return -2;
}
// Ecrit l'entête du fichier PPM binaire
fprintf(fp, "P6\n%d %d\n255\n", OUTPUT_WIDTH, OUTPUT_HEIGHT);
// Tableau temporaire pour une ligne de pixels
unsigned char line_buffer[OUTPUT_WIDTH * 3];
// Pour chaque pixel en Y
for (unsigned int y = 0; y < OUTPUT_HEIGHT; ++y) {
double p_i = (y - OUTPUT_HEIGHT / 2.0) / (0.5 * ZOOM * OUTPUT_HEIGHT) + START_Y;
// Pour chaque pixel en X
for (unsigned int x = 0; x < OUTPUT_WIDTH; ++x) {
double p_r = 1.5 * (x - OUTPUT_WIDTH / 2.0) / (0.5 * ZOOM * OUTPUT_WIDTH) + START_X;
double new_r = 0, new_i = 0, old_r = 0, old_i = 0;
unsigned int i = 0;
// Magie noir mathématique (merci Wikipedia)
while ((new_r * new_r + new_i * new_i) < 4.0 && i < MAX_ITERATION) {
old_r = new_r;
old_i = new_i;
new_r = old_r * old_r - old_i * old_i + p_r;
new_i = 2.0 * old_r * old_i + p_i;
++i;
}
// Dessine le pixel (avec conversion RGB565 -> RGB888)
unsigned int color = COLOR_TABLE[i];
line_buffer[3 * x] = ((color >> 11) & 0x1F) << 3;
line_buffer[3 * x + 1] = ((color >> 5) & 0x3F) << 2;
line_buffer[3 * x + 2] = (color & 0x1F) << 3;
}
// Sauvegarde la ligne de pixels dans le fichier PPM
fwrite(line_buffer, 1, sizeof(line_buffer), fp);
}
// Ferme le fichier de sortie
fclose(fp);
// All done
return 0;
}