2.4. Sistema de coordenadas y primitivas

En Processing se trabaja mediante un sistema de coordenadas preestablecido que nos permite ubicar objetos de forma ordenada en una determinada ventana de dibujo. Además, se cuenta con una buena base de funciones de dibujo y color, las cuales se denominan primitivas. Las funciones primitivas de los lenguajes de programación son las que permiten realizar tareas básicas, en este caso dibujar elipses, triángulos, etcétera.

En muchos lenguajes de programación dibujar figuras en la pantalla del monitor puede volverse una tarea no trivial, debido a que se debe tener acceso a la placa de video de nuestra computadora, y luego poder dibujar en el monitor, sin tener en cuenta que el dibujo sea estático o dinámico (se quede quieto o se mueva).

En Processing estos problemas están resueltos y en la mayoría de los casos el usuario se preocupa por el diseño, construcción y ubicación de los objetos básicos. Con pocas líneas de código se pueden resolver problemas gráficos que, realizados con otros lenguajes de programación, pueden ser engorrosos.

2.4.1. Coordenadas y píxeles

Se puede entender el monitor de una computadora de forma básica si se (lo) piensa como una grilla o matriz de pequeños elementos que brillan, los cuales se denominan píxel. Los monitores pueden soportar diferentes formatos de esta grilla, que se denominan “resoluciones de pantalla”: 800x600 píxeles, 1024x768 píxeles, 1280x1024 píxeles, etcétera.

Estos valores definen la cantidad de píxeles con los que se puede trabajar en una pantalla y que justamente da una idea de la cantidad de puntos que se pueden colorear para generar una estructura de dibujo más compleja. Por lo tanto, se entiende al píxel como la unidad mínima de creación de imágenes.

Las imágenes digitales son dibujadas píxel por píxel. Mientras más cantidad de píxeles, y más pequeños sean, podemos dibujar más cosas y con mayor definición.

Las resoluciones también se pueden medir por cantidad de píxeles por pulgada, lo que da una idea de la resolución con que se puede crear una imagen.

Los programas en Processing pueden manejar un conjunto o todos los píxeles de la pantalla. Ya hemos indicado que cuando ejecutamos un Sketch, se abre una ventana adicional a nuestro IDE que tiene una cantidad de píxeles determinada, y en la cual podemos escribir y leer la información de cada píxel. Si no realizamos ninguna indicación en el código fuente, el tamaño por defecto de esta pantalla adicional es de 100x100 píxeles.

Actividad 3

Abrir Processing y apretar el botón de ejecución del IDE. Describir en no más de tres líneas qué es lo que sucede.

 

Una vez creada esta ventana adicional, se debe interpretar cómo se manejan las coordenadas de la misma, debido a que va a ser necesario indicarle a Processing dónde se requiere dibujar. Por lo tanto, se entiende a la ventana de dibujo como un sistema de coordenadas de dos dimensiones X e Y. X representa el plano horizontal e Y, el plano vertical. El origen de este sistema de coordenadas, el píxel ubicado en la posición X=0 y la posición Y=0, el cual representaremos como una dupla de números (0, 0), se encuentra en la esquina superior derecha. A partir de este origen, el valor de X crece hacia la derecha y el valor de Y crece hacia abajo. En la imagen siguiente podemos observar una representación gráfica de este sistema de coordenadas.

Sistema de coordenadas utilizado por processing


 

A partir de esta forma de trabajo, se pueden crear imágenes/animaciones amplias o que solo ocupen un sector de la pantalla.

Configurar esta ventana donde vamos a trabajar es muy importante. Pensándolo desde el punto de vista de un artista plástico, siempre antes de comenzar a dibujar/pintar, este necesitará una superficie donde hacerlo. En Processing se pueden establecer las dimensiones de esta superficie y también la calidad de esta superficie, y hasta colores de fondo.

De forma análoga, cuando se quiere dibujar en la pantalla, las primeras opciones que se deben configurar son cuánto de esa pantalla se utilizará, el color de fondo que se utilizará, y la calidad de render que va a tener el dibujo.

A continuación, se estudiarán cuáles son las funciones que establecen estas características a partir del código fuente que se escribe.

2.4.2. Tamaño, fondo y render

A continuación, se revisarán dos funciones básicas de configuración en Processing: size y background. La función size permite establecer las dimensiones de la ventana de dibujo y background permite establecer un color o una imagen de fondo de esta ventana.

Veamos con un ejemplo la sintaxis de dichas funciones.

//Tamaño de la ventana
size(200, 200);
//Color de fondo de la ventana
background(255);

 

Lo que aparece en el ejemplo ya es código Processing. De hecho si se escribe las líneas del ejemplo en la ventana de código fuente, en el IDE de Processing, veremos cómo la ventana cambia de tamaño y de color de fondo al ejecutar el Sketch.

Cuando se crea un programa en Processing y se lo guarda, el mismo programa genera una carpeta que contiene el archivo de código fuente, con extensión .pde. Esto se hace para mantener un orden establecido para cada creación. Los recursos de imagen y fuentes que se utilicen pueden estar en la misma raíz de esta carpeta o en una subcarpeta que se denomina Data.

 

Analizando este código, en la primera línea se observa una anotación realizada luego de una doble barra (//). Esta es la forma en la que se realizan comentarios dentro del lenguaje Processing. Los comentarios son muy útiles para ordenar el programa y, además, permiten que el que escribe pueda dejar asentado las funcionalidades del código. Cuando se ejecuta el código fuente, Processing no interpretará las líneas que empiecen con esta doble barra.

Otro rasgo inicial que se observa es que ambas funciones terminan con punto y coma (;). Esto es fundamental en Processing, ya que todas las líneas de código que ejecutan alguna función, deben terminar con este símbolo. De esta manera, Processing puede interpretar que terminó una línea y se prepara para entender la siguiente.

Revisar la sintaxis de las funciones que se utilizaron en este primer ejemplo nos permite entender cómo funcionan. Empecemos con size:

size(200,200);

size acepta dos argumentos que son pasados mediante dos números separados por coma y dentro de paréntesis. Los argumentos que se pasan a la función size son las dimensiones de la ventana en píxeles, en este caso particular se configura una ventana de 200 píxeles de ancho y 200 píxeles de alto.

En el caso de la función background, el argumento que acepta es el de color. Este color puede ser pasado en escala de grises, que se indica con números desde 0 (negro) a 255 (blanco), o en código RGB. En este caso, se pasan tres argumentos indicando qué cantidad de cada color queremos asignar. La sintaxis en este caso sería:

background(255, 0, 0);


Estos tres colores también se indican con números desde 0 a 255. En el ejemplo, se estaría coloreando el fondo con color rojo.

Tanto size como background poseen argumentos complementarios que extienden su funcionalidad. En el caso de size se puede agregar un tercer parámetro que se denomina MODE. Este tercer parámetro permite elegir el motor de render que queremos utilizar. Cada motor de render tiene especificaciones que se adecuan mejor a determinadas finalidades.

Por defecto, size utiliza el motor de renderizado JAVA2D, que soporta dibujos en 2 dimensiones y provee imágenes de alta definición, aunque presenta una velocidad de render más baja que otros motores de render.

El modo P2D (Processing 2D) permite un renderizado rápido, pero que a veces no es tan efectivo como JAVA2D.

P3D (Processing 3D) es el renderizador en 3 dimensiones para Processing y es muy rápido para aplicaciones web. Lo malo (o bueno) es que sacrifica calidad de render por velocidad de procesado 3D.

OPENGL, basado en la librería de gráficos de software libre openGL, provee un motor muy rápido de render en 3 dimensiones, y es compatible con muchos hardware disponibles. Lo interesante de utilizar OPENGL es que automáticamente se produce un suavizado muy bueno que mejora la calidad de las imágenes.

Para usar este motor de render es necesario incluir en el código la librería opengl. Esto se hace incorporando la siguiente línea en el código fuente:

import processing.opengl.*;

El añadido de librerías en Processing se hace de forma muy sencilla. En el Propio IDE recorremos la siguiente ruta: pestaña Sketch>Import Library, y allí se elige qué librería se desea añadir a nuestro código.

 

Siguiendo con los diferentes MODES, el modo PDF permite exportar las imágenes que se generan en la ventana de dibujo, pero hacia un archivo pdf, lo que resulta útil si se desea gráficos de gran calidad vectoriales. Para esto se necesita agregar la librería pdf export (igual que openGL), añadiendo el archivo (y su ruta de ser necesario) en el cual queremos guardar el resultado de la ejecución del Sketch:

size(200,200, PDF, ‘archivo.pdf’);

Para background existe la opción de poder tener una imagen de fondo. Para esto se necesitan algunas líneas de código extras, las cuales indicaremos a continuación por una cuestión meramente explicativa, pero que se desarrollarán más profundamente en apartados posteriores. Veamos otro ejemplo con estas características.

//Se crea un objeto Pimage, el cual contendrá a la imagen
Pimage b;
//Se carga el archivo de imagen en el objeto Pimage
b = loadimage(“Imagen.jpg”);
//Se pasa el objeto Pimage a backaground
background(b);

 

Al utilizar una imagen como imagen de fondo de la ventana, se debe tener cuidado que el tamaño en píxeles de esa imagen sea el mismo que la ventana de dibujo. Se debe tener en cuenta que la imagen a utilizar esté guardada en la subcarpeta Data dentro de la carpeta del sketch. Los formatos de imagen que pueden ser utilizados en Processing son: .gif, .jpg, .tga y .png.

 

Actividad 4

Como se vio en los ejemplos de este apartado, en el lenguaje Processing se puede trabajar con diferentes motores de render, configuraciones de tamaño y fondo. La consigna de esta actividad implica crear cuatro programas diferentes; los cuales deben utilizar diferentes combinaciones de motor de render, tamaño de ventana y color de fondo. Cada programa debe ser escrito y guardado en un sketch diferente y entregado al docente.

Ejecutar Processing y generar programas que utilicen los diferentes motores de render que usamos y diferentes configuraciones de tamaño y fondo. Cada programa debe ser guardado, comentado y entregado al docente.

 

2.4.3. Formas primitivas

Dentro de Processing se puede dibujar, y para esto se utilizan las formas primitivas. Las formas primitivas no son ni más ni menos que elementos básicos (muy básicos) con los que se puede construir casi cualquier cosa dentro de los programas. La forma primitiva más básica dentro de Processing es el punto. Para dibujar un punto se utiliza la función point, con la siguiente sintaxis:

point(x, y);


Donde el primer parámetro es la coordenada x y el segundo parámetro es la coordenada y dentro del lienzo de dibujo.

Por supuesto, si se dibujan varios puntos, uno detrás del otro, se puede generar una línea. Si se tuviera que dibujar todo de esta manera sería muy costoso temporalmente. Por esto, existe otra primitiva que dibuja líneas y lo hace mediante la función line:

line(x1, y1, x2, y2);


En este caso se pasan dos coordenadas, que no son ni más ni menos que los dos puntos que unirán la línea. Como sabemos, mediante líneas se pueden crear múltiples figuras geométricas, pero, nuevamente, esto puede tornarse trabajoso. Por lo tanto, Processing plantea el uso de otras formas primitivas menos básicas, las que pueden dibujar triángulos, polígonos de cuatro lados, rectángulos y elipses. Para estas cuatro figuras se utilizan cuatro funciones diferentes:

triangle(x1, y1, x2, y2, x3, y3);

Los argumentos que recibe son los tres puntos que conforman el triángulo.

quad(x1, y1, x2, y2, x3, y3, x4, y4,);

Los argumentos que recibe son los cuatro puntos que conforman un polígono de cuatro lados.

rect(x, y, ancho, alto);

En este caso, recibe como argumentos la posición xy del rectángulo, y luego el ancho y alto que tendrá el mismo. Mediante esta función es simple dibujar un cuadrado.

ellipse(x, y, ancho, alto);


Los argumentos que recibe son los mismos que el rectángulo, pero se generan, obviamente, elipses. Esta primitiva es ideal para dibujar círculos y óvalos.

Una función primitiva especial que contiene Processing es la que se denomina Bezier, mediante la cual se pueden dibujar líneas no rectas.

Esta función proviene de las denominadas curvas de Bezier, las cuales son un sistema utilizado en el dibujo técnico. No es más ni menos que la forma de unir dos puntos mediante una curva. La forma de esta curva se define mediante la utilización de dos puntos invisibles en el dibujo, denominados puntos de control, manejadores o manecillas. Es una función que aparece en los principales programas de dibujo digital.

En la siguiente imagen puede observarse una representación de una curva Bezier con dos puntos de anclaje (P0 y P3) y dos puntos de control (P2 y P3). Este tipo de curvas Bezier son las que están disponibles en Processing.

Curva Bezier con dos puntos de anclaje y dos puntos de control


 

La sintaxis de la función bezier en Processing es la siguiente:

bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2);


La función recibe dos puntos de anclaje (x1, y1, x2, y2) y dos puntos de control que definen la forma de la curva (cx1,cy1, cx2, cy2). En el lienzo solo se verá la curva final.

Cuando se dibuja o pinta sobre un lienzo, se debe poner atención en qué figura queda por encima de la otra. En Processing esto se resuelve directamente mediante el flujo que lleva el programa. Esto significa que si se ordena a Processing que dibuje primero un círculo y luego, en el mismo lugar, un cuadrado, este último tapará al primero. Si revertimos este orden establecido, el círculo tapará al cuadrado. En resumen, la última figura creada estará por encima de las anteriores.

 

Actividad 5

Generar un tapiz de 200 x 200 píxeles mediante la utilización de las figuras primitivas. Deben utilizarse todas las funciones que estudiamos hasta ahora, y toda la superficie del lienzo debe ser dibujada.