Apuntes mientras aprendo sobre software y computadoras.

Processing

Processing: guía práctica básica

Esta es mi guía más o menos básica para empezar a programar con el lenguaje Processing.

Del mismo modo que las otras guías que hice hasta el momento, se trata de un texto escrito por un principiante. Estoy escribiendo para aprender.

Dicen que la mejor manera de aprender algo es primero practicarlo y luego explicarlo. Y eso es lo que intento hacer.

Siendo esto así, hago todo lo posible para transmitir mi experiencia con el tema en la mejor manera que puedo. Cualquier error que encuentres en el material, no olvides comunicármelo para que pueda rectificarlo. Todos tus consejos ayudan a mejorar esta guía.

¿Qué es Processing?

Processing es un lenguaje de programación especialmente dedicado al arte. Aunque también se usa para otros proyectos.

Estamos a punto de instalar el entorno que va a permitirnos desarrollar ideas en este lenguaje. Esto se conoce por PDE (Processing Development Enviroment) o “entorno para el desarrollo de Processing”.

A modo de bonus extra, Processing es de código abierto.

Cómo instalar Processing en Linux

Este es el link al sitio oficial para descargar el software.

En este caso en particular estoy buscando la versión de Linux, así que presiono el botón de download y descargo el archivo .tar.gz que contiene todo lo que necesito.

Existen varias versiones del programa. Hasta el momento de escribir esto existen las versiones: 2.0, 3.0 y 4.0 con todas sus variantes intermedias.

Entonces descargo la última edición estable, solo por seguridad. Pero es bueno saber que si necesito por algún motivo especifico una versión más antigua, siempre puedo conseguirla.

Una vez descargado, muevo este archivo a una nueva carpeta.

Voy a crear entonces una carpeta dedicada para almacenar toda esta nueva información en mi computadora. Esta nueva carpeta puede estar dentro de Home ( la Carpeta Personal) por ejemplo, o en cualquier lugar que consideres más apropiado.

No es necesario desempaquetar el contenido de la descarga, realmente no hay que lidiar con ningún software de instalación.

Lo siguiente es abrir la nueva carpeta en la terminal de Linux.

Para esto puedo buscar el directorio especifico desde la consola, o puedo hacer click derecho en la carpeta y elegir “Open in terminal” (abrir en la terminal).

Luego escribo:

tar xvfz processing-xxxx-linux64.tgz

Y cuido de reemplazar el “xxxx” en el comando por el número de versión de processing que descargué en el equipo.

La parte de “linux64” del comando se refiere a que estoy usando una versión para un sistema operativo de 64 bits. Esta parte también puede cambiar dependiendo de la versión que bajaste.

Dicho esto, por ejemplo, en mi caso el comando queda:

tar xvfz processing-4.0b1-linux64.tgz

Eso va a extraer una nueva carpeta dentro del nuevo directorio.

Si ingreso a ese nuevo carpeta voy a encontrar un archivo llamado “processing”. Si lo ejecuto, se va a abrir el entorno de desarrollo. Y eso es todo, ya puedo empezar a escribir código dentro del mismo entorno de Processing.

También puedo abrir esa nueva carpeta en la terminal, y luego escribir:

./processing

Y el entorno de Processing otra vez va a ejecutarse.

Listo, eso termina la instalación. Se podría decir que ya no nos queda nada por hacer, pero todavía nos queda responder…

Cómo agregar un acceso directo para Processing en el escritorio

Lo más seguro es que nos interese agregar en nuestro escritorio un acceso directo al programa, para poder encontrarlo rápidamente sin tener que pasar por el paso previo de buscar la carpeta correcta.

Para conseguir esto, lo que tengo que hacer es:

Ir al escritorio y hacer click en el mismo con el botón derecho. Luego seleccionar Create a New Launcher Here.

Me va a aparecer una nueva ventana.

Esa ventana me pide que le de un nombre al acceso directo. Lo hago, y luego presiono explorar. La idea es ir hasta la carpeta de Processing, para linkear este nuevo “lanzador” con el archivo llamado processing que vimos antes.

También puedo darle una imagen a este ícono, si exploro la carpeta de Processing voy a encontrar una librería (por lo general ubicada en lib > icons) con algunos posible gráficos para utilizar.

Y listo, si todo salio bien voy a tener el acceso directo creado en el escritorio.

No solo eso, al llevar a cabo esta acción también se nos va a preguntar si nos gustaría agregar el acceso directo en el menú. Si elegimos que si, ahora también vamos a tener en la categoría de “otros programas” este acceso directo listo para llevarlo a otra categoría.

Con todo eso ya tengo el entorno de Processing en mi equipo, puedo ya entonces empezar a utilizarlo.

¿Qué es un sketch en Processing?

En Processing un sketch es el nombre básico que se le asigna al proyecto que vas a programar.

Este sketch puede conectar en su interior múltiples tipos de archivos, por ejemplo imágenes o sonidos externos.

Empezar a programar con Processing

Los programas creados en Processing se conocen como un sketch.

Si la misma palabra que en el mundo del arte define por ejemplo a un dibujo rápido de una idea.

Siendo que Processing esta muy orientado a la creación de arte e imágenes, podemos decir que la idea de sketch funciona bien para describir estos programas.

La carpeta donde se guardan estos programas se llama sketchbook (libro de sketches o “carpeta de sketches”)

Pero no necesitamos obligatoriamente tener el entorno de Processing para correr un sketch. El lenguaje permite crear aplicaciones especificas que pueden usarse “por separado”, para que puedan ejecutarse en distintas computadores o navegadores.

Cómo crear un nuevo sketch en Processing

Hacer click en el botón “new” (nuevo) va a generar un nuevo sketch, luego podemos ponerle nombre al guardarlo (por ejemplo con “save as”).

Nada de esto es diferente a, por ejemplo, crear un nuevo documento en un procesador de texto como Word o LibreOffice Writer.

Cuando usamos Processing por primera vez, por defecto se crea un directorio donde los sketches van a comenzar a guardarse. Sin embargo siempre tenemos la opción de guardarlos en otra carpeta, si eso nos parece más conveniente.

Cada sketch esta compuesto por una carpeta que lleva el nombre que usamos al crear el programa. Dentro de la carpeta vamos a encontrar un archivo con “.pde” por extensión.

El archivo .pde es un texto sin formato que contiene las lineas de código del programa que estamos creando.

También se puede guardar otro tipo de archivos, por ejemplo con la extensión .java.

A la vez esta carpeta puede contener otra en su interior, llamada “data”. Estos son datos externos (imágenes y audios, por ejemplo), elementos con los que puede interactuar el programa.

Vamos a crear un sketch

Ya tenemos Processing abierto. Escribamos en su interior el siguiente código y dejemos que la magia del arte comience a comunicarse con nuestras pantallas.

void setup()
{
size(750,500);
}

¿Qué significa este código?

Un sketch tiene varias funciones, todas unidas por una sintaxis específica.

En este ejemplo tenemos una única función: setup() y size()

Una función es un set de instrucciones, con un nombre específico, que lleva adelante un trabajo.

Hay distintos tipos de funciones. Las funciones que hoy nos ocupan son parte estructural del lenguaje Processing.

Pero también podemos crear funciones nuevas, según cual sea el objetivo que estamos buscando conseguir.

Por decirlo de algún modo, la función setup() organiza el contenido del sketch. Podemos ver esto más claramente si tenemos en cuenta que la palabra setup quiere decir organización o disposición.

Dentro de void setup(), que podemos pensar como una “función principal”, podemos poner otra funciones que van a ejecutarse una única vez, en orden secuencial.

Si nos fijamos bien, luego de la función hay dos corchetes. Todo lo que entra entre esos corchetes se conoce como bloque. Ahí vamos a encontrar todos los comandos, que son parte de la función setup().

void setup()
{
size(700,500);
}

Esta función es muy importante, porque necesitamos usarla para cada sketch que hagamos.

En este caso tenemos el comando size() y en su interior tenemos el tamaño que vamos a darle a la ventana que va a usar el proyecto. Visto desde ese punto de vista, tenemos que:

size(700,500);

Quiere decir que la ventana va a tener 750 pixeles de ancho y 500 pixeles de alto.

También podemos notar que la función size termina como un “punto y coma”.

Cada función termina un (;). De este modo el sketch sabe cuando termina una función y comienza otra. Recordemos que entre los corchetes podemos poner varias funciones diferentes.

La sintaxis de los sketches tiene otras cosas a tener en cuenta. Algunas de estas cuestiones son solamente de forma, ayudan a crear un código más fácil de leer a simple vista.

No hay que preocuparse mucho por esto último. Tenemos la opción de darle “auto formato” al código, para que todo quede hermosamente presentado. El atajo para esto es presionar el combo Ctrl + T en el teclado.

Por otra parte, otros errores de la sintaxis pueden generar un error y que el programa no se ejecute.

Aunque vamos a ver más a cerca de estos errores en el futuro, tengamos en cuenta que Processing nos va a dar una idea general sobre donde se encuentra el posible error.

Por ejemplo, si olvidamos un (;) nos lo va a avisar para que podamos subsanarlo.

Pero para cerrar este apunte, volvamos a nuestro código. Si escribimos:

void setup()
{
size(500,700);
}

Ahora presionamos Run (el botón de “Play en la esquina superior izquierda de la pantalla) o el combo de teclas Ctrl + R en teclado.

Lo que va a ocurrir es que el código va a ejecutarse, y una nueva ventana va a abrirse. Esta nueva ventana es la que invocamos con size(). Se trata del espacio que nuestro futuro sketch va a utilizar para mostrarnos lo que vamos haciendo.

Escribir comentarios en Processing

Tenemos ahora el siguiente código en nuestro entorno de Processing:

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

Y como ya suponemos, al ejecutar este sketch, el resultado es la creación de una nueva ventana. Las dimensiones de la ventana van a ser de 500 Pixeles de ancho y de alto.

Ahora digamos que quiero aclarar lo que hace el programa, junto a otros detalles, sin tener que ejecutarlo primero. Para eso puedo escribir un comentario dentro del código.

Los comentarios que haga no van a a ejecutarse, y por lo tanto no van a interferir con el funcionamiento del sketch.

Para escribir un comentario, hago uso de dos barras consecutivas // (en inglés forward flashes).

Por ejemplo, si quiero agregar la fecha de creación del programa, puedo hacer:

// Modificado el 26/09/21

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

Todo lo que se encuentra en la misma linea que las dos barras // forma parte del comentario.

Pero ahora digamos que queremos varias lineas de comentario, sin tener que agregar nuevamente las dos barras al comienzo de cada renglón.

Para hacer un comentario de múltiples linea hacemos uso de una barra y un asterisco al comienzo del texto /* y luego cerramos con un asterisco y una barra */ para terminar.

Agregando un comentario de múltiples lineas en el código anterior, puede quedarnos así:

/* Modificado el 26/09/21.
Este programa crea una ventana de 500 pixeles de ancho y 500 de alto.*/

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

Pero recordemos que es importante cerrar el comentario de múltiples lineas, o el código va a dar error. Dicho de otro modo, va a parecer que todo el programa es parte de un comentario aun no terminado.

Realmente vamos a notar que lo que se considera “comentario” dentro del programa aparece con una tipografía ligeramente diferente en su tono, para facilitar la distinción entre partes a simple vista.

Otra cosa que vale la pena recordar. Podemos utilizar los comentarios para “ocultar” partes del código, consiguiendo así que estas partes no se ejecuten.

Ejemplo, digamos que queremos ver si una linea de código interfiere en el funcionamiento del programa. Podríamos borrar esa linea, pero eso luego puede confundirnos. En cambio, podemos marcarla como un comentario y efectivamente dejarla fuera del programa, sin necesidad de borrarla por el momento.

Processing, entender la ventana en pixels

Voy a tratar de pensar «geográficamente» el display del sketch, para luego poder usar las dimensiones de la ventana a mi favor para la creación de imágenes.

Pero antes, un ejemplo.

Digamos que tengo que hacer una animación, un video de tres segundos de duración.

La animación se trata de un fondo blanco, con un pequeño circulo azul por delante. El circulo se mueve desde el costado izquierdo del cuadro hacia el derecho. Todo esto en un dibujo (o mejor dicho, un plano) de dos dimensiones.

El circulo puede ir hacia arriba o hacia abajo; moverse hacia la izquierda o hacia la derecha de la pantalla.

Entre la primera y la última posición del circulo hay varios cuadros de animación. Voy a suponer tres posiciones, una por segundo. Cada una de esas posiciones forman cuadros (frames) individuales.

En cada uno de los tres segundos, en cada cuadro, la figura tiene una posición distinta en el espacio.

Sin embargo ¿Cómo se trasladada esto al mundo del código? ¿Cómo se divide el espacio de la pantalla? ¿En que forma puedo trasladar conceptos del tipo “arriba o abajo” dentro de un script?

Al programar no tengo una forma gráfica para «arrastrar» cada elemento por el cuadro. No puedo usar, al menos en principio, el ratón para crear las posiciones de cada frame. Tampoco hay linea de tiempo para ayudarme.

La respuesta: tengo que pensar pantalla de Processing como en una grilla de pixeles en la que puedo ubicarme por coordenadas.

Tengo que ver el espacio de mi proyectocomo una grilla donde el punto de origen (0,0) se encuentra siempre en la esquina superior izquierda.

Todo esto puede sonar algo confuso… y mi explicación no puede estar ayudando mucho. Pata entenderlo más, voy a intentar expandir la idea con el ejemplo que sigue.

Crear una ventana en Processing

Antes escribí un pequeño programa básico. El código había quedado así:

void setup()
{
size(500,700);
}

La función size() tiene dos parámetros.

Con el primero de esos parámetros se define el ancho de la ventana ( expresado en la letra x), y con el segundo la altura (expresado en la letra y). Puedo pensar la función como size(x,y).

Por ejemplo, al ejecutar dentro del código:

size(500,700);

Me encuentro con una nueva ventana. Puedo llamarla ventana de display (display window) y es el espacio donde se va a cristalizar el resto de mi código.

Digamos que quiero dibujar una linea, esa linea va a aparecer representada en la display window.

En este caso, en una ventana de 500 de ancho por 700 de alto.

Pero falta que me haga la pregunta ¿500 y 700 de qué? ¿En que unidad se mide el ancho y el alto de la ventana? La respuesta en este caso es: píxeles.

Por ejemplo, puedo decir que el tamaño de una hoja A4 es de 21 centímetros de ancho y 29,7 centímetros de alto. Pero ahora en la pantalla tengo una ventana de display, no una hoja. Y el tamaño del display que hice tiene 500 píxeles de ancho y 700 pixeles de alto.

Una ventana medida en pixeles

El pixel es la unidad más pequeña de la imagen digital. Sin ir más lejos, si pudiera ver el monitor desde muy muy cerca, podría ver al pixel como un único punto de color individual.

En inglés la palabra pixel viene de “picture element” o “elemento de imagen”.

El monitor no es más que un conjunto de pixeles que se iluminan según la imagen lo requiere. Por eso cuando se dice que un “pixel muere” se hace referencia a un punto específico en la pantalla que ya no se ilumina o que ya no se enciende correctamente.

En ese caso se puede diferenciar ese pixel individual porque es uno que no esta funcionando dentro de una grilla más grande.

Sin dudarlo escuchamos mucho sobre pixels, en especial cuando hablamos de fotos, televisores o monitores. Todas esas cosas vienen en distintos tamaños y resoluciones.

Por ejemplo, la medida de una pantalla de computadora puede ser de 1680 pixeles de ancho y 1050 de altura. La cantidad de pixeles la sabemos porque:

1680 x 1050 = 1.764.000

1.764.000 es la cantidad de pixeles individuales en ese rectángulo. Si fuéramos saltando por cada uno de arriba hacia abajo, de izquierda a derecha y de arriba hacia abajo, podríamos ubicar cada caso con su coordenada específica.

Del mismo modo, la distancia y la posición de la ventana del sketch esta dada en pixels. Y cada uno de esos pixels nos muestra una ubicación especifica con su propia coordenada.

Pixels y coordenadas en la ventana de Processing

Esta coordenada es valida para cualquier dimensión. Incluso la dimensión de “profundidad”, si fueran tres dimensiones. Pero este caso que nos ocupa hoy es más sencillo, estamos trabajando solamente en dos dimensiones y dos parámetros en lugar de tres.

La ventana de display en cierta forma es parecida al Plano Cartesiano. Hay coordenadas, hay un eje X e Y, del mismo modo que vimos en los parámetros anteriores. Pero a diferencia del Plano Cartesiano, la ventana de Processing no se encuentra divida en cuadrantes.

Por ejemplo, en el Plano Cartesiano tenemos X y -X, para representar un lado positivo y otro negativo de plano. El punto (0,0) de origen esta en el centro.

En el caso de Processing, el punto de origen (0,0) se encuentra en la esquina superior izquierda de la ventana. Entonces el eje Y aumenta de valor a medida que descendemos por el eje de X.

Entonces cada cada pixel corresponde a una coordenada del plano. Una coordenada X y otra Y.

Mientras nos movemos hacia la derecha, el valor de X se agranda, se hace “más ancho”. Y si nos paramos en un pixel más bajo, el valor de Y se agranda, se vuelve “más alto”.

La clave en esto es darse cuenta que la pantalla en processing no es más que una grilla, en la que podemos movernos por sus coordenadas.

El resto es simplemente ubicar lo que queremos en la pantalla, moviéndonos por medio de esa mismas coordenadas.

Dibujar un punto en una coordenada

Para entender mejor todo esto, vamos a dibujar un punto en el plano. Y lo hacemos con la función:

point(x, y);

Esta función también tiene dos parámetros, para definir la posición. La coordenada X (en el ancho, la horizontal del plano) y la coordenada Y (en el alto, en la vertical del plano).

Por ejemplo, para dibujar un punto ubicado en la coordenada X (10) y la Y (20) escribimos

point(10,20);

Después de todo esto ya nos damos cuenta que X nos indica la posición en la horizontal, e Y en la vertical. De ese modo, viendo de nuevo el código completo, al decir:

 void setup()
{
size(500,700);
point(50,40);
point(100,50);
point(150,70);
}

Nos dibuja tres puntos, en tres pares de coordenadas diferentes, cada uno representando a un pixel distinto en la parte superior izquierda del display.

Los puntos son diminutos, pequeños como pixels, pero si nos fijamos bien vamos a encontrarlos ahí.

Por otra parte, para terminar, vamos a dibujar una linea.

Dibujar una linea en Processing

Para dibujar una linea tenemos:

line(x1, y1, x2, y2);

Lo que estamos haciendo es darle a Processing dos coordenadas por medio de los parámetros. Estas coordenadas son la del “principio de la linea” con el par (x1, y1) y el “cierre de la linea” con el par (x2, y2).

Como ejemplo:

 void setup()
{
size(500,700);
line(10, 10, 200, 350);
}

La linea cruza hasta el centro del display.

En resumen: estoy ubicando mi dibujo en un tipo de grilla con un eje X y otro eje Y.

Lo más común es mirar la pantalla y decir “voy a ubicar este punto/imagen para que se vea en la parte superior izquierda del plano”. Pero al mismo tiempo casi nunca pienso ,o al menos no hasta hoy, “voy a ubicar este punto/imagen para que se vea entre las coordenadas/pixel (0,100) y (20, 140)”.

Pero ahora, al programar, veo que por fuerza necesito pensar en pixels. Antes había pixeles, pero no les prestaba atención. Ahora tengo que medir todo en estos diminutos puntos digitales.

(La guía aun no esta terminada, voy completandola poco a poco)

Dejar una respuesta