Repetición: dibujar un árbol

March 25, 2008 – 11:27 pm

La recursión es una técnica de repetición muy usada tanto en el GenerArt como en la InfoVis.

En el GenerArt su poder reside en la capacidad de crear resultados sorprendentes e inesperados a partir de reglas muy sencillas. Los fractales y los Sistema-L són un claro ejemplo.

Aquí veremos un ejemplo en el que dibujaremos un árbol mediante una regla sencilla.


Un árbol puede definirse como una rama principal (dibujada mediante una linea recta) en la extremidad de la cual dibujamos dos arboles más pequeños inclinados.

En esta definición de árbol utilizamos de nuevo la palabra árbol, estas son las situaciones claras en las que podemos hacer uso de la recursión.

Este sería el código a utilizar (no os asustéis por la longitud del código, más de la mitad son comentarios):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 
void arbol(float tallaRama, float angulo){
  // Si la rama que tenemos que dibujar
  // es demasiado pequeña, salimos de la recursion
  if(tallaRama < 2){
     return; 
  }
 
  // Dibujamos nuestra rama
  // Recordamos que en Processing las coordenadas de las "y" apuntan hacia abajo
  // y las de las "x" hacia la derecha
  // entonces para dibujar hacia arriba debemos dar una "y" negativa (y=-tallaRama)
  line(0, 0, 0, -tallaRama);
 
  // Nos posicionamos al final de la rama que hemos dibujado
  translate(0, -tallaRama);
 
  // Definimos la nueva talla de la rama 
  // tiene que reducirse respecto a la rama anterior
  // ATENCION: si la reduccion de la talla de la rama
  //           es muy pequeña la recursion no acabara nunca
  //           y se bloqueara la applicacion
  //           (cuidado con los valores < a 1.4)
  float nuevaTallaRama = tallaRama / 1.6;
 
 
 
  // Guardamos nuestro estado
  // Esto es necesario porque
  // sino acumulamos todas las rotaciones
  // y no conseguimos bifurcar las ramas
  pushMatrix();
 
  // Giramos hacia el contrario 
  // de las agujas del reloj de la mitad de nuestro angulo
  // para dibujar la otra rama secundaria
  rotate(angulo / 2);
 
  // Dibujamos la rama secundara
  // En realidad dibujamos de nuevo un segundo arbol
  // Aqui es donde convertimos esta funcion en recursiva
  arbol(nuevaTallaRama, angulo);
 
  // Volvemos a nuestro estado
  // Para no acumular las rotaciones (rotate) y movimientos (translate)
  // Esto nos permite crear una bifurcacion
  popMatrix();
 
 
 
  // Guardamos nuestro estado
  pushMatrix();
 
  // Giramos hacia el contrario 
  // de las agujas del reloj de la mitad de nuestro angulo
  // para dibujar la otra rama secundaria
  rotate(-angulo / 2);
 
  arbol(nuevaTallaRama, angulo);
 
  // Volvemos a nuestro estado
  popMatrix();
}
 
void setup(){
  // Definimos la talla de nuestra pantalla
  size(500, 500); 
 
  // Pintamos el fondo de blanco
  background(255);
 
  // Cogemos el lapiz de color negro
  stroke(0);
 
  // Nos situamos a bajo (y=height) y al centro de la pantalla (x=width/2)
  translate(width/2, height);
 
  // Dibujamos un arbol con un rama inicial de 100 pixeles
  // y cuyas ramas secundarias formaran un angulo 90 grados (debemos convertir a radianes)
  arbol(100, radians(90));
}

Post a Comment