jardínBit

Funciones de dibujo

Podemos crear nuestras propias funciones para dibujar figuras específicas.

Hay varias ventajas:

En general, nos interesará crear funciones con parámetros para poderlas utilizar como las que conocemos line(), rect(), ellipse(), etc.

Pero hay veces en que escribir funciones, aunque no usen parámetros, ayuda bastante.

1 Funciones sin parámetros

La forma de declarar una función de dibujo sin parámetros será la que sigue:

void miFigura(){
   // código que dibuja la figura
}

Por ejemplo, puedo declarar esta función que dibuja una “equis” con su esquina superior izquierda en 0,0:

void equis(){
  line(0,0, 50,50);
  line(0,50,50,0);
}

Para utilizarla, solo será necesario llamar equis().

1.1 En contexto

Así se podría ver un programa completo con la función en contexto:

void setup(){
  size( 400, 400 );
}

void draw(){
  background(255); // fondo blanco

  translate( 200, 100); // mueve el origen 200 a la derecha y 100 abajo
  equis(); // dibuja la "equis"
}

void equis(){
  line(0,0, 50,50);
  line(0,50,50,0);
}

Nota que la función draw() queda un poco más clara cuando vemos que lo que se dibuja en ella es una “equis”, y no solo dos líneas con parámetros que habría que interpretar.

Nota también el uso de la traslación.

[Transformaciones]

2 Funciones con parámetros

Parametrizar nuestra figura nos permite dibujarla de múltiples maneras, variarla durante la ejecución del programa, y más.

Podemos tener tantos parámetros como queramos. Solo hay que establecer su tipo de dato, y el nombre con el que los llamaremos dentro de la función.

La forma de declarar una función de dibujo con dos parámetros x,y será la que sigue:

void miFigura(float x, float y){
   // código que dibuja la figura respecto a x, y
}

2.1 Uso de transformaciones

Podemos aprovechar las funciones de transformación para añadirle a nuestro dibujo la posibilidad de colocarse donde sea.

En el ejemplo anterior con la función equis(), sus vértices están descritos de manera constante (hardcoded).

Pero si agregamos transformaciones, podemos moverlos a donde queramos:

void equis( float x, float y ){
  // guarda la matriz de transformaciones antes de cualquier cosa
  pushMatrix(); 

  // traslada el origen (x, y) unidades:
  translate(x, y);

  // dibuja la figura sin cambio:
  line(0,0, 50,50);
  line(0,50,50,0);

  // recupera la matriz a como estaba antes:
  popMatrix();
}

[Transformaciones]

2.2 Uso de parámetros en vértices

Otra posibilidad, que en algunos contextos puede tener más sentido, es usar los parámetros directamente en los vértices de la figura.

Por ejemplo, el caso anterior podría quedar también así:

void equis( float x, float y ){
  // dibuja la figura respecto a x,y:
  line(x,y,   x+50,y+50);
  line(x,y+50,x+50,y);
}

En el caso de esa función, y dependiendo lo que queramos hacer, el 50 también podría convertirse en un parámetro, ya sea en cada eje, o para los dos ejes.

Por ejemplo:

void equis( float x, float y, float d ){
  // dibuja la figura respecto a x,y, con "tamaño" d:
  line(x,y,   x+d,y+d);
  line(x,y+d,x+d,y);
}

Como dato curioso, la función rect( ) que utilizamos, está definida en Processing de una manera parecida:

// versión simplificada de la función rect( )
void rect( float x, float y, float w, float h ){
  beginShape();
  vertex(x, y); // superior izquierda
  vertex(x+w, y); // superior derecha
  vertex(x+w, y+h); // inferior derecha
  vertex(x, y+h); //inferior izquierda
  endShape(CLOSE);
}

2.3 En contexto

Sin importar qué versión escojamos, podemos utilizarla y reutilizarla como cualquier otra función de dibujo:

void setup(){
  size( 400, 400 );
}

void draw(){
  background(255); // fondo blanco
  noFill();

  equis(10, 20); // dibuja la "equis" en 10, 20
  equis(50, 70); // dibuja la "equis" en 50, 70
}

void equis( float x, float y ){
  // guarda la matriz de transformaciones antes de cualquier cosa
  pushMatrix(); 

  // traslada a los valores dados por x, y:
  translate(x, y);

  // dibuja la figura sin cambio:
  line(0,0, 50,50);
  line(0,50,50,0);

  // recupera la matriz a como estaba antes:
  popMatrix();
}