Générateur de fractale de Mandelbrot sur plateforme Arduino

par skywodd | | Langue : C++ | Licence : GPLv3

Description :

Générateur de fractale de Mandelbrot sur plateforme Arduino.

Code source :

Voir le code source brut | Télécharger mandelbrot.ino | Télécharger mandelbrot.ino.zip

/*
 * Générateur de fractale de Mandelbrot sur plateforme Arduino
 */

/* Includes */
#include <stdint.h>           // Pour les types d'entier de taille fixe
#include <SPI.h>              // Pour la communication avec l'écran
#include <digitalWriteFast.h> // Pour éviter une erreur de compilation
#include <GraphicsLib.h>      // Pour les fonctions de dessin
#include <MI0283QT2.h>        // Pour l'écran lui-même

/* Defines */
const uint16_t MAX_ITERATION = 142; // Nombre de couleurs
const uint16_t SCREEN_WIDTH  = 320; // 
const uint16_t SCREEN_HEIGHT = 240; // Taille de l'écran

/**
 * Tableaux de couleurs (142 couleurs + noir, tiré d'un nuancier trouvé sur le web)
 */
const uint16_t COLOR_TABLE[143] = { // HTML color
  0xf7df, 0xff5a, 0x07ff, 0x7ffa, 0xf7ff, 0xf7bb, 0xff38, 0xff59, 0x001f, 0x895c, 
  0xa145, 0xddd0, 0x5cf4, 0x7fe0, 0xd343, 0xfbea, 0x64bd, 0xffdb, 0xd8a7, 0x7ff, 
  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
};

/* Déclaration de l'objet lcd pour l'affichage */
MI0283QT2 lcd;

/* Fonction setup */
void setup() {

  /* Initialise l'écran LCD */
  lcd.begin(2); // Initialisation de l'écran lcd
  lcd.led(30); // Backligth à 30%
  //lcd.fillScreen(RGB(0, 0, 0)); // Écran noir
  lcd.setOrientation(270);
}

/* Fonction loop() */
void loop() {

  /* Point de départ de la fenêtre de dessin dans le plan réel / complexe de mandelbrot */
  static float start_x = -0.75;
  static float start_y = 0.0;
  static float zoom = 0.8;

  /* Dessine la fractale */
  draw_mandelbrot(start_x, start_y, zoom);

  /* Effet de zoom très sommaire et pas du tout proportionné */
  zoom += 0.1;
}

/** 
 * Dessine une fractale de Mandelbrot
 */
void draw_mandelbrot(const float start_x, const float start_y, const float zoom) {

  /* Commence l'affichage */
  lcd.setArea(0, 0, SCREEN_HEIGHT - 1, SCREEN_WIDTH - 1);
  lcd.drawStart();

  /* Pour chaque pixel en X */
  for(uint16_t x = 0; x < SCREEN_WIDTH; ++x) {
    float p_r = 1.5 * (x - SCREEN_WIDTH / 2.0) / (0.5 * zoom * SCREEN_WIDTH) + start_x;

    /* Pour chaque pixel en Y */
    for(uint16_t y = 0; y < SCREEN_HEIGHT; ++y) {
      float p_i = (y - SCREEN_HEIGHT / 2.0) / (0.5 * zoom * SCREEN_HEIGHT) + start_y;
      float new_r = 0.0, new_i = 0.0, old_r = 0.0, old_i = 0.0;
      uint16_t 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;
      }

      /* Affiche le pixel */
      lcd.draw(COLOR_TABLE[i]);
    }
  }

  /* Termine l'affichage */
  lcd.drawStop();
}