Partage
  • Partager sur Facebook
  • Partager sur Twitter

[FAIT][Défis] #6 : Dessinez la courbe du dragon

Venez vous entraîner !

    28 octobre 2011 à 21:38:30

    Salutations,

    Cette semaine, nous vont proposons de dessiner une fractale : la courbe du dragon.

    Si vous souhaitez plus de renseignements sur les défis, rendez vous sur le topic de recensement des défis, vous y trouverez également les règles principales.

    Cet exercice a été écrit par yoch, merci à lui !

    Dessinez la courbe du dragon



    Les fractales



    Vous avez peut-être déjà entendu parler des figures fractales : ce sont des structures ayant la particularité de présenter certaines auto-similarités à toutes les échelles.

    Ces figures intéressent à la fois mathématiciens et informaticiens. Aussi, par exemple, vous pouvez trouver sur le SdZ un tutoriel pour expliquer comment créer une des fractales les plus célèbres : l'ensemble de Mandelbrot, ainsi qu'un autre tutoriel abordant certains aspects mathématiques des fractales.

    Il existe tout un tas de types de fractales, et aussi (évidement ;) ) divers de moyens d'en générer. Si vous êtes curieux, vous pouvez aller faire un tour sur cette page Wikipédia, où sont recensés un bon nombre de fractales, ou encore aller faire un tour sur l'atelier Cod'Art du SdZ, dans lequel sont exposés de nombreuses créations de membres du site (généralement avec le code source). Également, vous pouvez lire un bon dossier sur la question ici.

    La courbe du dragon




    Exemple de courbe du dragon (Source: Wikipédia)
    Image utilisateur


    La courbe du dragon est une très jolie image fractale, que l'on peut obtenir notamment de deux façons :
    • En utilisant une grammaire de construction, appelée L-System.
    • En utilisant un système de fonctions itérées, communément appelé IFS.

    Ces deux méthodes sont extrêmement riches, et permettent de réaliser de très nombreuses images fractales. Pensez à vous documenter convenablement dessus. Aussi, n'hésitez pas si vous le sentez à rendre votre code un peu plus générique pour tracer d'autres images.

    Liens vers un document pour appréhender les IFS (#1, #2, #3).

    Consignes



    Votre mission, si vous l'acceptez ;) , sera d'écrire un programme graphique (C + SDL) permettant de tracer la courbe du dragon.
    N’hésitez pas à innover et sortir des sentiers battus, si vous le désirez.

    Prérequis



    Vous devez maitriser un minimum la programmation graphique avec SDL, et disposer de deux primitives : tracé de point et/ou tracé de ligne.
    Pour le tracé de point, vous pouvez vous référer à cette page. Quant au tracé de ligne, vous pouvez envisager d'utiliser une bibliothèque de fonctions existante (telle que SDL_gfx par exemple), ou bien éventuellement le faire par vous même.

    Objectifs


    • Comprendre une documentation.
    • Maitriser la récursivité.
    • Créer un programme graphique.


    Énoncé



    Niveau 1

    Créer un programme permettant de tracer et visualiser la courbe du dragon à partir de ce L-System :

    • angle 90°
    • graine <math>\(FX\)</math>
    • règles :
      <math>\(X \mapsto X+YF+\)</math>
      <math>\(Y \mapsto -FX-Y\)</math>

    Ce qui se traduit simplement comme suit: Partir d'un segment de base; puis en suivant la courbe, remplacer chaque segment par deux segments à angle droit en effectuant une rotation de 45° alternativement à droite puis à gauche. (source: Wikipédia)


    Niveau 2

    Créer un programme permettant de tracer et visualiser la courbe du dragon à partir de l'ensemble limite de l'IFS suivant (sur le plan complexe) :

    <math>\(f_1(z)=\frac{(1+i)z}{2}\)</math>
    <math>\(f_2(z)=1-\frac{(1-i)z}{2}\)</math>

    Si vous ne connaissez pas les nombres complexes, vous pouvez remplacer ces deux fonctions par ces expressions analytiques (applications affines sur un repère orthonormé) :
    <math>\(\left\{ \begin{array}{r c l} x' & = & \frac{x-y}{2} \\ y' & = & \frac{x+y}{2} \end{array} \right .\)</math>
    <math>\(\left\{ \begin{array}{r c l} x' & = & 1-\frac{x+y}{2} \\ y' & = & 1-\frac{y-x}{2} \end{array} \right .\)</math>


    Conclusion



    Bon courage à tous ! :)

    Participants



    Participants Code
    Pouet_forever Niveau 1
    Tickyletroll Niveau 1
    yoch Niveau 1
    Niveau 2
    • Partager sur Facebook
    • Partager sur Twitter
      29 octobre 2011 à 22:57:11

      Ah tiens, j'avais pas vu que mon exo était posté (par qui ?). Je fais un petit up... ;)

      PS : Au passage, si vous ne comprenez pas quelque chose à l'énoncé, ou si un point vous semble peu clair, vous pouvez poser des questions ici, on essaiera de vous aider. :)
      • Partager sur Facebook
      • Partager sur Twitter
        31 octobre 2011 à 18:34:37

        Avec comme règles :

        <math>\(\begin{align} X&\to X + YF\\ Y&\to FX - Y \end{align}\)</math>
        ça m'a donné ça :

        dragon curve


        mais c'est en Java, donc le code on verra plus tard :-°
        J'avais une pseudo-implémentation de Logo codée, donc ça a pas été très long. Je vais essayer de coder ça en C, mais ne m'étant quasiment jamais servi de la SDL ça va peut-être prendre un moment.
        • Partager sur Facebook
        • Partager sur Twitter
          31 octobre 2011 à 20:03:08

          Citation : Pouet_forever

          Oh la belle bleue ! :o

          Image utilisateur


          Le code est où ? Tu l'as fait avec des L-System, des IFS (on dirait pas, on voit des lignes), ou encore un autre truc ?
          • Partager sur Facebook
          • Partager sur Twitter
            31 octobre 2011 à 21:28:29

            Pour le dessin, j'utilise asymptote (proche du C), et voilà ce qu'on trouve en exemple.
            http://www.piprime.fr/844/l-system-wit [...] tote-fig0120/
            • Partager sur Facebook
            • Partager sur Twitter
              31 octobre 2011 à 21:35:20

              Bonjour, je poste pour penser à tester quand je pourrais programmer, ça a l'air intéressant.
              • Partager sur Facebook
              • Partager sur Twitter
                1 novembre 2011 à 0:40:44

                Citation : yoch

                Le code est où ? Tu l'as fait avec des L-System, des IFS (on dirait pas, on voit des lignes), ou encore un autre truc ?


                Voilà le code :

                void dragon(SDL_Surface * sfc, int n, int x, int y, int z, int t) {
                  int u, v;
                  
                  if (n <= 1) {
                    line(sfc, x, y, z, t);
                  }
                  else {
                    u = (x + z + t - y) / 2;
                    v = (y + t - z + x) / 2;
                    dragon(sfc, n - 1, x, y, u, v);
                    dragon(sfc, n - 1, z, t, u, v);
                  }
                }
                

                Honteusement pompé sur ce site. :p Je sais pas si c'est l system ou ifs, mais c'est court et efficace. :-°
                J'ai aussi fait le l system, mais c'est plus long et plus moche. :D
                Pour le fait qu'on voit les lignes, c'est fait exprès. ;)

                D'ailleurs, si vous voulez des participants, faudrait étoffer un peu plus votre présentation. Sérieusement, une fois que j'ai lu votre truc, j'ai qu'une envie c'est de ne pas faire le truc. :-°
                • Partager sur Facebook
                • Partager sur Twitter
                  1 novembre 2011 à 0:52:33

                  Intéressent, je note qu'il faudrait que je participe un jour à celui-ci ;)
                  • Partager sur Facebook
                  • Partager sur Twitter
                  🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.
                    1 novembre 2011 à 9:05:10

                    A mon tour de me lancer dans les défis en C.

                    Voici une première image de la courbe du dragon itération 12.


                    Courbe dragon iteration 12


                    Je vais améliorer mon programme et poster le code !


                    Je me suis amusé à tout représenter sous forme de pliage, donc une méthode reposant sur la géométrie.


                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 novembre 2011 à 11:14:24

                      Citation : Pouet_forever

                      D'ailleurs, si vous voulez des participants, faudrait étoffer un peu plus votre présentation. Sérieusement, une fois que j'ai lu votre truc, j'ai qu'une envie c'est de ne pas faire le truc. :-°


                      Bon, je prends acte, vu que je suis le fautif présumé. Pour être plus constructif, tu pourrais détailler un peu plus ta critique ?

                      @Tickyletroll : Joli, je serais curieux de voir ton code.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        1 novembre 2011 à 12:14:45

                        Je pense notamment à détailler un peu plus ce qu'est le l system et l'ifs, ou sans trop détailler, comment passer d'un truc purement théorique à un code. Parce qu'en fait, une fois qu'on a fini de lire la présentation, on est dans le flou et on se dit 'ouah, c'est trop mathématique et compliqué comme truc j'y arriverai pas' alors qu'en fait c'est pas très compliqué. Le programmeur néophyte fera demi-tour, c'est certain. :)
                        Ma remarque vallait surtout sur le vide qu'il y a entre la partie théorique et le code. ;)
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          1 novembre 2011 à 12:20:15

                          Je dois dire que je suis d'accord avec Pouet, j'ai vu l'énoncé et ça m'a un peu refroidi (bon j'avais un peu la flemme avouons-le).
                          • Partager sur Facebook
                          • Partager sur Twitter
                            1 novembre 2011 à 13:08:56

                            Aller, histoire de dire que c'est moi qui ai fait le code et que j'ai pas fait que pomper sur le net. :-°

                            #include <stdio.h>
                            #include <stdlib.h>
                            
                            #include <SDL.h>
                            
                            enum {
                              SCR_W = 800,
                              SCR_H = 600,
                              SCR_BPP = 32,
                              SCR_FLAGS = SDL_HWSURFACE
                            };
                            
                            enum {
                              PX_LINE = 2,
                              STARTX  = 400,
                              STARTY  = 200,
                              NITER   = 15
                            };
                            
                            enum {
                              UP,
                              RIGHT,
                              DOWN,
                              LEFT
                            };
                            
                            /*
                             * Set the pixel at (x, y) to the given value
                             * NOTE: The surface must be locked before calling this!
                             */
                            void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel) {
                              int bpp = surface->format->BytesPerPixel;
                              /* Here p is the address to the pixel we want to set */
                              Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
                              
                              if (x < 0 || y < 0 || x >= SCR_W || y >= SCR_H)
                                return;
                              
                              switch(bpp) {
                                case 1:
                                  *p = pixel;
                                  break;
                                  
                                case 2:
                                  *(Uint16 *)p = pixel;
                                  break;
                                  
                                case 3:
                                  if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
                                    p[0] = (pixel >> 16) & 0xff;
                                    p[1] = (pixel >> 8) & 0xff;
                                    p[2] = pixel & 0xff;
                                  } else {
                                    p[0] = pixel & 0xff;
                                    p[1] = (pixel >> 8) & 0xff;
                                    p[2] = (pixel >> 16) & 0xff;
                                  }
                                  break;
                                  
                                case 4:
                                  *(Uint32 *)p = pixel;
                                  break;
                              }
                            }
                            
                            void line(SDL_Surface * sfc, int x1, int y1, int x2, int y2) {
                              int x, y;
                              int dx, dy;
                              int e, ex, ey;
                              int i;
                              
                              dy = y2 - y1;
                              dx = x2 - x1;
                              y = y1;
                              x = x1;
                              
                              ex = (dx > 0) ? 1 : -1;
                              ey = (dy > 0) ? 1 : -1;
                              dy *= ey;
                              dx *= ex;
                              
                              if (dx > dy) {
                                e = dx / 2;
                                for (i = 0; i < dx; i++) {
                                  e += dy;
                                  if (e >= dx) {
                                    y += ey;
                                    e -= dx;
                                  }
                                  x += ex;
                                  putpixel(sfc, x, y, SDL_MapRGB(sfc->format, 0, 0xFF, 0xFF));
                                }
                              }
                              else {
                                e = dy / 2;
                                for (i = 0; i < dy; i++) {
                                  e += dx;
                                  if (e >= dy) {
                                    x += ex;
                                    e -= dy;
                                  }
                                  y += ey;
                                  putpixel(sfc, x, y, SDL_MapRGB(sfc->format, 0, 0xFF, 0xFF));
                                }
                              }
                            }
                            
                            int init(void) {
                              if (SDL_Init(SDL_INIT_VIDEO) < 0) {
                                fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
                                return -1;
                              }
                              atexit(SDL_Quit);
                              
                              if (SDL_SetVideoMode(SCR_W, SCR_H, SCR_BPP, SCR_FLAGS) == NULL) {
                                fprintf(stderr, "Couldn't set video mode: %sn",SDL_GetError());
                                return -1;
                              }
                              SDL_WM_SetCaption("Dragon curve", NULL);
                              
                              return 0;
                            }
                            
                            int changeWay(int c, int way) {
                              int t;
                              
                              switch (c) {
                                case '-':
                                  if (way == UP)
                                    t = RIGHT;
                                  else if (way == RIGHT)
                                    t = DOWN;
                                  else if (way == DOWN)
                                    t = LEFT;
                                  else if (way == LEFT)
                                    t = UP;
                                  break;
                                case '+':
                                  if (way == UP)
                                    t = LEFT;
                                  else if (way == RIGHT)
                                    t = UP;
                                  else if (way == DOWN)
                                    t = RIGHT;
                                  else if (way == LEFT)
                                    t = DOWN;
                                  break;
                                default:
                                  break;
                              }
                              
                              return t;
                            }
                            
                            void drawLine(SDL_Surface * sfc, int * x, int * y, int sz, int way) {
                              int u, v;
                              
                              switch (way) {
                                case UP:
                                  u = *x;
                                  v = *y - sz;
                                  break;
                                case LEFT:
                                  u = *x - sz;
                                  v = *y;
                                  break;
                                case DOWN:
                                  u = *x;
                                  v = *y + sz;
                                  break;
                                case RIGHT:
                                  u = *x + sz;
                                  v = *y;
                                  break;
                                default:
                                  break;
                              }
                              
                              line(sfc, *x, *y, u, v);
                              *x = u;
                              *y = v;
                            }
                            
                            void dragon(SDL_Surface * sfc, char * s, int n, int * x, int * y, int sz, int * way) {
                              if (n < 1)
                                return;
                              
                              while (*s) {
                                switch (*s) {
                                  case 'F':
                                    drawLine(sfc, x, y, sz, *way);
                                    break;
                                  case 'X':
                                    dragon(sfc, "X+YF+", n - 1, x, y, sz, way);
                                    break;
                                  case 'Y':
                                    dragon(sfc, "-FX-Y", n - 1, x, y, sz, way);
                                    break;
                                  case '-':
                                  case '+':
                                    *way = changeWay(*s, *way);
                                    break;
                                  default:
                                    break;
                                }
                                s++;
                              }
                            }
                            
                            void loop(void) {
                              SDL_Surface * screen;
                              Uint8 * key;
                              int done;
                              int x, y, way;
                              
                              screen = SDL_GetVideoSurface();
                              key = SDL_GetKeyState(NULL);
                              done = 0;
                              x = STARTX;
                              y = STARTY;
                              way = RIGHT;
                              
                              SDL_FillRect(screen, NULL, 0);
                              dragon(screen, "FX", NITER, &x, &y, PX_LINE, &way);
                              SDL_Flip(screen);
                              
                              while (!SDL_QuitRequested()) {
                                SDL_PumpEvents();
                                if (key[SDLK_ESCAPE])
                                  break;
                                SDL_Delay(10);
                              }
                            }
                            
                            int main(int argc, char ** argv) {
                              if (init() < 0)
                                return EXIT_FAILURE;
                              
                              loop();
                              
                              SDL_FreeSurface(SDL_GetVideoSurface());
                              return EXIT_SUCCESS;
                            }
                            
                            • Partager sur Facebook
                            • Partager sur Twitter
                              1 novembre 2011 à 17:23:07

                              Voici mon code pour une vision géométrique de la courbe.

                              J'ai rajouté quelques fonctionnalités comme le tracé de la courbe pas par pas.
                              les touches utilisables sont:
                              - d pour aller plus vite
                              - q pour quitter
                              - p pour pause
                              - espace pour sauvegarder en bmp.

                              tab[MAX] contient l'ensemble des directions gauche, droite de la courbe.


                              #include <stdlib.h>
                              #include <SDL.h>
                              #include <unistd.h>
                              
                              //taille maximale du tableau contenant la courbe
                              #define MAX 8000
                              
                              //nombre d'itération pour construire la courbe
                              #define IT_MAX 12
                              
                              //taille d'un segment de la courbe
                              #define PAS 5
                              
                              //paramètres de la fenêtre
                              #define LONGUEUR_FENETRE 700
                              #define LARGEUR_FENETRE 500
                              
                              enum
                              {
                                NORD = 0,
                                EST = 1,
                                SUD = 2,
                                OUEST = 3
                              };
                              
                              typedef struct
                              {
                                Sint16 x, y;
                              } SDL_point;
                              
                              SDL_Surface *affichage;
                              
                              
                              void affiche_tab (short int tab[MAX], int limite);
                              
                              
                              /*------------------------------------------------------------------------
                              | Fonctions d'affichage pour la SDL de points et de droites pour la
                              | SDL récupéré sur http://anomaly.developpez.com/tutoriel/sdl/partie1/
                              | Je remercie anomaly pour son travail.
                              |-----------------------------------------------------------------------*/
                              void ligne (int x1, int y1, int x2, int y2, Uint32 coul);
                              void echangerEntiers (int *x, int *y);
                              void setPixel (int x, int y, Uint32 coul);
                              void setPixelVerif (int x, int y, Uint32 coul);
                              
                              
                              /*------------------------------------------------------------------------
                              |Fonction qui génère la représentation de la courbe du dragon dans un
                              |tableau tab[MAX].
                              |
                              |Codage de l'adn du bestiau:
                              | Droite est codé par 1 
                              | Gauche est codé par 0 
                              |-----------------------------------------------------------------------*/
                              void genere_courbe_dragon (short int tab[MAX], int iteration, int *a);
                              
                              int main (void)
                              {
                                //creation de la courbe
                                short int tab[MAX] = { 0 };
                                int i,k,limite=1, direction=EST;
                                genere_courbe_dragon(tab,IT_MAX, &limite);
                                printf ("Iteration %i, longueur de %i\n", IT_MAX, limite);
                              
                                //initialisation de l'affichage et affichage de la courbe 
                                SDL_Init (SDL_INIT_VIDEO);
                                atexit (SDL_Quit);
                                SDL_Event event;
                                int continuer = 1,pause =1, attente=2;
                              
                                affichage =SDL_SetVideoMode (LONGUEUR_FENETRE, LARGEUR_FENETRE, 32, SDL_SWSURFACE);
                                Uint32 mcolor = SDL_MapRGB (affichage->format, 0, 0, 255);
                              
                                //initialisation du point de départ de la courbe, on commence par l'est.
                                SDL_point depart={LONGUEUR_FENETRE * 2 / 3,LARGEUR_FENETRE * 1 / 3};
                                SDL_point arrivee={depart.x + PAS, depart.y};
                              
                                ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                                depart.x = arrivee.x;
                                depart.y = arrivee.y;
                                SDL_UpdateRect (affichage, 0, 0, 0, 0);
                              
                                //gestion des évènements
                                SDL_EnableKeyRepeat (0, 0);
                                i = 0;  //indicateur de quel morceau de la courbe est tracé.
                              
                                while (continuer)
                                  {
                                    while (SDL_PollEvent (&event))
                              	{
                              	  switch (event.type)
                              	    {
                              	    case SDL_QUIT:
                              	      continuer = 0;
                              	      break;
                              	    case SDL_KEYDOWN:
                              	      switch (event.key.keysym.sym)
                              		{
                              		case SDLK_SPACE:
                              		  SDL_SaveBMP (affichage, "courbe_dragon.bmp");
                              		  break;
                              		case SDLK_q:
                              		  continuer =0;
                              		  break;
                              		case SDLK_d:
                              		  attente =0;
                              		  break;
                              		case SDLK_p:
                              		  pause ^= 1;
                              		  break;
                              		default:
                              		  ;
                              		  break;
                              		}
                              	      break;
                              	    default:
                              	      ;
                              	      break;
                              	    }
                              	}
                              
                                    if (i<limite && pause)
                                    {
                                    //tracé morceau par morceau de la courbe
                                    if (tab[i] == 1)
                              	direction = direction + 1;
                                    else
                              	direction = direction - 1;
                                    if (direction > 3)
                              	direction = 0;
                                    if (direction < 0)
                              	direction = 3;
                                    switch (direction)
                              	{
                              	case 0:
                              	  arrivee.x = depart.x;
                              	  arrivee.y = depart.y - PAS;
                              	  ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                              	  depart.x = arrivee.x;
                              	  depart.y = arrivee.y;
                              	  break;
                              	case 1:
                              	  arrivee.x = depart.x + PAS;
                              	  arrivee.y = depart.y;
                              	  ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                              	  depart.x = arrivee.x;
                              	  depart.y = arrivee.y;
                              	  break;
                              	case 2:
                              	  arrivee.x = depart.x;
                              	  arrivee.y = depart.y + PAS;
                              	  ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                              	  depart.x = arrivee.x;
                              	  depart.y = arrivee.y;
                              	  break;
                              	case 3:
                              	  arrivee.x = depart.x - PAS;
                              	  arrivee.y = depart.y;
                              	  ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                              	  depart.x = arrivee.x;
                              	  depart.y = arrivee.y;
                              	  break;
                              	}	
                                      i=i+1;
                                      SDL_UpdateRect (affichage, 0, 0, 0, 0);
                              	SDL_Delay(attente);
                                    }
                                  }
                              
                                SDL_Quit ();
                                return 0;
                              }
                              
                              
                              
                              void genere_courbe_dragon (short int tab[MAX], int iteration, int *a)
                              {
                                int i, j;
                                int lim;
                                tab[0] = 1;
                                lim = 1;
                                for (i = 1; i < IT_MAX; i++)
                                  {
                                    //on rajoute un chemin à Droite
                                    tab[lim] = 1;
                                    //puis on parcourt la courbe à l'envers en inversant D et G
                                    for (j = (lim - 1); j > (-1); j--)
                              	{
                              	  if (tab[j] == 1)
                              	    tab[lim + lim - j] = 0;
                              	  else
                              	    tab[lim + lim - j] = 1;
                              	}
                                    //on actualise le nombre d'éléments que contient la courbe.
                                    lim = 2 * lim + 1;
                                  }
                                *a=lim;
                              }
                              
                              
                              
                              
                              void affiche_tab (short int tab[MAX], int limite)
                              {
                                int i = 0;
                                for (i = 0; i < limite; i++)
                                  printf ("%i", tab[i]);
                                printf ("\n");
                              }
                              
                              
                              
                              void setPixelVerif (int x, int y, Uint32 coul)
                              {
                                if (x >= 0 && x < affichage->w && y >= 0 && y < affichage->h)
                                  setPixel (x, y, coul);
                              }
                              
                              
                              
                              
                              void setPixel (int x, int y, Uint32 coul)
                              {
                                *((Uint32 *) (affichage->pixels) + x + y * affichage->w) = coul;
                              }
                              
                              
                              
                              void ligne (int x1, int y1, int x2, int y2, Uint32 coul)
                              {
                                int d, dx, dy, aincr, bincr, xincr, yincr, x, y;
                              
                                if (abs (x2 - x1) < abs (y2 - y1))
                                  {
                                    /* parcours par l'axe vertical */
                              
                                    if (y1 > y2)
                              	{
                              	  echangerEntiers (&x1, &x2);
                              	  echangerEntiers (&y1, &y2);
                              	}
                              
                                    xincr = x2 > x1 ? 1 : -1;
                                    dy = y2 - y1;
                                    dx = abs (x2 - x1);
                                    d = 2 * dx - dy;
                                    aincr = 2 * (dx - dy);
                                    bincr = 2 * dx;
                                    x = x1;
                                    y = y1;
                              
                                    setPixelVerif (x, y, coul);
                              
                                    for (y = y1 + 1; y <= y2; ++y)
                              	{
                              	  if (d >= 0)
                              	    {
                              	      x += xincr;
                              	      d += aincr;
                              	    }
                              	  else
                              	    d += bincr;
                              
                              	  setPixelVerif (x, y, coul);
                              	}
                              
                                  }
                                else
                                  {
                                    /* parcours par l'axe horizontal */
                              
                                    if (x1 > x2)
                              	{
                              	  echangerEntiers (&x1, &x2);
                              	  echangerEntiers (&y1, &y2);
                              	}
                              
                                    yincr = y2 > y1 ? 1 : -1;
                                    dx = x2 - x1;
                                    dy = abs (y2 - y1);
                                    d = 2 * dy - dx;
                                    aincr = 2 * (dy - dx);
                                    bincr = 2 * dy;
                                    x = x1;
                                    y = y1;
                              
                                    setPixelVerif (x, y, coul);
                              
                                    for (x = x1 + 1; x <= x2; ++x)
                              	{
                              	  if (d >= 0)
                              	    {
                              	      y += yincr;
                              	      d += aincr;
                              	    }
                              	  else
                              	    d += bincr;
                              
                              	  setPixelVerif (x, y, coul);
                              	}
                                  }
                              }
                              
                              
                              
                              void echangerEntiers (int *x, int *y)
                              {
                                int t = *x;
                                *x = *y;
                                *y = t;
                              }
                              


                              le Makefile au besoin
                              all: ligne_dragon
                              
                              SDLFLAGS = `sdl-config --cflags`
                              SDLLIB = `sdl-config --libs`
                              
                              ligne_dragon: ligne_dragon.o
                              	gcc $(CFLAGS) -Wall ligne_dragon.o -o ldragon $(SDLLIB)
                              
                              ligne_dragon.o: ligne_dragon.c
                              	gcc $(CFLAGS) $(SDLFLAGS) -Wall -c ligne_dragon.c 
                              
                              clean:
                              	rm -f *.o ldragon
                              	rm -f *~ *.*~
                              


                              et le code dépouillé:


                              #include <stdlib.h>
                              #include <SDL.h>
                              #include <unistd.h>
                              
                              //taille maximale du tableau contenant la courbe
                              #define MAX 8000
                              
                              //nombre d'itération pour construire la courbe
                              #define IT_MAX 12
                              
                              //taille d'un segment de la courbe
                              #define PAS 5
                              
                              //paramètres de la fenêtre
                              #define LONGUEUR_FENETRE 700
                              #define LARGEUR_FENETRE 500
                              
                              enum
                              {
                                NORD = 0,
                                EST = 1,
                                SUD = 2,
                                OUEST = 3
                              };
                              
                              typedef struct
                              {
                                Sint16 x, y;
                              } SDL_point;
                              
                              SDL_Surface *affichage;
                              
                              
                              void affiche_tab (short int tab[MAX], int limite);
                              
                              
                              /*------------------------------------------------------------------------
                              | Fonctions d'affichage pour la SDL de points et de droites pour la
                              | SDL récupéré sur http://anomaly.developpez.com/tutoriel/sdl/partie1/
                              | Je remercie anomaly pour son travail.
                              |-----------------------------------------------------------------------*/
                              void ligne (int x1, int y1, int x2, int y2, Uint32 coul);
                              void echangerEntiers (int *x, int *y);
                              void setPixel (int x, int y, Uint32 coul);
                              void setPixelVerif (int x, int y, Uint32 coul);
                              
                              
                              /*------------------------------------------------------------------------
                              |Fonction qui génère la représentation de la courbe du dragon dans un
                              |tableau tab[MAX].
                              |
                              |Codage de l'adn du bestiau:
                              | Droite est codé par 1 
                              | Gauche est codé par 0 
                              |-----------------------------------------------------------------------*/
                              void genere_courbe_dragon (short int tab[MAX], int iteration, int *a);
                              
                              int main (void)
                              {
                                //creation de la courbe
                                short int tab[MAX] = { 0 };
                                int i,limite=1, direction=EST;
                                genere_courbe_dragon(tab,IT_MAX, &limite);
                                printf ("Iteration %i, longueur de %i\n", IT_MAX, limite);
                              
                                //initialisation de l'affichage et affichage de la courbe 
                                SDL_Init (SDL_INIT_VIDEO);
                                atexit (SDL_Quit);
                              
                              
                                affichage =SDL_SetVideoMode (LONGUEUR_FENETRE, LARGEUR_FENETRE, 32, SDL_SWSURFACE);
                                Uint32 mcolor = SDL_MapRGB (affichage->format, 0, 0, 255);
                              
                                //initialisation du point de départ de la courbe, on commence par l'est.
                                SDL_point depart={LONGUEUR_FENETRE * 2 / 3,LARGEUR_FENETRE * 1 / 3};
                                SDL_point arrivee={depart.x + PAS, depart.y};
                              
                                ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                                depart.x = arrivee.x;
                                depart.y = arrivee.y;
                              
                                SDL_UpdateRect (affichage, 0, 0, 0, 0);
                              
                                //tracé complet de la courbe
                                for(i=0;i<limite;i++)
                                 {
                                    if (tab[i] == 1)
                              	direction = direction + 1;
                                    else
                              	direction = direction - 1;
                                    if (direction > 3)
                              	direction = 0;
                                    if (direction < 0)
                              	direction = 3;
                                    switch (direction)
                              	{
                              	case 0:
                              	  arrivee.x = depart.x;
                              	  arrivee.y = depart.y - PAS;
                              	  ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                              	  depart.x = arrivee.x;
                              	  depart.y = arrivee.y;
                              	  break;
                              	case 1:
                              	  arrivee.x = depart.x + PAS;
                              	  arrivee.y = depart.y;
                              	  ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                              	  depart.x = arrivee.x;
                              	  depart.y = arrivee.y;
                              	  break;
                              	case 2:
                              	  arrivee.x = depart.x;
                              	  arrivee.y = depart.y + PAS;
                              	  ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                              	  depart.x = arrivee.x;
                              	  depart.y = arrivee.y;
                              	  break;
                              	case 3:
                              	  arrivee.x = depart.x - PAS;
                              	  arrivee.y = depart.y;
                              	  ligne (depart.x, depart.y, arrivee.x, arrivee.y, mcolor);
                              	  depart.x = arrivee.x;
                              	  depart.y = arrivee.y;
                              	  break;
                                      }
                                 }
                                SDL_UpdateRect (affichage, 0, 0, 0, 0);
                                SDL_Delay(5000);
                                SDL_Quit ();
                                return 0;
                              }
                              
                              
                              
                              void genere_courbe_dragon (short int tab[MAX], int iteration, int *a)
                              {
                                int i, j;
                                int lim;
                                tab[0] = 1;
                                lim = 1;
                                for (i = 1; i < IT_MAX; i++)
                                  {
                                    //on rajoute un chemin à Droite
                                    tab[lim] = 1;
                                    //puis on parcourt la courbe à l'envers en inversant D et G
                                    for (j = (lim - 1); j > (-1); j--)
                              	{
                              	  if (tab[j] == 1)
                              	    tab[lim + lim - j] = 0;
                              	  else
                              	    tab[lim + lim - j] = 1;
                              	}
                                    //on actualise le nombre d'éléments que contient la courbe.
                                    lim = 2 * lim + 1;
                                  }
                                *a=lim;
                              }
                              
                              
                              
                              
                              void affiche_tab (short int tab[MAX], int limite)
                              {
                                int i = 0;
                                for (i = 0; i < limite; i++)
                                  printf ("%i", tab[i]);
                                printf ("\n");
                              }
                              
                              
                              
                              void setPixelVerif (int x, int y, Uint32 coul)
                              {
                                if (x >= 0 && x < affichage->w && y >= 0 && y < affichage->h)
                                  setPixel (x, y, coul);
                              }
                              
                              
                              
                              
                              void setPixel (int x, int y, Uint32 coul)
                              {
                                *((Uint32 *) (affichage->pixels) + x + y * affichage->w) = coul;
                              }
                              
                              
                              
                              void ligne (int x1, int y1, int x2, int y2, Uint32 coul)
                              {
                                int d, dx, dy, aincr, bincr, xincr, yincr, x, y;
                              
                                if (abs (x2 - x1) < abs (y2 - y1))
                                  {
                                    /* parcours par l'axe vertical */
                              
                                    if (y1 > y2)
                              	{
                              	  echangerEntiers (&x1, &x2);
                              	  echangerEntiers (&y1, &y2);
                              	}
                              
                                    xincr = x2 > x1 ? 1 : -1;
                                    dy = y2 - y1;
                                    dx = abs (x2 - x1);
                                    d = 2 * dx - dy;
                                    aincr = 2 * (dx - dy);
                                    bincr = 2 * dx;
                                    x = x1;
                                    y = y1;
                              
                                    setPixelVerif (x, y, coul);
                              
                                    for (y = y1 + 1; y <= y2; ++y)
                              	{
                              	  if (d >= 0)
                              	    {
                              	      x += xincr;
                              	      d += aincr;
                              	    }
                              	  else
                              	    d += bincr;
                              
                              	  setPixelVerif (x, y, coul);
                              	}
                              
                                  }
                                else
                                  {
                                    /* parcours par l'axe horizontal */
                              
                                    if (x1 > x2)
                              	{
                              	  echangerEntiers (&x1, &x2);
                              	  echangerEntiers (&y1, &y2);
                              	}
                              
                                    yincr = y2 > y1 ? 1 : -1;
                                    dx = x2 - x1;
                                    dy = abs (y2 - y1);
                                    d = 2 * dy - dx;
                                    aincr = 2 * (dy - dx);
                                    bincr = 2 * dy;
                                    x = x1;
                                    y = y1;
                              
                                    setPixelVerif (x, y, coul);
                              
                                    for (x = x1 + 1; x <= x2; ++x)
                              	{
                              	  if (d >= 0)
                              	    {
                              	      y += yincr;
                              	      d += aincr;
                              	    }
                              	  else
                              	    d += bincr;
                              
                              	  setPixelVerif (x, y, coul);
                              	}
                                  }
                              }
                              
                              
                              
                              void echangerEntiers (int *x, int *y)
                              {
                                int t = *x;
                                *x = *y;
                                *y = t;
                              }
                              
                              • Partager sur Facebook
                              • Partager sur Twitter
                                1 novembre 2011 à 19:08:44

                                Bonsoir,

                                Un petit code pour la version L-System.

                                Le code est réduit au strict minimum, et n'est pas trop générique (pour d'autres L-System avec des angles un peu plus exotiques), mais le principe est bien là.

                                Code :


                                #include <stdlib.h>
                                #include <SDL.h>
                                
                                
                                #define SCR_W   1200
                                #define SCR_H   800
                                #define SEG_SZ  3
                                
                                SDL_Surface* screen = NULL;
                                
                                
                                /* Dessine un pixel - mode 32 bits */
                                void setPixel(int x, int y, Uint32 color)
                                {
                                    if (x >= 0 && x < screen->w && y >= 0 && y < screen->h)
                                    {
                                        Uint8 *p = (Uint8 *)screen->pixels + y * screen->pitch + x * screen->format->BytesPerPixel;
                                        *(Uint32 *)p = color;
                                    }
                                }
                                
                                /* Trace une ligne (horizontale ou verticale uniquement) */
                                #define swap(a,b)   { int tmp = a; a = b; b = tmp; }
                                void draw_line(int x1, int y1, int x2, int y2, Uint32 color)
                                {
                                    int i;
                                    if (y1 == y2)  // horizontal line
                                    {
                                        if (x1 > x2) swap(x1, x2);
                                        for (i=x1; i <=x2; i++)
                                            setPixel(i, y1, color);
                                    }
                                    else if (x1 == x2)  // vertical line
                                    {
                                        if (y1 > y2) swap(y1, y2);
                                        for (i=y1; i <=y2; i++)
                                            setPixel(x1, i, color);
                                    }
                                }
                                
                                
                                int directions[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };  // vers la droite
                                int cursor[] = {SCR_W/3,SCR_H/3};
                                unsigned direction = 1;
                                #define NB  15      // profondeur de recursion
                                
                                void dragon_curve (const char* s, unsigned depth)
                                {
                                    while (*s)
                                    {
                                        switch (*s)
                                        {
                                        case 'X':
                                            if (depth)
                                                dragon_curve ("X+YF+", depth-1);
                                            break;
                                        case 'Y':
                                            if (depth)
                                                dragon_curve ("-FX-Y", depth-1);
                                            break;
                                        case 'F':
                                            {
                                            int x = cursor[0], y = cursor[1];
                                            cursor[0] += SEG_SZ*directions[direction][0];
                                            cursor[1] += SEG_SZ*directions[direction][1];
                                            draw_line(x, y, cursor[0], cursor[1], SDL_MapRGB(SDL_GetVideoSurface()->format, 255, 255, 255));
                                            }
                                            break;
                                        case '+':
                                            direction = (direction+1)%4;
                                            break;
                                        case '-':
                                            direction = (direction+3)%4;
                                            break;
                                        }
                                        s++;
                                    }
                                }
                                
                                int main ( int argc, char** argv )
                                {
                                    unsigned done;
                                    SDL_Event event;
                                
                                    /*  initialise SDL video */
                                    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
                                    {
                                        fprintf( stderr, "Unable to init SDL: %s\n", SDL_GetError() );
                                        return 1;
                                    }
                                
                                    screen = SDL_SetVideoMode(SCR_W, SCR_H, 32, SDL_HWSURFACE);
                                
                                    dragon_curve("FX", NB);
                                
                                    SDL_Flip(screen);
                                
                                    done = 0;
                                    while (!done)
                                    {
                                        SDL_WaitEvent(&event);
                                        switch (event.type)
                                        {
                                        case SDL_QUIT:
                                            done = 1;
                                            break;
                                
                                        default:
                                            break;
                                
                                        } /* fin switch (event.type) */
                                    } /* fin boucle evenementielle */
                                
                                    SDL_Quit();
                                    return 0;
                                }
                                


                                Image :


                                Cliquez pour agrandir
                                </span>
                                Image utilisateur


                                • Partager sur Facebook
                                • Partager sur Twitter
                                  12 novembre 2011 à 20:40:25

                                  Bonsoir,

                                  Dommage que personne n'a tenté avec les IFS, ce n'était pas particulièrement difficile.

                                  Voici un code pour tracer la courbe du dragon avec l'IFS donné dans l'énoncé :

                                  #include <stdlib.h>
                                  #include <SDL.h>
                                  #include <math.h>
                                  #include <complex.h>
                                  #include <time.h>
                                  
                                  
                                  
                                  /* Dimensions de l'ecran */
                                  #define SCR_LARGEUR     800
                                  #define SCR_HAUTEUR     800
                                  /* couleurs */
                                  #define BLANC           SDL_MapRGB(surface->format, 255, 255, 255)
                                  #define NOIR            SDL_MapRGB(screen->format, 0, 0, 0)
                                  /* nb iterations */
                                  #define ITER            20
                                  /* nombre de fonctions */
                                  #define N               2
                                  
                                  #define rand_a_b(a,b)   ((double)rand()/RAND_MAX)*(b-a) + a;
                                  
                                  
                                  
                                  /* Dessine un pixel - mode 32 bits */
                                  void setPixel(SDL_Surface* surface, int x, int y, Uint32 color)
                                  {
                                      if (x >= 0 && x < surface->w && y >= 0 && y < surface->h)
                                      {
                                          Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * surface->format->BytesPerPixel;
                                          *(Uint32 *)p = color;
                                      }
                                  }
                                  
                                  
                                  complex double F0 (complex double z)
                                  {
                                      return ((1+I)*z)/2;
                                  }
                                  
                                  complex double F1 (complex double z)
                                  {
                                      return 1-((1-I)*z)/2;
                                  }
                                  
                                  // tableau des fonctions
                                  complex double (*tFunctions[])(complex double) = {  F0,F1  };
                                  
                                  
                                  /* fonction de dessin */
                                  void draw_dragon_curve (SDL_Surface* surface)
                                  {
                                      unsigned i, j;
                                      double x, y;
                                      complex double z;
                                      /* tirage aleatoire d'un pixel de l'ecran */
                                      for (i=0; i<surface->w*surface->h; i++)
                                      {
                                          //x = rand_a_b(-1,1);
                                          //y = rand_a_b(-1,1);
                                          x = y = 0;
                                          z = x + y * I;
                                          for (j=0; j<=ITER; j++)
                                          {
                                              // choisit aleatoirement la fonction
                                              z = tFunctions[rand() % N](z);
                                          }
                                          // les nombres ajoutes sont pour centrer l'image
                                          setPixel(surface, (creal(z)+0.6)*((double)surface->w/2), (cimag(z)+1)*((double)surface->h/2), BLANC);
                                      }
                                  }
                                  
                                  int main ( int argc, char** argv )
                                  {
                                      SDL_Event event;
                                      SDL_Surface* screen;
                                  
                                      srand(time(NULL));
                                      /*  initialise SDL video */
                                      if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
                                      {
                                          printf( "Unable to init SDL: %s\n", SDL_GetError() );
                                          return 1;
                                      }
                                  
                                      /*  make sure SDL cleans up before exit */
                                      atexit(SDL_Quit);
                                  
                                      /*  create a new window */
                                      screen = SDL_SetVideoMode(SCR_LARGEUR,SCR_HAUTEUR,32,SDL_HWSURFACE);
                                      SDL_FillRect(screen, NULL, NOIR);
                                  
                                      draw_dragon_curve (screen);
                                      /* actualise l'affichage */
                                      SDL_Flip(screen);
                                  
                                      unsigned done = 0;
                                      while (!done)
                                      {
                                          /* attente d'un evenement */
                                          SDL_WaitEvent(&event);
                                          /*  on traite l'evenement */
                                          switch (event.type)
                                          {
                                              /* fermeture de la fenetre */
                                          case SDL_QUIT:
                                              done = 1;
                                              break;
                                  
                                          } /* fin switch (event.type) */
                                      } /* fin boucle evenementielle */
                                  
                                      return 0;
                                  }
                                  


                                  Comme vous pouvez le voir, le code est très simple. :)

                                  On peut faire des jolies choses avec les IFS, un petit exemple en image, créée avec un petit logiciel fait maison, utilisant les IFS :

                                  Cliquez pour agrandir
                                  Image utilisateur


                                  On peut faire de très jolies choses avec les L-System aussi, notamment en 3D...
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    12 novembre 2011 à 22:13:15

                                    J'avais codé ça l'année dernière en créant une image au format pgm. (donc sans SDL) Ce format est lisible par le logiciel The GIMP.

                                    #include <stdio.h>
                                    #include <stdlib.h>
                                    #include <time.h>
                                    #include <string.h>
                                    
                                    #if defined(__WIN32__) || defined(__WIN64__)
                                    #include <io.h>
                                    #else
                                    #include <unistd.h>
                                    #endif
                                    
                                    #define NB_PIXEL_PAR_CASE 6
                                    #define NB_PIXELS_LIGNE 3
                                    
                                    static void at(int t[], int i, int j, int longueur, int hauteur, int value)
                                    {
                                    #if defined (DEBUG)
                                    	if(i >= 0 && i < longueur && j >= 0 && j < hauteur)
                                    #endif
                                    		t[i + longueur * j] = value;
                                    #if defined (DEBUG)
                                    	else
                                    		fprintf(stderr,"Erreur : i : %d (l : %d), j : %d (h : %d)\n",i,longueur,j,hauteur);
                                    #endif
                                    }
                                    
                                    static int * augmenter_dragon(int * dragon, int n, int init)
                                    {
                                    	int i;
                                    
                                    	dragon[n] = init;
                                    	for(i = 1;i<=n;i++)
                                    		dragon[i + n] = (dragon[n - i] ^ 1);
                                    	return dragon;
                                    }
                                    
                                    /** \brief cr?e un dragon de taille 2^taille - 1
                                    * @param taille entier permettant de conna?tre la taille du futur dragon
                                    * @param init entier permettant de conna?tre la g?n?ration du dragon
                                    * @return renvoie le nouveau dragon cr??
                                    * le dragon dragon est lib?r? de la m?moire ? la fin de la fonction
                                    */
                                    int * creer_dragon(int taille,int init)
                                    {
                                    	int i;
                                    	int n,_init;
                                    	int * res = malloc(sizeof(int) * ((1 << taille) - 1));
                                    	for(i = 0,n = 1,_init = init;i<taille;i++,n<<=1,_init>>=1)
                                    		augmenter_dragon(res,n-1,_init & 1);
                                    	return res;
                                    }
                                    
                                    /** \brief compte la place que prendra le dragon
                                    * @param dragon tableau contenant les virages du dragon
                                    * @param n taille du dragon
                                    * @param plongueur_min pointeur vers un entier qui contiendra l'oppos? de la longueur_min
                                    * @param plongueur_max pointeur vers un entier qui contiendra la longueur_max
                                    * @param phauteur_min pointeur vers un entier qui contiendra l'oppos? de la hauteur_min
                                    * @param phauteur_max pointeur vers un entier qui contiendra la hauteur_max
                                    */
                                    static void compter_place_dragon(int const * dragon, int n,
                                    								 int * plongueur_min, int * plongueur_max,
                                    								 int * phauteur_min, int * phauteur_max)
                                    {
                                    	int i;
                                    	int longueur_act = 0, hauteur_act = 1, direction = 0;
                                    	*plongueur_min = 0; *plongueur_max = 0;
                                    	*phauteur_min = 0; *phauteur_max = 1;
                                    	
                                    	for(i = 0;i<n;i++)
                                    	{
                                    		// on commence par avancer
                                    		switch(direction)
                                    		{
                                    			case 0: //on va ? droite, donc la longueur augmente de 1
                                    				longueur_act++;
                                    				if(*plongueur_max < longueur_act)
                                    					*plongueur_max = longueur_act;
                                    				break;
                                    			case 1: //on va en bas, donc la hauteur diminue de 1
                                    				hauteur_act--;
                                    				if(*phauteur_min > hauteur_act)
                                    					*phauteur_min = hauteur_act;
                                    				break;
                                    			case 2: // on va ? gauche, donc la longueur diminue de 1
                                    				longueur_act--;
                                    				if(*plongueur_min > longueur_act)
                                    					*plongueur_min = longueur_act;
                                    				break;
                                    			case 3: // on va en haut, donc la hauteur augmente de 1
                                    				hauteur_act++;
                                    				if(*phauteur_max < hauteur_act)
                                    					*phauteur_max = hauteur_act;
                                    				break;
                                    		}
                                    		// ensuite, on tourne
                                    		direction = (direction - 1 + 2 * dragon[i]) & 3;
                                    	}
                                    }
                                    
                                    /** remplit la case correspondante dans le tableau qui permettra de g?n?rer l'image
                                    * @param tab tableau contenant les donn?es n?cessaires ? limage du dragon
                                    * @param i colonne qu'il faut remplir
                                    * @param j ligne qu'il faut remplir
                                    * @param longueur largeur de l'image
                                    * @param depart direction depuis laquelle on arrive
                                    * @param arrivee direction vers laquelle on part
                                    */
                                    void traiter(int tab[],int i, int j, int longueur, int hauteur, int depart, int arrivee)
                                    {
                                    	int cpt;
                                    	const int tab_values[2 * NB_PIXELS_LIGNE] = {0,1,2,3,4,5};
                                    	i *= NB_PIXEL_PAR_CASE;
                                    	j *= NB_PIXEL_PAR_CASE;
                                    	if((depart == 0 && arrivee == 3) || (depart == 1 && arrivee == 2)) // coin sup?rieur gauche
                                    	{
                                    		for(cpt = 0;cpt<NB_PIXELS_LIGNE;cpt++)
                                    			at(tab,i+tab_values[cpt],j+tab_values[NB_PIXELS_LIGNE-1-cpt],longueur,hauteur,1);
                                    	}
                                    	else if((depart == 0 && arrivee == 1) || (depart == 3 && arrivee == 2)) //coin inf?rieur gauche
                                    	{
                                    		for(cpt = 0;cpt<NB_PIXELS_LIGNE;cpt++)
                                    			at(tab,i+tab_values[cpt],j+tab_values[NB_PIXELS_LIGNE+cpt],longueur,hauteur,1);
                                    	}
                                    	else if((depart == 3 && arrivee == 0) || (depart == 2 && arrivee == 1)) //coin inf?rieur droit
                                    	{
                                    		for(cpt = 0;cpt<NB_PIXELS_LIGNE;cpt++)
                                    			at(tab,i+tab_values[NB_PIXELS_LIGNE+cpt],j+tab_values[2 * NB_PIXELS_LIGNE - 1 - cpt],longueur,hauteur,1);
                                    	}
                                    	else //coin sup?rieur droit
                                    	{
                                    		for(cpt = 0;cpt<NB_PIXELS_LIGNE;cpt++)
                                    			at(tab,i+tab_values[NB_PIXELS_LIGNE + cpt],j+tab_values[cpt],longueur,hauteur,1);
                                    	}
                                    
                                    }
                                    
                                    /** \brief remplit le fichier ? l'aide des valeurs de temp
                                    * @param fichier flux vers lequel on ?crit ce qu'il faut pour dessiner le dragon
                                    * @param tmp tableau contenant les donn?es pour ?crire ce qui est n?cessaire pour dessiner le dragon
                                    * @param longueur largeur de l'image finale
                                    * @param hauteur hauteur de l'image finale
                                    */
                                    void ecrire(FILE * fichier,int const * tmp,int longueur,int hauteur)
                                    {
                                    	int i;
                                    	fprintf(fichier,"P2\n"); // pour dire qu'on est en pgm
                                    	fprintf(fichier,"%d %d\n",longueur,hauteur); // on renseigne sur les dimensions de l'image
                                    	fprintf(fichier,"1\n"); // on renseigne sur la valeur maximale prise
                                    	for(i = 0;i< hauteur * longueur;i++) // on remplit avec le tableau
                                    		fprintf(fichier,"%d ",tmp[i]);
                                    }
                                    
                                    /** \brief affiche le dragon pass? en param?tre dans le fichier pass? en param?tre
                                    * @param dragon dragon ? dessiner
                                    * @param n taille du dragon ? dessiner
                                    * @param nom_fichier nom du fichier dans lequel sera stock? le dragon
                                    * dessine dans le fichier (auquel on ajoute l'extension pgm) le dragon pass? en param?tre
                                    */
                                    void dessiner(int const * dragon, int n, char const * nom_fichier)
                                    {
                                    	FILE * fichier = NULL;
                                    	char * fichier_tmp = NULL;
                                    	int * tmp = NULL;
                                    	int i,j,cpt;
                                    	int longueur, hauteur;
                                    	int depart,arrivee = 0; // permet de savoir de quel coin on part et ? quel coin on arrive
                                    
                                    	int longueur_min, longueur_max;
                                    	int hauteur_min, hauteur_max;
                                    
                                    
                                    	// on cr?e le nom du fichier ? partir de ce qu'on avait en argument
                                    	j = strlen(nom_fichier) + 5;
                                    	fichier_tmp = malloc(sizeof(char) * j);
                                    	if(fichier_tmp == NULL)
                                    	{
                                    		free(tmp);
                                    		return;
                                    	}
                                    	for(i = 0;i < j - 5;i++)
                                    		fichier_tmp[i] = nom_fichier[i];
                                    
                                    	fichier_tmp[j-5] = '.';
                                    	fichier_tmp[j-4] = 'p';
                                    	fichier_tmp[j-3] = 'g';
                                    	fichier_tmp[j-2] = 'm';
                                    	fichier_tmp[j-1] = '\0';
                                    	// on compte le nombre de cases qu'il faudra pour contenir le dragon
                                    	compter_place_dragon(dragon,n,
                                    						 &longueur_min,&longueur_max,
                                    						 &hauteur_min,&hauteur_max);
                                    	longueur = longueur_max - longueur_min + 1;
                                    	hauteur = hauteur_max - hauteur_min + 1;
                                    	longueur *= NB_PIXEL_PAR_CASE;
                                    	hauteur *= NB_PIXEL_PAR_CASE;
                                    	// on alloue le tableau interm?diaire n?cessaire pour dessiner le dragon
                                    	tmp = malloc(sizeof(int) * longueur * hauteur);
                                    	if(tmp == NULL)
                                    		return;
                                    	// on initialise toutes ses coordonn?es ? 0
                                    	for(cpt = 0;cpt<longueur * hauteur;cpt++)
                                    		tmp[cpt] = 0;
                                    	
                                    	i = -longueur_min;
                                    	j = hauteur_max - 1;
                                    	// on traite la direction dans laquelle on va
                                    	for(cpt = 0;cpt<n;cpt++)
                                    	{
                                    		depart = arrivee;
                                    		switch(arrivee)
                                    		{
                                    			case 0: //on va ? droite
                                    				i++;
                                    				break;
                                    			case 1: //on va en bas
                                    				j++;
                                    				break;
                                    			case 2: // on va ? gauche
                                    				i--;
                                    				break;
                                    			case 3: // on va en haut
                                    				j--;
                                    				break;
                                    		}
                                    		arrivee = (arrivee - 1 + (2 * dragon[cpt])) & 3;
                                    		traiter(tmp,i,j,longueur,hauteur,depart,arrivee);
                                    	}
                                    	
                                    	// on ouvre le fichier
                                    	fichier = fopen(fichier_tmp,"w");
                                    	if(fichier != NULL)
                                    	// on ?crit dedans
                                    	{
                                    		ecrire(fichier,tmp,longueur,hauteur);
                                    		fclose(fichier);
                                    	}
                                    	// on lib?re tout ce qui doit l'?tre
                                    	free(fichier_tmp);
                                    	free(tmp);
                                    }
                                    
                                    int main(int argv, char* argc[])
                                    {
                                    	char nom_fichier[1000];
                                    	int * v = NULL;
                                    	int n = 0;
                                    	int taille = 0,init, nb = 1;
                                    	int cpt = 0;
                                    
                                    	int res_sc, i, j, c;
                                    
                                    	srand(time(NULL));
                                    	printf("Quelle doit etre la taille de votre dragon ? ");
                                    	while((res_sc = scanf("%d",&taille)) != 1 && res_sc != EOF)
                                    		while((c = getchar()) != '\n' && c != EOF);
                                    
                                    	printf("Combien de dessins voulez-vous creer ? ");
                                    	while((res_sc = scanf("%d",&nb)) != 1 && res_sc != EOF)
                                    		while((c = getchar()) != '\n' && c != EOF);
                                    	
                                    	n = (1 << taille) - 1;
                                    	for(i = 0;i<nb;i++)
                                    	{
                                    		printf("%d\n",init = (rand() % (1 << taille)));
                                    		sprintf(nom_fichier,"dragon_%d_%d",taille,init);
                                    		// si on a d?j? ?crit ce fichier, on ne le refait pas
                                    		if(!access(nom_fichier,F_OK))
                                    		{
                                    			i--;
                                    			cpt++;
                                    			if(cpt > nb)
                                    				break;
                                    			continue;
                                    		}
                                    		v = creer_dragon(taille,init);
                                    		dessiner(v,n,nom_fichier);
                                    		free(v);
                                    		v = NULL;
                                    	}
                                    	return 0;
                                    }
                                    


                                    Ca prend vite beaucoup de place (plus de 2GO pour une "taille" d'environ 22), alors que toutes les informations nécessaires pour la création du dragon sont contenues dans le nom du fichier pgm créé.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      4 novembre 2015 à 21:25:36

                                      la courbe du dragon

                                      -
                                      Edité par AlphaIssagaDiallo1 4 novembre 2015 à 21:40:01

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        4 novembre 2015 à 21:34:38

                                        Alpha Issaga Diallo a écrit: programme C++   LA COURBE DU DRAGON

                                        #include <iostream>

                                        #include <vector>

                                        #include <cmath>

                                        #include "graphics.h"

                                        using namespace std;

                                        void dragon (int n, vector <bool> &c) {

                                                        c.resize(static_cast<int>(pow(2,n))-1);

                                                        c[0] = false;

                                                        int i = 0;

                                                        for (int pliage = 2 ; pliage <= n ; pliage++) {

                                                                       c[++i] = false;

                                                                       for (int j = i-1 ; j >=0 ; j--) {

                                                                                       c[++i] = !c[j];

                                                                       }

                                                        }

                                        }

                                        void afficheCode(vector <bool> &c) {

                                                        for (int i = 0 ; i < c.size() ; i++) {

                                        cout<<c[i]<<" ; ";

                                                        }

                                        }

                                        void quelDirection(int dir, int &x , int &y , int lon) {

                                                        switch (dir) {

                                                                       case 0:

                                                                                       x+=lon;

                                        break;

                                                                       case 1:

                                                                                       y-=lon;

                                                                                       break;

                                                                       case 2:

                                                                                       x-=lon;

                                                                                       break;

                                                                       case 3:

                                                                                       y+=lon;

                                                                                       break;

                                                        }

                                        }

                                        void dessineDragon(const vector <bool> &c, int x, int y, int dir, int lon, int cool) {

                                                        if (0 > dir || dir > 3) return;

                                                        setcolor(cool);

                                                        moveto(x,y);

                                                        for (int i = 0 ; i < c.size() ; i++) {

                                                                       quelDirection(dir, x , y , lon);

                                                                       lineto(x,y);

                                                                       if (c[i]) {

                                                                                       dir +=3;

                                                                       } else {

                                                                                       dir +=1;

                                                                       }

                                                                       dir=dir%4;

                                                        }

                                                        quelDirection(dir, x , y , lon);

                                                        lineto(x,y);

                                        }

                                        int main (int argc, char** argv) {

                                                        vector <bool> c;

                                                        int n;

                                                        cout<<"Quelle est la taille du dragon ?\n";

                                                        cin>>n;

                                                        dragon(n,c);

                                                        //afficheCode(c);

                                                        int x,y,dir,lon,cool;

                                                        x = 700;

                                                        y = 400;

                                                        lon = 2;

                                                        dir = 0;

                                                        cool = GREEN;

                                                        opengraphsize(1600,900);

                                                        setcolor(cool);

                                                        setbkcolor(BLACK);

                                                        cleardevice();

                                                        dessineDragon(c,x,y,dir,lon,cool);

                                                        dessineDragon(c,x,y,1,lon,RED);

                                                        dessineDragon(c,x,y,2,lon,YELLOW);

                                                        dessineDragon(c,x,y,3,lon,BLUE);

                                                        getch();

                                                        return 0;

                                        }



                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          4 novembre 2015 à 21:41:06

                                          Salut,

                                          bouton </> pour présenter ton code, et bouton en haut à droite de tes messages pour les modifier.

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          [FAIT][Défis] #6 : Dessinez la courbe du dragon

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                          • Editeur
                                          • Markdown