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.
La forma de declarar una función de dibujo sin parámetros será la que sigue:
void miFigura(){
// código que dibuja la figura
}
void
implica que es una función que no “regresa” un valor.miFigura
puede ser cualquier nombre que queramos, mientras no sea una de las palabras reservadas de Processing()
indica que es una función y que no hay parámetros{ }
engloban el bloque de código que le pertenece a la función.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()
.
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.
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
}
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();
}
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);
}
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();
}