Empezando con Processing

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

hola_mundoEn este artículo vamos a poner en marcha y probar nuestro IDE Processing y a empezar a conocer la sintaxis del lenguaje. Quiero que entiendas una cosa. Si bien el punto fuerte de Processing es su conectividad con Arduino, y la posibilidad de interactuar entre ambos entornos, lo que nos abre un infinito abanico de posibilidades, Processing también puede funcionar como entorno de desarrollo independiente, por sí mismo. Vamos a familiarizarnos un poco con Processing, antes de que Arduino entre en escena, y a esto dediacremos este artículo y los siguientes.

HOLA, MUNDO.

¿Cómo no? Vamos a empezar por el típico “Hola, mundo”. Veamos cómo. Abrimos nuestra ventana de Processing y, en el área de edición, escribimos, en la primera línea, lo siguiente:

print ("Hola, mundo. Aquí estoy.");

Sólo eso. Esa única línea de código. Ahora grabamos el sketch. Para ello abrimos el menú Archivo y seleccionamos la opción Guardar como.... Se nos abre un cuadro de diálogo para que escojamos donde lo queremos guardar. Elegiremos el destino y. cómo nombre, le ponemos hola_mundo. Los sketches de Processing se guardan con la extensión .pde, pero esa nos la pone el sistema automáticamente. Nosotros sólo tenemos que poner el nombre.

ATENCIÓN. Al igual que Arduino, Processing crea una carpeta para cada sketch, con el mismo nombre que este. La carpeta se crea dentro de la ruta dónde has elegido guardar el sketch y, dentro de ella, se almacena el propio sketch. En ese sentido funciona igual que Arduino.

boton_reproduccionEs la hora de la verdad. Pulsamos el botón Ejecutar (ya lo conocemos del artículo anterior, pero lo vemos reproducido a la izquierda). En la consola de ejecución (la zona negra de la parte inferior de la ventana de Processing) vemos el resultado de la ejecución, cómo se muestra en la imagen a continuación:

La consola de ejecución, mostrando el resultado de nuestro primer sketch.

La consola de ejecución, mostrando el resultado de nuestro primer sketch.

ventana_flotante-de-processingAdemás, aunque en este caso no es relevante, quiero que repares en que se ha abierto una pequeña ventanita flotante, que vemos a la derecha de la reproducción de la consola. De momento, no hace nada, ni nos sirve para nada pero, en esa ventana sucederán muchas cosas interesantes cuando lleguemos a sketches interesantes. Por ahora sólo quédate con la copla.

Fíjate que cuando pulsas el botón Detener, en la parte superior de la ventana principal de Processing, la ventanita flotante se cierra por las buenas.

La instrucción print() que hemos usado, creo, se explica por sí sola. Vuelca el contenido que hay entre paréntesis (en nuestro ejemplo, una cadena de texto), en la consola. Cómo lo que queremos mostrar es una cadena de texto, va entrecomillada pero, por supuesto, las comillas no se muestran en el resultado; sólo la cadena en sí.

Esta instrucción tiene una alternativa que es println(). Actúa del mismo modo, pero añadiendo un salto de línea al final del volcado del contenido. Vamos a ver el sketch impresiones.pde, que nos ilustra esto.

El resultado lo vemos en la consola, donde podemos apreciar el efecto del salto de línea introducido por println(). Compruébalo en tu consola.

ALGO MÁS VISTOSO

La parrilla de dibujo, vista por Processing

La parrilla de dibujo, vista por Processing

Si tuviéramos que definir dónde radica la potencia de Processing, no pensaríamos en cálculos aritméticos, ni en acceso a datos, por ejemplo (aunque, por supuesto, el lenguaje cubre esos aspectos y muchos más). Pero el punto fuerte de Processing son los gráficos, así que vamos a empezar a ver cómo podemos manejarlos.

Los gráficos se van a visualizar en esa ventanita flotante que te mencionaba en el apartado anterior. Concretamente, en la zona gris central.

Para la creación de gráficos Processing utiliza una cuadríacula de píxeles, en la que cada gráfico se dibuja pixel a pixel. Los píxeles se definen mediante coordenadas X e Y, correspondiendo la esquina superior izquierda de la cuadrícula a las coordenadas 0, 0, de modo que el eje de las X aumenta según nos desplazamos a la derecha y el eje de las Y aumenta según nos desplazamos hacia abajo. En la imagen situada a la izquierda tienes un esquema que representa la zona de dibujo, tal cómo la ve Processing. Por supuesto, la parrila de dibujo no es de sólo 10 x 10 píxeles. Esto es a modo meramente esquemático, para que te hagas una idea. En la ventanita flotante que se nos abre al ejejutar un sketch, el tamaño de la zona de dibujo es de 100 x 100 aunque, por supuesto, eso lo podremos cambiar, cómo iremos viendo.

Observa el listado primer_grafico.pde:

Nuestro primer gráfico con Processing

Nuestro primer gráfico con Processing

A la derecha vemos la ventanita que se abre cuando pulsamos el botón Ejecutar, y que nos muestra el resultado de este código, que ahora analizaremos paso a paso.

EL COLOR

Lo primero que tenemos que zaber es como se gestiona el color en Processing. Esto lo necesitaremos para cualquier dearrollo que implique gráficos (lo que, en la práctica, significa una gran cantidad de los desarrollos que llevaremos a cabo con Processing).

El color se define con un total de hasta cuatro valores, que varían entre 0 y 255, y que son, según el orden en que se emplean en Processing, los siguientes;

  • Factor de rojo.
  • Factor de verde.
  • Factor de azul.
  • Factor alfa u opacidad, correspondiendo el 0 a transparencia total y el 255 a opacidad total.

 La forma adecuada de expresar el color es usando estos cuatro valores cómo argumentos de las funciones que afecten al color de los distintos elementos aunque, en algunas, sólo emplearemos los tres primeros y en otras el cuarto (el factor alfa), será opcional.

Cómo normal general, la sintaxis de aplicación de un color a un elemento que vayamos a usar es:

funcion (R, G, B, [A]);

La R corresponde a la intensidad de rojo, la G a la de verde, la B a la de azul y la A (opcional) al factor alfa).

Ahora suponte que quieres un color en el que no vayamos a definir al factor alfa y los tres colores fundamentales vayan a tener la misma intensidad (por ejemplo, blanco, en el que los tres serán 255, negro, en el que los tres serán 0, o un gris equilibrado). En ese caso podemos usar un solo argumento, entre 0 y 255, que indicará el nivel de los tres colores, asi:

funcion (n);

dónde n es un valor entre 0 y 255.

LOS ELEMENTOS BÁSICOS

Existen cuatro elementos que deberemos definir siempre (o casi siempre) que vayamos a plasmar un gráfico en Processing:

  • Tamaño del lienzo. Cómo hemos visto, Processing nos da para dibujar, si no especificamos otra cosa, un lienzo de 100 x 100 pixeles. Con la función size() podemos cambiar esto. Esta función recibe dos parámetros. El primero se refiere a la anchura y el segundo es la altura que deseamos, expresadas ambas en píxeles.
  • Color de fondo. Lo establecemos con la función background(), pasándole, como argumentos, los valores que definen el color de fondo para toda la zona de trabajo. Esta función no acepta el parámetro opcional relativo al factor alfa. Si lo incluyes, no te dará error, pero será ingnorado. Dicho de otro modo. El color de fondo del lienzo siempre es un tono 100% sólido. Si no lo establecemos, el color de fondo por defecto es gris.
  • Color de trazo. Lo aplicaremos con la función stroke(), pasándole, como argumentos, los valores que definen el color tanto para las líneas independientes cómo para el contorno de las figuras cerradas que se dibujen después del uso de esta instrucción. Si queremos que la próxima figura que vamos a dibujar no tenga contorno, usaremos la función noStroke(). Esta última no necesita ningún argumento. Si no establecemos un color de trazo, por defecto los sketches se inician con color negro.
  • Color de relleno. Lo aplicaremos con la función fill(), pasándole, como argumentos, los valores que definen el color de relleno para las figuras cerradas que dibujemos en lo sucesivo. Si queremos que la próxima figura que vamos a dibujar no tenga relleno usaremos la función noFill(). Esta última no necesita ningún argumento. Si no establecemos un color de relleno, por defecto los sketches se inician con color blanco.

Los dos primeros se establecen al principio del sketch y no suele ser necesario modificarlos durante el mismo.

LAS PRIMITIVAS BÁSICAS 2D

Processing contempla unas formas básicas para gráficos 2D (que es con lo que empezaremos, claro), y que nos facilitan el trabajo con nuestros diseños.

  • Trazado de puntos individuales. Para dibujar un punto en el lienzo (un único píxel) usaremos la función point(), que recibe dos argumentos, correspondientes a las coordenadas X e Y del pixel que queremos dibujar. El punto se dibujará en el color que se haya establecido con la función stroke().
  • Trazado de líneas rectas. Se emplea la función line(), que recibe cuatro argumentos: las coordenadas X e Y del punto inicial, y las coordenadas X e Y del punto final de la recta. Lógicamente, según las coordenadas que le demos a estos puntos, la línea podemos trazarla completamente horizintal, completamente vertical, o en cualquier ángulo que deseemos. La línea se trazará en el color establecido con stroke().
  • Dibujado de rectángulos. Se emplea la función rect(), que recibe cuatro argumentos: las coordenadas X e Y de la esquina superior izquierda, y las coordenadas X e Y de la esquina superior derecha. El rectángulo se dibujará con el color de contorno establecido con stroke() y el color de relleno establecido con fill().
  • Dibujado de elipses. Se emplea la función ellipse(). Esta recibe cuatro argumentos. Los dos primeros corresponden a las coordenadas X e Y del centro. El tercer parámetro es la anchura y el cuarto la altura de la elipse. Si estos dos últimos son iguales, la elipse será, realmente, un círculo, y lo dos últimos parámetros estarán indicando el diámetro. Tendrá el contorno del color establecido con stroke() y el relleno del color establecido con fill().
  • Dibujado de polígonos irregulares de cuatro lados. La función quad() nos permite dibujar un polígono de cuatro lados que no tiene por que ser un cuadrado o un rectángulo, es decir, que sus cuatro ángulos interiores no están constreñidos a tener 90º. El contorno será el definido con stroke() y el relleno el definido con fill(). Esta función recibe, nada menos, que ocho argumentos. Son cuatro pares de coordenadas X e Y. El primer par se refiere a la esquina superior izquierda y los demás al resto de las esquinas, en el sentido de las agujas del reloj. Dicho de otro modo:
    • Esquina superior izquierda.
    • Esquina superior derecha.
    • Esquina inferior derecha.
    • Esquina inferior izquierda.
  • Dibujado de triángulos. La función triangle() nos permite dibujar un triángulo, pasándole seis argumentos que corresponden a tres pares de coordenadas X e Y, un par para cada vértice. Tendrá el contorno definido con stroke() y el relleno definido con fill().
  • Dibujado de arcos. Esta es, en el apartado de primitivas 2D, la función más versatil y, por tanto la que más configuraciones de argumentos admite. Se trata de la función arc(), para dibujar arcos circulares. Debido a sus posibilidades la veremos en un apartado propio, dentro de este mismo artículo.

ALGUNOS EJEMPLOS BÁSICOS

Con lo que hemos visto en el apartado anterior ya somos capaces de interpretar perfectamente el código del primer ejemplo que vimos. Resumiendo, Resumiendo, establecemos un color de trazo rojo y dibujamos una línea. Después establecemos un color de trazo amarillo y relleno negro, y dibujamos un rectángulo. Ahora vamos a ver algunos ejemplos más elaborados.

El primer ejemplo se llama primitivas_1.pde, y su código es el siguiente:

primitivas_1El resultado lo vemos a la izquierda. Veamos lo que hemos hecho:

  • Establecemos las dimensiones del área de dibujo un poco más grandes que las que vienen por defecto.
  • Establecemos el color de fondo en negro.
  • Establecemos el color de trazo en rojo.
  • Trazamos una línea horizontal.
  • Establecemos el color de trazo en verde. Para el color de fondo ponemos un blanco con cierta transparencia.
  • Trazamos una elipse.

Los gráficos que se dibujan después quedan “por encima” de los que se dibujan antes, pero como la elipse tiene un cierto grado de transparencia, se ve la línea roja y el fondo a través de ella. Prueba a cambiar el cuarto parámetro de la instrucción fill() por 255 o, simplemente, eliminarlo, y verás que la elipse es totalmente opaca, tapando lo que tiene por debajo.

El siguiente ejemplo se llama primitivas_2.pde, y su listado es el siguiente:

primitivas_2

 Cómo ves, llevamos a cabo las siguientes acciones:

  • Establecemos el tamaño del lienzo.
  • Establecemos un color de fondo.
  • Establecemos un color de línea (blanca) y un tono azul de relleno.
  • Dibujamos un triángulo.
  • Cambiamos el color de relleno a un tono anaranjado. Cçomo no cambiamos el color de trazo, este seguirá siendo blanco.
  • Dibujamos un paralelepipedo irregular.
  • Cambiamos el tono de trazo a cyan.
  • Dibujamos cuatro puntos en ubicaciones próximas a la esquina inferior derecha.

LOS ARCOS

Cómo decíamos un poco más arriba, la función arc() nos permite crear arcos circulares con bastante flexibilidad. Los arcos de establecen sobre la base de una elipse. Vamos a empezar a verlo con un ejemplo simple, llamado arcos_1.pde.

arcos_1elipse_circular_completaComo ves, no hemos cambiado el tamaño de lienzo, ni los colores por defecto, para centrarnos en el trazado del arco en sí mismo. El resultado de este mini sketch lo estás viendo en la imagen de la izquierda. Cómo ves, la función arc() está recibiendo seis argumentos:

Los cuatro primeros definen la elipse de la que se va a obtener el arco. Si te fijas en la imagen del resultado, verás que el arco que aparece es parte de un círculo. Estamos indicando que se parte de una elipse cuyo centro está en las coordenadas X = 50 e Y = 50 (lo que, dado que el lienzo tiene 100 x 100 píxeles, hace que coincida el centro del círculo con el centro del lienzo). Los parámetros tercero y cuarto determinan, cómo sabemos, la anchura y altura de la elipse. Al ser iguales la elipse sería, realmente, un círculo. A la derecha vemos cómo sería la elipse circular si estuviera completa, para que te hagas la idea de que realmente, el arco es un fragmento de la misma.

Volviendo al arco, el quinto parámetro indica el ángulo en el que se empieza a dibujar dicho arco. Cómo ves es 0, lo que se refiere a la posición de las tres en la esfera de un reloj, es decir, el punto situado más a la derecha posible de la elipse. El arco se dibujará, a partir de ese punto, en el sentido de las agujas del reloj.

El sexto argumento es el ángulo que cubre el arco. Pero, ATENCIÓN, expresado en radianes, no en grados sexagesimales. Normalmente estamos acostumbrados a pensar en ángulos en términos de grados, pero existen muchas herramientas en Internet para convertir grados a radianes y viceversa. Incluso el propio Processing implementa funcionalidades en este sentido, cómo explicamos en el cuadro a continuación:

CONVERSIÓN DE ÁNGULOS. Dado que Processing trabaja mucho con radianes y nosotros estamos, en general, más acostumbrados a pensar en grados, los autores de Processing han tenido la generosidad de implementar dos funciones que nos permiten las conversiones necesarias:

Arco de 90º

Arco de 90º

  • Convertir grados a radianes. La función radians() recibe, cómo argumento, un ángulo en grados y nos devuelve el equivalente en radianes.
  • Convertir radianes a grados. La función degrees() recibe, cómo argumento, un ángulo expresado en radianes y nos devuelve el equivalente en grados.

Así pues, supongamos la siguiente instrucción:

arc (50, 50, 50, 50, 0, radians(90));

En ella vemos cómo podemos expresar el ángulo en grados, incluyendo la función radians() cómo un argumento de arc(). El resultado lo vemos a la izquierda de este texto.

Arco "normal"

Arco “normal”

Arco con OPEN

Arco con OPEN

La función arc() admite un séptimo argumento, que es opcional, para modificar el aspecto del arco. Observa la siguiente línea de código:

arc(50, 50, 70, 70, 0, 4);

Esta es la definición de un arco cómo ya la conocemos. Fíjate en que el punto de inicio está en 0 (como decíamos antes, las tres en la esfera del reloj, y el arco tiene 4 radianes de ángulo (aproximadamente, 230ª). El arco tiene el aspecto que vemos a la izquierda de estás líneas.

Ahora vamos a añadir, cómo séptimo argumento, una constante propia de Processing, llamada OPEN. La vamos a incluir en el código, sin comillas ni nada más, así;

arc(50, 50, 70, 70, 0, 4, OPEN);

El resultado lo vemos a la derecha de este texto, dónde podemos comparar con el anterior para ver la diferencia.

El séptimo argumento puede ser una de las siguientes constantes: OPEN, CHORD o PIE. A continuación vemos dos líneas de ejemplo y, debejo de ellas, las muestras de uso de CHORD y PIE, ya que OPEN ya la conocemos.

arc(50, 50, 70, 70, 0, 4, CHORD);
arc(50, 50, 70, 70, 0, 4, PIE);

Arco con CHORD

Arco con CHORD

arco_pie

Arco con PIE

 

 

 

 

 

 

 

 

En el próximo artículo continuaremos viendo prestaciones gráficas de Processing.

 

     

3 comentarios:

  1. Pingback: Primitivas 3D » eldesvandejose.com

  2. Pingback: El efecto Moiré » eldesvandejose.com

  3. Pingback: Los menús de Processing (V): Herramientas » eldesvandejose.com

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *