« | »

Context Free Art Grammar – Introduction

J’ai récemment découvert un petit logiciel libre et gratuit que j’aime beaucoup, Context Free. Il permet, à partir d’instructions qu’on lui donne, de générer des dessins. On peut lui donner des instructions récursives, c’est à dire qui se répètent en boucle, ce qui est pratique pour dessiner des fractales, et/ou aléatoires, qui nous donneront un résultat chaque fois différent.

Arbre généré à partir du code de la fin du tutoriel

Je vous invite à visiter la galerie de Context Free Art pour avoir un aperçu de ce dont ce logiciel est capable. Et si grâce au petit tutoriel qui va suivre, vous arrivez à faire de jolies choses, n’hésitez pas à l’enrichir de vos créations !

On écrit ces instructions dans un langage qui s’appelle CFDG, pour Context Free Design Grammar. Voici une petite introduction pour commencer à faire vos propres créations en CFDG. Pour l’exemple, nous dessinerons des arbres comme celui que vous voyez ci-dessus, ce qui nous permettra à la fois de voir comment faire des instructions récursives et des instructions aléatoires. N’ayez surtout pas peur d’expérimenter, de modifier les nombres ou faire ce dont vous avez envie ! C’est comme ça que vous vous familiariserez vraiment avec ce langage.

Tout d’abord, il faut lui dire par où commencer. Pour ça on écrit startshape suivi du nom de la règle que l’on veut lui faire appliquer en premier. On peut décider de l’appeler comme on le veut, la seule contrainte étant que le nom ne doit pas contenir d’espaces ni de caractères qui ont une signification dans le code, comme les accolades que l’on va voir dans un instant, les / et les # qui servent à mettre des commentaires dans le code.

Donc, si j’écris startshape arbre et que j’appuie sur le bouton Render, il va chercher dans tout le code la règle qui s’appelle « arbre » et l’appliquer. Pour le moment je n’ai pas défini de règle « arbre », il va donc faire une erreur en disant qu’il n’a pas pu trouver la règle à appliquer.

Définissons donc notre règle. Pour lui annoncer que l’on va définir une règle, on écrit rule suivi du nom de la règle puis des instructions qu’elle contient entre des accolades. Même si la règle ne contient pas d’instruction, ce qui peut être utile dans certains cas, il faut quand même mettre les accolades. Ce qui nous donne, pour notre exemple :

CIRCLE{}
startshape arbre

rule arbre{ CIRCLE{} }

Chaque instruction est aussi suivie d’accolades, qui nous permettent d’ajuster l’instruction si on le souhaite. Ici, j’ai mis l’instruction CIRCLE{} qui lui demande dessiner un cercle.Il existe quatre sortes formes de base : le cercle, le carré, le triangle équilatéral et les formes de base que l’on peut définir nous-mêmes, mais que nous ne verrons pas dans ce tutoriel. Ces formes sont les éléments de base de tous les dessins, car ce sont les seules instructions qui dessinent vraiment quelquechose, toutes les
autres instructions ne servent qu’à dire comment et où elles doivent être dessinées. Pour dessiner un cercle on dira donc CIRCLE{}, pour un carré on mettra SQUARE{} et pour un triangle on écrira TRIANGLE{}.

Maintenant, si nous appuyons sur Render, nous voyons apparaître un gros cercle noir comme demandé. Il prend toute la place car Context Free redimensionne automatiquement l’image pour que le rendu soit le plus grand possible.

Nous voulons un arbre. Comment est fait notre arbre ? Nous voyons qu’il est composés de branches. Chaque branche est un trait. Nous voyons aussi que, au fur et à mesure que nous nous éloignons des racines la largeur d’une branche est de plus en plus petite. Voyons comment appliquer ça en CFDG.

Pour faire un trait à partir de cercles, il suffit d’en mettre côte à côte ou mieux, de les faire se chevaucher. Nous pourrions écrire :

Le rendu : 3 cercles les uns sur les autresstartshape arbre

rule arbre{
CIRCLE{}
CIRCLE{y 0.5}
CIRCLE{y 1}
//etc…
}

Quand il y a plusieurs instructions dans une règle, je passe à la ligne pour chaque instruction, c’est un choix, je trouve ça plus clair et je m’y retrouve mieux. Les // servent à mettre la ligne en « commentaire », c’est à dire que l’on indique au logiciel de ne pas tenir compte de ce qu’il y a écrit dans la ligne après les //.
À part ces petites remarques sur la forme, cette fois-ci nous avons donné des ajustements à deux de nos instructions : y 0.5 et y 1. y c’est l’axe vertical de notre dessin. L’axe horizontal est l’axe x. y 1 veut dire « déplace-toi de 1 vers le haut ». 1, c’est la hauteur ou la largeur du cercle ou du carré de base quand on ajuste pas sa taille. Si le nombre que l’on met après le y est positif on se déplace vers le haut, et s’il est négatif, on se déplace vers le bas. De la même manière, si on écrit x suivi d’un nombre positif on ira vers la droite, et si on écrit un nombre négatif on ira vers la gauche. J’ai choisi y car un arbre pousse à la verticale.

Ce morceau de code nous fait donc 3 cercles les uns sur les autres à la verticale et qui se chevauchent de moitié.

Si nous devions dessiner notre arbre comme ceci cercle par cercle, ce n’est pas demain la veille que nous aurions fini. Comme c’est tout le temps la même chose nous pouvons faire une règle récursive. Voici comment cela se présente :

Rendu : un picstartshape arbre

rule arbre{
CIRCLE{}

arbre{y 0.1 s 0.995}
}

Examinons ce que comprend le logiciel lorsqu’il exécute ce morceau de code :

  • Commençons par exécuter la règle arbre. (startshape arbre)
  • La règle arbre (rule arbre) dit de dessiner un cercle (CIRCLE{}) puis d’exécuter la règle arbre (arbre{ ), en la déplaçant de 0.1 (y 0.1) vers le haut et en la rétrécissant d’un chouïa (s 0.995).
  • La règle arbre dit de dessiner un cercle puis d’exécuter la règle arbre, en la déplaçant de 0.1 vers le haut et en la rétrécissant d’un chouïa.
  • La règle arbre dit de dessiner un cercle puis d’éxécuter la règle arbre, en la déplaçant de 0.1 vers le haut et en la rétrécissant d’un chouïa.
  • etc…

C’est donc sans fin ? En théorie, oui, mais en pratique, le logiciel s’arrête quand ce qu’il doit dessiner devient tellement petit que c’en est invisible. Ce qui veut dire aussi que si ce qu’il doit dessiner ne rétrécit pas, le logiciel ne s’arrête jamais, à moins d’appuyer sur le bouton Stop qui remplace le bouton Render lorsqu’il est en train de faire un rendu.

Comme vous l’avez deviné, s ajuste la taille (size en anglais), et donc une taille de 0.995 est un chouïa plus petite que la taille normale 1. À chaque fois que le logiciel applique une nouvelle fois la règle arbre un chouïa plus petite, il « oublie » tout ce qu’il a fait avant et pour lui, la nouvelle taille est la taille normale parce qu’il a oublié qu’il y avait jamais eu une taille plus grande. C’est pour cela que ça s’appelle « Context Free », « Sans Contexte », parce qu’il ne tient pas compte de ce qui se passe avant ou après. Ce qui veut dire aussi que lorsqu’il se déplace de 0.1 vers le haut, ce 0.1 est lui aussi à chaque fois plus petit, comme le cercle qu’il vient de dessiner, et chaque fois un peu plus haut.

On obtient donc un genre de pic qui pointe vers le haut.

L’arbre que je montre en haut n’a pas les branches aussi droites, elles sont légèrement courbes. Pour ça il faut un autre ajustement, r, comme rotation. Le nombre qui suit  r est l’angle en degrés, dans le sens contraire des aiguilles d’une montre.

Rendu: une spiralestartshape arbre

rule arbre{
CIRCLE{}

arbre{y 0.1 s 0.995 r 1}
}

En appuyant sur Render, on obtient une spirale ! De la même manière que le logiciel considère comme taille 1 une taille toujours plus petite à chaque fois qu’il répète le rétrécissement, tourner de 1 degré vers la gauche modifie la verticale à chaque fois un peu plus à gauche.

Passons maintenant aux branches. L’intérêt de dessiner notre arbre avec Context Free est qu’il peut les générer aléatoirement, avec les branches pas toujours au même endroit.

Rendu : un arbre dans le ventstartshape arbre

rule arbre 100{
CIRCLE{}
arbre{y 0.1 s 0.995 r 0.2}
}

rule arbre{
CIRCLE{}
arbre{y 0.1 s 0.85 r 15}
arbre{y 0.1 s 0.85 r -15}
}

Lorsque qu’on définit plusieurs règles qui portent le même nom, le logiciel choisit aléatoirement l’une ou l’autre. On peut l’influencer en mettant un nombre après le nom de la règle. Ici, j’ai mis 100 à la première règle arbre, ça veut dire qu’il y aura 100 chances sur 101 qu’il choisisse celle-ci, et 1 chance sur 101 qu’il choisisse l’autre. Si on ne précise pas, le logiciel fait comme si on avait écrit 1.

Dans la règle que j’ai ajoutée, je demande d’exécuter deux fois la règle arbre, pour qu’il fasse deux branches, une penchée vers la gauche, et l’autre vers la droite (r 15 et r -15) et plus petites (s 0.85). Appuyons sur Render. Voilà qui ressemble maintenant à un arbre, mais avec un peu trop de vent qui vient de la droite ! Il y a un autre défaut, c’est qu’au niveau des embranchements les petites branches partent du milieu du bout de la grosse branche, au lieu d’avoir leur côté aligné sur le côté de la grosse branche.

startshape arbre

rule arbre 100{
CIRCLE{}
arbre{y 0.1 s 0.995 r 0.2}
}

rule arbre{
CIRCLE{}
arbre{y 0.1 s 0.85 r 15 x -0.1}
arbre{y 0.1 s 0.85 r -15 x 0.1 flip 90}
}

Voici un nouvel ajustement : flip. Il sert à dessiner à l’envers, comme dans le reflet d’un miroir. Le nombre qui suit flip est l’angle de ce miroir : un angle de 0 est horizontal, et un angle de 90 vertical. Comme ça, les branches qui vont vers la droite se courbent aussi vers la droite, sans avoir eu à écrire toute une règle pour faire en sorte que des branches se courbent vers la droite.

Et notre code est fini ! Voici quelques exemples de rendus de ce même code :

Différentes variantes de l'arbre

Il est intéressant de préciser que dans mon exemple, les deux règles demandent au logiciel de dessiner une forme de base, mais ce n’est pas obligatoire : essayez donc d’enlever l’instruction CIRCLE{} de la première règle, et voyez ce qui se passe lorsque vous appuyez sur Render !

Il y a une dernière chose sur laquelle je veux attirer votre attention : la suite de lettres qui se trouve dans le champ à droite du bouton Render : la variante. C’est elle qui détermine les choix « aléatoires » du logiciel lorsqu’il y en a. Pour un même code et une même variante, le rendu sera toujours le même, mais comme il existe 321 272 406 variantes (toutes les combinaisons possibles avec 26 lettres de l’alphabet et 6 lettres maximum) on a de quoi faire une énorme forêt !

Dans un autre tutoriel je vous montrerai comment on peut mettre des couleurs là-dedans, mais aujourd’hui on va s’arrêter là, d’accord ?

Pour aller plus loin, il vous faudra lire la documentation en anglais,
ou bien poser vos questions sur le forum de Context Free, il semble qu’il y ait un bon nombre de francophones qui utilisent ce logiciel. Vous pouvez aussi copier coller le code des œuvres exposées dans la galerie dans votre logiciel Context Free et essayer de comprendre comment elles fonctionnent, en modifiant légèrement le code voir ce que ça change :)

    4 commentaires pour “Context Free Art Grammar – Introduction”


  1. Warning: Use of undefined constant imagecreatetruecolor - assumed 'imagecreatetruecolor' (this will throw an Error in a future version of PHP) in /public_html/wp-content/plugins/wavatars/wavatars.php on line 379

    Warning: A non-numeric value encountered in /public_html/wp-content/plugins/wavatars/wavatars.php on line 382
    Wavatar

    Si je n’m’abuse, ça fait quand même pas mal de temps que tu as découvert ce logiciel non ? ^_^

    Je ne crois pas que j’aurais la patience de faire du code comme ça.

    Mais bon, comme souvent, ton résultat est très beau :)


  2. Warning: Use of undefined constant imagecreatetruecolor - assumed 'imagecreatetruecolor' (this will throw an Error in a future version of PHP) in /public_html/wp-content/plugins/wavatars/wavatars.php on line 379

    Warning: A non-numeric value encountered in /public_html/wp-content/plugins/wavatars/wavatars.php on line 382
    Wavatar

    Oui en effet ça fait pas mal de temps, mais à l’époque où j’ai commencé à écrire ce tuto, c’était encore récent ^^


  3. Warning: Use of undefined constant imagecreatetruecolor - assumed 'imagecreatetruecolor' (this will throw an Error in a future version of PHP) in /public_html/wp-content/plugins/wavatars/wavatars.php on line 379

    Warning: A non-numeric value encountered in /public_html/wp-content/plugins/wavatars/wavatars.php on line 382
    Wavatar

    Je reviendrai à l’étude ici tout cela me semble trés bien, j’aimerai évoluer dans mes dessins, et avec photofiltre je commence à être limité .
    Un grand merci pour ces tutoriels et bon plan.


  4. Warning: Use of undefined constant imagecreatetruecolor - assumed 'imagecreatetruecolor' (this will throw an Error in a future version of PHP) in /public_html/wp-content/plugins/wavatars/wavatars.php on line 379

    Warning: A non-numeric value encountered in /public_html/wp-content/plugins/wavatars/wavatars.php on line 382
    Wavatar

    Bonjour Lison,

    Context Free n’a absolument rien à voir avec Photofiltre, tu ne peux pas éditer d’image ni même dessiner avec ta souris, tu peux que en générer des images que tu auras programmées.
    Si tu te sens limitée avec Photofiltre mais que tu veux éditer des images ou bien peindre, essaie plutôt the GIMP. Il n’est pas forcément facile à prendre en main, mais si tu prends le temps de l’apprivoiser tu ne le regretteras pas !
    Sinon si tu veux c’est vraiment peindre et que tu as une tablette graphique, tu peux essayer MyPaint, qui lui est entièrement fait pour la peinture, mais tu auras quand même besoin de GIMP ou de Photofiltre, ne serait-ce que pour recadrer la peinture.

Laissez un commentaire

Votre commentaire

Si vous savez vous en servir, vous pouvez utiliser ces balises xhtml :<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Votre adresse email ne sera pas divulguée.
Elle me sert à afficher votre avatar si vous en avez enregistré un sur Gravatar et à vous identifier comme visiteur honnête lors de vos prochains passages.

Les avatars aléatoires ont été générés avec le logiciel Context Free Art grâce au code créé par mycelium.