Test de xrvg avec la fractale Dragon Curve
Xrvg est une bibliothèque permettant la création de fichiers svg à partir de code. Why_ en parle comme outil pour s’amuser à créer des fractales avec quelques exemples de l’auteur de xvrg. Mais la vraie utilité, pour moi, est de créer tout ce qui est diagramme quand on ne sait se servir de sa souris, son trackball ou son trackpoint qu’avec ses deux mains gauches.
Néanmoins, tracer des fractales est un bon test, ludique qui plus est, de xrvg. Voilà donc la dragon curve dessiné avec xrvg. Pour ce faire, j’ai utilisé un L-system et un petit turtle personnel pour cette fractale. Et bien sûr xrvg. Merci Julien Léonard pour cette belle lib qu’est xrvg.
Coté algorithme
On retrouve un bon vieux L-system caractérisé par :
- les variables :
F,X,Yqui sont des lignes droites identiques - les constantes :
+,-qui correspondent à des rotations de90° et-90° dans le sens trigonométrique. - l’axiome de départ :
FX - les règles :
X=> X+YF+etY=> -FX-Y
Pour la tortue, j’ai juste limité les directions à 0°,90°,180°,270° ce qui me permet de ne pas utiliser de sinusoïdes. Ensuite, c’est le classique point 2 qui devient point 1 et point 2 dessiné à un endroit précis.
Le code est sûrement améliorable, on est dans le naïf là. On doit aussi pouvoir utiliser la méthode du pliage pour retrouver la même chose (un vieux code de ma prime jeunesse grandement améliorable, soyez indulgents ou utilisez le comme exercice de refactoring)
Le code
#!/usr/bin/env ruby
#Copyright (c) 2008 Bessot Jean-Michel
#
## Permission is hereby granted, free of charge, to any person obtaining a copy
## of this software and associated documentation files (the "Software"), to deal
## in the Software without restriction, including without limitation the rights
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
## copies of the Software, and to permit persons to whom the Software is
## furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included in
## all copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
## THE SOFTWARE.
#
require "rubygems"
require "xrvg"
include XRVG
sentence="FX"
puts "nb iteration : "
n = gets.chomp.to_i
#L-system part
n.times do
tmp = ""
sentence.each_byte do |sym|
if sym.chr == "X"
tmp = tmp + "X+YF+"
elsif sym.chr == "Y"
tmp = tmp + "-FX-Y"
else
tmp = tmp + sym.chr
end
sentence = tmp
end
end
puts sentence
#parsing part
sentence = sentence.gsub('+-','')
angular=0
p1=[0.0,0.0]
p2=[10.0,0.0]
i=0
render = SVGRender[ :filename, "dragon-curve-"+n.to_s+".svg", :background, "white" ]
sentence.each_byte do |sym|
case sym.chr
when "F"
render.add(Line[:points,[V2D[p1[0],p1[1]], V2D[p2[0],p2[1]]]],Style[ :stroke, "red" ] )
when "X"
render.add(Line[:points,[V2D[p1[0],p1[1]], V2D[p2[0],p2[1]]]],Style[ :stroke, "green"] )
when "Y"
render.add(Line[:points,[V2D[p1[0],p1[1]], V2D[p2[0],p2[1]]]],Style[ :stroke, "blue"] )
when "+"
angular=angular + 1
if angular == 3
angular = -1
end
i=1
when "-"
angular=angular -1
if angular == -3
angular = 1
end
i=2
end
#make the angular for turtle
if i==0
p1=p2 + [0,0]
if angular == 0
p2[0] = p2[0] + 10
elsif angular == 1
p2[1] = p2[1] + 10
elsif angular == -1
p2[1] = p2[1] - 10
else
p2[0] = p2[0] - 10
end
elsif i==1
if angular == 0
p2[0] = p2[0] + 10
p2[1] = p2[1] + 10
elsif angular == 1
p2[0] = p2[0] - 10
p2[1] = p2[1] +10
elsif angular == -1
p2[0] = p2[0]+10
p2[1] = p2[1]-10
else
p2[0] = p2[0]-10
p2[1] = p2[1]-10
end
elsif i==2
if angular == 0
p2[0] = p2[0] + 10
p2[1] = p2[1] - 10
elsif angular == 1
p2[0] = p2[0] + 10
p2[1] = p2[1] + 10
elsif angular == -1
p2[0] = p2[0] -10
p2[1] = p2[1] - 10
else
p2[0] = p2[0] - 10
p2[1] = p2[1] +10
end
end
# print "[",p1[0]," ",p1[1],"]","[",p2[0]," ",p2[1],"]",i," ",angular,"\n"
i=0
end
render.end
Résultats du programme
Ici F est en rouge, X en vert et Y en bleu.
À venir
Le peu que j’ai vu de xrvg semble vraiment très sympathique même si il faut plus qu’un dragon-curve pour en déceler le potentiel. Je risque de publier de petits scripts l’utilisant de temps à autres.