El grabado y la espiral

Hay obras de arte que en el momento que las ves, te enamoras. No es lo que me pasó con la obra que inicia este artículo:

Opnamedatum:  2011-04-29

A primera vista parece un grabado típico de Jesucristo, pero hay algo raro en la imagen, un efecto óptico extraño. Acerquémonos un poco más para verlo:

Cristo-cerca

El grabado es una espiral que empieza en la nariz de Cristo y cubre el dibujo completo. El artista aumenta el grosor de la espiral en las zonas en las que lo requiere para dar forma o sombra. Además, el trazado de la espiral es modificado levemente para adaptarse al dibujo. Y todo esto realizado a mano.

contando

¡Oh! ¿Qué le habrá pasado a nuestro Schrödi sorprendido? Parece que se ha “espiralizado”, tendrás que seguir leyendo para descubrirlo y probarlo tú mismo.

El sudario de Santa Verónica fue dibujado por Claude Mellan en 1649 y es la obra más conocida del artista francés. No fue el único grabado que creó con esta técnica, pero sí el más importante y el que muestra de una forma más pura el trazo en espiral.

¿Y qué es una espiral?

¿Y tú me lo preguntas? Espiral eres tú.

La espiral que más se asemeja al dibujo de Mellan es la espiral de Arquímedes, que consiste en el lugar geométrico de un punto moviéndose a velocidad constante sobre una recta que gira sobre un punto de origen fijo a velocidad angular constante.

A mí esta explicación me suena a chino. Además es imposible leerla sin parase a respirar. Pero para estos casos siempre contamos con la ayuda de recursos visuales, aquí tenéis una animación que he preparado para comprender mejor esta espiral:

espirala1_1

Podéis ver cómo el rombo que dibuja la espiral se encuentra en una recta que va girando a velocidad constante. Además el punto se aleja del origen también a velocidad constante, describiendo así la espiral de Arquímedes. El movimiento a velocidad constante del punto en la recta quizás sea difícil de ver en esta animación, pero vamos a darle la vuelta a la tortilla y a hacer que lo que gire en la animación sea el plano:

espirala2_1

Si habéis conseguido evitar el mareo, podéis ver cómo el punto va avanzando a velocidad constante en la recta. En este caso lo que está girando es el plano a una velocidad constante, mientras dibujamos una línea recta, también  a velocidad constante.

Una característica importante de la espiral de Arquímedes es que la distancia entre las distintas “vueltas” es constante. Este hecho hace que sea perfecta para hacer un grabado como el que hizo Claude Mellan. Si hubiera usado una espiral logarítimica, el aumento de distancia que se produce en cada vuelta habría dado al traste con el dibujo.

La fórmula en coordenadas polares mediante la que podemos representar este tipo de espirales es:

r = a + b \theta

Donde:

  • ason dos valores que determinan dónde se inicial la espiral (a) y cómo de juntos están los brazos de la misma (b)
  • es la distancia al eje de cada punto
  • \theta es el ángulo respecto al origen y al eje x

Aquí podéis ver  3 ejemplos de la espiral para distintos valores de b:

bigualtodos

Vamos a dibujar espirales emulando a Mellan

Mi capacidad artística es nula, pero por suerte existen los ordenadores. Así que vamos a emular a Mellan y vamos a hacer nuestros dibujos en espiral usando nuestro pincel binario.

Para ello lo que necesitamos es una imagen inicial, a poder ser en blanco negro y con alto contraste, para que la imagen final sea más resultona. Por ejemplo, esta imagen:

Schrodinger

Así se quedó Schrödinger cuando se enteró de que Disney había comprado los derechos de Star Wars.

Y ahora tenemos que trazar la espiral respecto a la imagen. Para no hacer más cálculos de los necesarios obtenemos el radio máximo que podrá tener la espiral dentro de la imagen, usando un simple cálculo trigonométrico:

Como decía un profesor que tuve de química: "esto es de cajón de madera de pino". Claro que el lo decía después de poner una formulaca.

Como decía un profesor que tuve de química: “esto es de cajón de madera de pino”. Claro, que el lo decía después de poner una formulaca.

Ahora sabemos que debemos calcular una espiral cuya distancia al centro de la imagen vaya desde cero hasta el valor de r que acabamos de calcular. Para calcular los puntos de la espiral usaremos la fórmula que hemos visto antes, dándole valores al ángulo para obtener los valores de r.

Una vez obtenido un par de valores (r, \theta), su paso a coordenadas (x,y) se realiza de nuevo mediante una sencilla operación trigonométrica:

x = r\, cos \,\theta

y = r\, sen \,\theta

Los números obtenidos tendremos que redondearlos para que sean enteros, para hacerlos corresponder con pixeles de la imagen. Aquí tenemos un ejemplo en el que el ángulo va aumentando en un valor de 0.1:

tabla

Al hacer el cálculo de la espiral respecto a la imagen se pierde mucha información, estamos convirtiendo varios puntos de la espiral en uno solo para la imagen.

Una vez calculados los puntos de nuestra espiral, tendremos que rehacer el dibujo. Para ello recorreremos la imagen pixel a pixel, desde la esquina superior izquierda, hasta la esquina inferior derecha, y pondremos un punto blanco donde no se cruce con la espiral y un punto con el color original de la imagen donde coincida con la espiral.

De esta forma el resultado final sería este:

schrodiespiral

Y esta es la cara que se le quedó al pobre Schrödi cuando se enteró de que en las nuevas películas volverá a salir Jar Jar.

Ahora viene lo bueno, tú también puedes probarlo

Todo esto que os he explicado se ha convertido en una aplicación web que permite convertir en una espiral una imagen:

Captura de pantalla 2013-12-02 a las 23.38.09

Así que si quieres probar a espiralizarte estás invitado y si quieres saber como #%&@ funciona esto… puedes seguir leyendo.

¿Cómo funciona esto?

La aplicación es bastante sencilla, comienza con un script escrito en python que muestra la página inicial y contiene la lógica necesaria para poder subir un fichero al servidor. Aunque el procesamiento de la imagen ser hará mediante javascript en el navegador del usuario, la imagen debe estar en el mismo dominio que la aplicación para que pueda modificarse. En este caso el servicio se encuentra alojado en una cuenta gratuita de Google App Engine.

Una vez el fichero ha sido subido o se elige una imagen por defecto, se pasa a una página html que realiza la transformación de la imagen mediante javascript. Para realizar esta transformación uso las ventajas que ofrece el objeto canvas en HTML5. Como su propio nombre indica, la clase canvas es un lienzo en el que podemos dibujar lo que nos apetezca dentro de una página HTML. En este caso empezamos dibujando la imagen original:

function drawImage(imageObj) {
	//obtener objeto canvas
	var canvas = document.getElementById('myCanvas');
	//obtener un contexto 2d del canvas
	var context = canvas.getContext('2d');

	//asociar al canvas la altura y anchura de la imagen
	canvas.width = imageObj.width;
	canvas.height = imageObj.height;

	//dibujar la imagen
	context.drawImage(imageObj, 0, 0);
}

imageObj es un objeto de tipo imagen, que se crea de la siguiente forma a partir de los parámetros de la página:


	    //objeto imagen
	    var imageObj = new Image();
	    //cuando la imagen se carga se dibuja
	    imageObj.onload = function() {
	        drawImage(this);
	    }

	    // Obtener parámetros de la página
	    function getQueryParams(qs) {
			qs = qs.split("+").join(" ");

			var params = {}, tokens,
			re = /[?&]?([^=]+)=([^&]*)/g;

			while (tokens = re.exec(qs)) {
			    params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
			}

			return params;
		}

		//Obtener los parametros de la pagina y utilizar el parametro img como ruta de la imagen
		var param = getQueryParams(document.location.search);
	    imageObj.src = param.img;

Luego el usuario podrá pulsar la opción de espiral deseada, y ver cómo su imagen se transforma. La función que realiza el cambio es la siguiente:

		function espiralizaImagen(imageObj, b)
		{
			//obtener objeto canvas
			var canvas = document.getElementById('myCanvas');
			//obtener un contexto 2d del canvas
			var context = canvas.getContext('2d');

			//Obtener los datos de la imagen que hay dentro del canvas
	        var imageData = context.getImageData(0, 0, imageObj.width, imageObj.height);

	 		//Array con los valores de cada pixel de la imagen
	        var data = imageData.data;

	        // calcular centro de la imagen
			var xcenter = imageObj.width/2;
			var ycenter = imageObj.height/2;

			// calcular radio máximo de la espiral
			var rmax = Math.sqrt(xcenter*xcenter + ycenter*ycenter);

			//calculo de la espiral
			var r=0 , t=0, pold = '';
			var espiral = new Object();

			// mientras no alcancemos el radio maximo
			while(r<rmax)
			{
				// calcular el radio.
				// t es el valor del angulo en radianes
				// b el valor que define la distancia entre lineas de la espiral
			    r = b*t;

			    // a partir del valor de r y t podemos calcular los valores x e y
			    hx = Math.round(r*Math.cos(t));
			    hy = Math.round(r*Math.sin(t));

			    // definimos la variable para guardar el punto de la espiral
			    var p = 'p'+hx+','+hy;
			    // si no se ha guardado antes, lo hacemos e incrementamos t
			    if (p!=pold){

			    	espiral[p]=1;
			    	pold=p;
			    	t+=_paso;
				}
				// si ya estaba guardado estamos repitiendo valores, aumentamos más el paso
				else
					t+=2*_paso;

			}

			// creación de la nueva imagen
			// el array con los datos de la imagen es de una sola dimensión
			// cada trio de valores corresponde con los valores RGB de un pixel
			for(var i = 0; i < data.length; i += 4) {

				//Calcular los valores x,y a los que corresponde el índice i actual
				var xi = i/4%imageObj.width;
			  	var yi = Math.floor(i/4/imageObj.width);
			  	xi-=Math.round(xcenter);
				yi=Math.round(ycenter)-yi;

			  	// valor que se pondrá si el pixel no esta en la espiral (#FFF)
			  	brightness=255;

			  	// clave con la que deberá estar guardado en la espiral
			  	var p = 'p'+xi+','+yi;

	          	// si no está en la espiral, pondremos los pixeles con color #FFF (blanco)
			  	if(!espiral.hasOwnProperty(p)){
			  		// red
	          		data[i] = brightness;
	          		// green
	          		data[i + 1] = brightness;
	          		// blue
	          		data[i + 2] = brightness;
			  	}
			  	// en caso contrario, esta en la espiral y lo dejamos tal como está
	        }

	        // sobreescribimos la imagen con los nuevos datos conseguidos
	        context.putImageData(imageData, 0, 0);

	        // creamos una URL de descarga para la imagen
	        var dataUrl = canvas.toDataURL();
	        // asociamos la imagen a nuestro objeto imagen
	        var descarga= document.getElementById('canvasImg');
	        descarga.src = dataUrl;

	        // ocultamos el canvas y mostramos el objeto imagen para que pueda descargarse
	        canvas.style.display = "none";
	        descarga.style.display="inline";
		}

Los puntos de la espiral se almacenan en una lista, que luego es usada para comprobar si el punto de la imagen está en la espiral o no. Finalmente se guarda la imagen y se hace un truquito: la clase canvas no permite descargar la imagen, por lo que se sustituye por un objeto imagen que si permitirá la descarga.

En los enlaces tenéis la estructura completa subida a app.engine por si queréis trastear un poco con la aplicación. Y ya sabéis, ¡a espiralizarse y mineralizarse!

Más información

Aplicación web para convertir una imagen en una espiral.

El sudario de Santa Verónica de Claude Mellan en Wikipedia

La espiral de Arquímedes en Wikipedia

Tutoriales de uso del objeto canvas en HMTL5, de este recurso obtuve mucha información para realizar la aplicación.

Google App Engine, el recurso para los que no queremos rascarnos el bolsillo cuando ponemos una aplicación online.

Archivo con el código fuente de la aplicación, incluyendo fichero de configuración para App Engine.

Anuncios

Publicado el 2 diciembre, 2013 en Arte y ciencia y etiquetado en , , , , , , , , . Guarda el enlace permanente. 17 comentarios.

  1. Jaja, ¡mola!

  2. ¡Qué bueno! Los diagramas/animaciones que explican la espiral me han parecido sensacionales. Lo demás también lo parece, pero como no me entero bien del todo, mejor no me pronuncio de forma más contundente.

    Geniales los pies de foto, aunque espero, ESPERO, que lo de Jar Jar sea parte de la coña. Por favor.

  3. Muy interesante! Y ameno!
    P.D: sin embargo no me impacta que los religiosos utilizasen en sus dibujos efectos ópticos hipnotizantes…. porqué será 😄

    • Gracias!

      Seguramente en esa época, para vender tus obras lo mejor era hacer retratos u obras de temática religiosa. Si buscas obras de Mellan verás que tenía también otros retratos de gente de la época, pero en ninguna usaba la espiral de una forma tan marcada.

  4. Que suerte de haber encontrado tu blog! Exelente artículo, una pregunta, ¿con qué herramienta creaste las animaciones?

  1. Pingback: Bitacoras.com

  2. Pingback: El grabado y la espiral

  3. Pingback: Lo Mejor de la Semana (1-7 de diciembre) | Hablando de Ciencia | Artículos

  4. Pingback: El grabado y la espiral | Matifutbol | Scoop.it

¡Un comentario para un ex-leproso!

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: