Code de test 5 pour comparatif carte Arduino

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

Description :

Code de test 5 : générateur de fractale de Mandelbrot

Code source :

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

/*
 * Code de test 5 : générateur de fractale de Mandelbrot
 */

/* Includes */
#include <stdint.h>
 
#if defined(__AVR_ATmega2560__)
#define MAX_PIN_NUM A15
#elif defined(__AVR_ATmega328P__)
#define MAX_PIN_NUM A5
#elif defined(__AVR_ATmega32U4__)
#define MAX_PIN_NUM A5
#endif

/* Defines */
#define MAX_ITERATION 142 // Nombre de couleurs
#define SCREEN_X_MAX 320  // 
#define SCREEN_Y_MAX 240  // Taille de l'écran

/**
 * Tableaux de couleurs (142 couleurs, tiré d'un nuanciez HTML trouvé sur le web)
 */
const uint16_t color_table[MAX_ITERATION] = { // HTML color
  0xf7df, 0xff5a, 0x7ff, 0x7ffa, 0xf7ff, 0xf7bb, 0xff38, 0xff59, 0x1f, 0x895c, 
  0xa145, 0xddd0, 0x5cf4, 0x7fe0, 0xd343, 0xfbea, 0x64bd, 0xffdb, 0xd8a7, 0x7ff, 
  0x11, 0x451, 0xbc21, 0xad55, 0x320, 0xbdad, 0x8811, 0x5345, 0xfc60, 0x9999, 
  0x8800, 0xecaf, 0x8df1, 0x49f1, 0x2a69, 0x67a, 0x901a, 0xf8b2, 0x5ff, 0x6b4d, 
  0x1c9f, 0xd48e, 0xb104, 0xffde, 0x2444, 0xf81f, 0xdefb, 0xffdf, 0xfea0, 0xdd24, 
  0x8410, 0x400, 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, 0x7e0, 0x3666, 0xff9c, 
  0xf81f, 0x8000, 0x6675, 0x19, 0xbaba, 0x939b, 0x3d8e, 0x7b5d, 0x7d3, 0x4e99, 
  0xc0b0, 0x18ce, 0xf7ff, 0xff3c, 0xff36, 0xfef5, 0x10, 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, 0x7ef, 0x4416, 
  0xd5b1, 0x410, 0xddfb, 0xfb08, 0x471a, 0xec1d, 0xd112, 0xf6f6, 0xffff, 0xf7be, 
  0xffe0, 0x9e66
};

/* Setup */
void setup() {
  
  // Port série au repos
  pinMode(0, INPUT);
  pinMode(1, OUTPUT);
  digitalWrite(1, HIGH);
  
  // Evite les broches flottantes
  for (byte pin = 3; pin <= MAX_PIN_NUM; pin++) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW);
  }
  
  // En prévision du test 3
  pinMode(2, INPUT_PULLUP);
}
 
/* Loop() */
void loop() {
  
  // Fenêtre de dessin dans le plan réel/complexe de mandelbrot
  static float x0 = -2.5;
  static float y0 = -1;
  static float x1 = 1;
  static float y1 = 1;

  unsigned long stime = millis();   // Temps avant dessin
   
  //lcd.clear(COLOR_BLACK);           // Écran noir
  draw_mandelbrot(x0, y0, x1, y1); // Dessin d'un figure de mandelbrot
   
  /* Effet de zoom très sommaire et pas du tout proportionné ... */
  x0 += 0.1;
  if(x0 > 1) x0 = -2.5;
  y0 += 0.1;
  if(y0 > 1) y0 = -1;
  x1 -= 0.1;
  if(x1 < -2.5)x1 = 1;
  y1 -= 0.1;
  if(y0 < -1) y1 = 1;
}

/* Fonction de dessin d'un pixel */
void draw_pixel(uint16_t x, uint16_t y, uint16_t color) {
  volatile uint16_t gcc_please_dont_optimize_this = x ^ y;
  gcc_please_dont_optimize_this += color;
  //lcd.drawPixel(x, y, color);
}

/** 
 * Dessine une fractale de Mandelbrot
 */
void draw_mandelbrot(const float x0, const float y0, const float x1, const float y1) { 
  for(uint16_t x = 0; x < SCREEN_X_MAX; ++x) {
    float sx = x * (x1 - x0) / SCREEN_X_MAX + x0;
     
    for(uint16_t y = 0; y < SCREEN_Y_MAX; ++y) {
      float sy = y * (y1 - y0) / SCREEN_Y_MAX + y0;
       
      float z_r = 0, z_i = 0;
      uint16_t i = 0;
 
      do {
        float tmp = z_r * z_r - z_i * z_i + sx;
        z_i = 2 * z_r * z_i + sy;
        z_r = tmp;
        ++i;
      } while((z_r * z_r + z_i * z_i) < 4 && i < MAX_ITERATION);
 
      draw_pixel(x, y, (i == MAX_ITERATION) ? 0x0000 : color_table[i]);
    }
  }
}