4.6 Primitivas De ibujo (Linea, Arco, Circulo, Colores, Rellenos, Imágenes)

Se trata de un proceso muy simple, pero que nos permite vislumbrar el enorme mundo de posibilidades gráficas que este entorno nos ofrece. Por supuesto, el verdadero poder de Processing viene de la mano de su conectividad con Arduino, pero a eso ya llegaremos.

EMPEZANDO EN 3D
Lo primero, al igual que hacíamos en el artículo anterior, es inicializar el escenario, estableciendo las dimensiones del lienzo con la instrucción size. Sin embargo, en esta ocasión debemos agregar un tercer parámetro, una constante de Processing llamada P3D, que le indica al sketch que vamos a trabajar con objetos 3D. Si no establecemos esta constante, no podremos dibujar en 3D. Así pues, inicializaremos este primer sketch así:


size (200, 200, P3D);



El siguiente paso, cómo no, es establecer, un color de fondo, un color de línea y un color de relleno. Esto es igual que lo que aprendimos con las primitivas 2D, por lo que reproducimos directamente las tres líneas, sin entrar en mas detalles.

background(255);

stroke(0);

fill(255, 150, 100);



Ahora sí, vamos a empezar a dibujar. En este ejemplo dibujaremos una caja en 3D, vista en perspectiva, con los colores que hemos establecido. El siguiente paso es establecer el punto central de la caja que vamos a dibujar. Este punto se establece, inicialmente, con respecto a las coordenadas 0, 0, es decir, la esquina superior izquierda del lienzo. Lo haremos mediante la instrucción translate(), así:

translate(100, 100, -50);

Tu punto de vista, desde el eje Z.

Esta instrucción nos introduce algunos conceptos importantes. En primer lugar, los dos primeros argumentos indican los píxeles que nos desplazamos desde el punto de origen (en este caso la esquina superior izquierda) para establecer el centro de la figura que vamos a dibujar. Cómo el lienzo tiene, en nuestro ejemplo, 200 x 200 píxeles, el centro de la figura coincidirá con el centro del lienzo.

Lo del tercer parámetro tiene más enjundia. A partir de aquí tienes que empezar a pensar en tres dimensiones. Tu ya no estás viendo un lienzo de dibujo. Estás viendo un plano en el espacio, y lo estás viendo “desde arriba”, desde el eje Z. El tercer parámetro te dice en que posición quedará el objeto con respecto a tu punto de observación. Cuanto más pequeño sea este valor, más lejos de tí quedará el objeto, y más cerca del plano o, por expresarlo del mejor modo posible, del fondo de la pantalla. Por lo tanto, cuanto más reduzcas este valor, más pequeño verás el objeto final. El gráfico de tu izquierda revela tu posición de observador viendo, desde arriba el plano X-Y.

Si ahora dibujásemos una caja, no la veríamos en perspectiva, si no que sólo veríamos la cara superior. Por esta razón, nos parecería estar viendo sólo un cuadrado (o un rectángulo; en todo caso, un objeto 2D, no 3D). Antes de dibujar la caja, vamos a imponer alguna rotación, para tener una vista en perspectiva. Las rotaciones pueden establecerse en uno, dos o los tres ejes, mediante las instrucciones rotateX(), rotateY() y rotateZ(). Estas tres actúan rotando el objeto, cdad uno sobre su eje. Para ello, reciben un argumento que es el ángulo de rotación, expresado en radianes. Si te acuerdas, en el artículo anterior hablamos de los ángulos en grados y radianes. Todo lo que dijimos al respecto entonces es válido aquí también. Vamos a darle a nuestra caja un poco de giro en los ejes X e Y, de momento.

rotateY(0.8);
rotateX(0.8);


Y, por fin, vamos a dibujar la caja. Para ello recurrimos a la instrucción box(). Esta recibe, normalmente, tres parámetros, que indican la anchura (eje X), altura (eje Y) y profundidad (eje Z) de la caja, en píxeles. Alternativamente (y es lo que haremos aquí), se puede poner un sólo valor. En ese caso, este valor será para las tres dimensiones, y la caja será completamente cuadrada:

box (100);


primera_caja

Y ya está. Ejecuta tu sketch de Processing y verás una caja en perspectiva, similar a la de la derecha de este texto.

Antes de seguir adelante, experimenta un poco. Cambia algunos valores, y observa el resultado al ejecutar de nuevo. De esta forma, te familiarizarás un poco con el punto de vista 3D. A continuación, te dejo este sketch completo para que lo copies y pegues en tu IDE Processing.

size(200, 200, P3D);
background(255);
stroke(0);
fill(255, 150, 100);
translate(100, 100, -50); 
rotateY(0.8);
rotateX(0.8);
box(100);

ATENCIÓN. La función translate (), que hemos usado para posicionar el centro del objeto que vamos a dibujar usa valores relativo, no absolutos. Eso quiere decir que si en el mismo sketch vamos a dibujar otro objeto 3d y usamos, por ejemplo, translate (10, 10, 0);, el centro se desplazará 10 píxeles hacia la derecha y hacia abajo del centro del último objeto dibujado, manteniendo la misma distancia en el eje Z, dónde hemos puesto 0. Sólo se toman valores absolutos la primera vez que se usa esta función en el sketch (en realidad, no son absolutos, sino relativos a 0, 0, 0 lo que, en la práctica, es lo mismo, claro).7

ACERCA DE LA MALLA

Hemos aprendido a ocultar la malla, para que no sea visible una superficie triangulada, que “hace feo”. Sin embargo, aunque no la veamos, la malla sigue estando ahí. El objeto se rende rizará siempre a partir de una malla de triángulos, tanto si la vemos cómo si no.

La densidad de esta triangulación determinará la resolución del objeto final. A mayor número de triángulos, tendremos una malla más densa y, por tanto, una esfera más definida. Cómo contrapartida, si aumentamos mucho el número de triángulos, serán necesarios más cálculos por parte de Processing para renderizar la esfera, lo que puede ralentizar el funcionamiento. Lo ideal es buscar una solución de compromiso, de modo que

obtengamos un resultado aceptable a la vista, pero sin sobrecargar el equipo. La renderización 3D consume muchos recursos y, aunque la mayoría de cosas que hagamos con Processing, podremos llevarlas a cabo en un PC “normalito”, si alguna vez nos metemos en “palabras mayores” quizá necesitemos más memoria, mejor tarjeta gráfica… Bueno, los jugones empedernidos saben de que va el tema. De momento, no debemos preocuparnos.

Para establecer la densidad de la malla contamos con la función sphereDetail(). Esta recibe un argumento, que indica el número de triángulos que se usan para renderizar los 360º de una esfera. El valor por defecto (que nos sirve en la mayoría de las ocasiones) es de 30. Tambiién podemos invocar a esta función con dos argumentos. En ese caso, el primero establece la resolución en horizontal, y el segundo en vertical. Para entender cómo puede haber una dicotomía en la resolución, observa el sketch distintas_resoluciones.pde, listado a continuación, y que nos da un resultado cómo el que vemos a la derecha de estas líneas.


size (200, 200, P3D);
stroke(0);
fill(50, 120, 180);
lights();
translate(100, 100, -50);
sphereDetail(4, 40);
sphere(90);

No hay comentarios:

Publicar un comentario