Geometría en las aplicaciones web

Las matemáticas están presentes en nuestra vida diaria. Como nos recuerda la aclamada serie: «We all use math every day». En el desarrollo web del lado del cliente necesitamos apelar –entre otras ramas– a la geometría y la trigonometría en el momento en que deseamos realizar aplicaciones que requieren de un alto contenido de animaciones e interactividad.

En esta entrada intentaremos agrupar los problemas de cálculo matemático que más nos encontramos en nuestros desarrollos web y las técnicas que normalmente usamos para afrontarlos.

Posicionar elementos en las esquinas del viewport

Si utilizamos CSS para posicionar el elemento no necesitaríamos realizar ningún tipo de cálculo ya que podríamos usar las propiedades top, right, bottom y left del mismo. Pero si nuestra aplicación no hace uso de hojas de estilo, entonces tendríamos que realizar cálculos y deberíamos tener en cuenta el ancho y el alto del elemento para poder posicionarlo correctamente. Suponiendo que el viewport tiene de ancho A y de alto B y el elemento a posicionar tiene de ancho α y de alto β los cálculos serían los siguientes para cada una de las posiciones:

Superior izquierda Superior derecha Inferior derecha Inferior izquierda

Un código jQuery podría ser el siguiente:

// Variables
var viewportW = viewport.width();
var viewportH = viewport.height();
var elementW = element.width();
var elementH = element.height();

// Puntos
var points = [

	{x: 0, y: 0},
	{x: viewportW - elementW, y: 0},
	{x: viewportW - elementW, y: viewportH - elementH},
	{x: 0, y: viewportH - elementH}

];

element.click( animate );

// Función de animar el elemento
var index = 0;

function animate(){

	index++;

	if(index == points.length) index = 0;

	element.stop().animate({

		left : points[index].x + "px",
		top : points[index].y + "px"

	});					

}
Clickear el cuadro naranja para observar la animación

Posicionar elementos aleatoriamente en el viewport

La técnica de posicionar elementos aleatoriamente en el viewport es parecida a la anterior. Si queremos asegurarnos que el elemento siempre quede dentro del área, las coordenadas en x e y deben mantenerse siempre comprendidas entre los cuatro puntos calculados anteriormente. Por lo tanto para hallar un punto aleatorio lo deberiamos hacer como se describe a continuación:

Donde ω equivale a un número aleatorio entre 0 y 1.

Un código jQuery podría ser el siguiente:

// Variables
var viewportW = viewport.width();
var viewportH = viewport.height();
var elementW = element.width();
var elementH = element.height();

function animate(){

	element.stop().animate({

		left : ( Math.random() * (viewportW - elementW) ) + "px",
		top : ( Math.random() * (viewportH - elementH) ) + "px"

	});					

}
Clickear el cuadro naranja para observar la animación

Posicionar elementos en el centro del viewport

Si el punto de referencia se encontrara en el centro del elemento no haría falta recurrir a muchos cálculos para posicionarlo. En un viewport de ancho A y alto B el centro se encontraría en:

Pero si el punto de referencia se encuentra en la esquina superior izquierda del elemento y este tiene de ancho α y de alto β entonces deberíamos restarle a ese punto la mitad de cada uno de estos lados para que el elemento quedara justo en el centro, las siguientes fórmulas describen los cálculos:
  =  

Clickear el cuadro naranja para observar la animación

Rotar elementos dirigiéndolos a un punto

Este proceso es muy sencillo y se basa en una relación trigonométrica, si tenemos dos puntos podemos calcular el ángulo θ que forma el vector que los une con respecto al eje de las abscisas. El siguiente ejemplo demuestra esta relación:

Mueve el mouse por la escena para observar la animación

Teniendo las coordenadas de los dos puntos podemos hallar el ángulo representado por θ. El método para hallarlo es calcular la arcotangente del cociente de la diferencia en las y y las diferencia en las x. Por ejemplo, si las coordenadas del primer punto son {x1, y1} y las del segundo son {x2, y2}, podemos calcular el ángulo de la siguiente forma:

Esto calculará un ángulo entre 0 y π cuando el punto 2 se encuentre por debajo del punto 1 y un ángulo entre 0 y cuando se encuentre por encima. Este sería el código JavaScript para que un objeto rote dirigiéndose a un punto dinámico que en este caso será el mouse:

Este ejemplo supone que el objeto se encuentra horizontal dirigiéndose a la derecha, si el objeto se encuentra en otra posición sería necesario sumar el ángulo que forma con el eje de las abscisas al ángulo calculado.

//  Acceder al elemento
var element = document.getElementById("element");

// Coordenadas del elemento
var bounds = element.getBoundingClientRect();
var elx = bounds.left + (bounds.right - bounds.left) / 2;
var ely = bounds.top + (bounds.bottom - bounds.top) / 2;

// Evento de mover el mouse por la pantalla
document.onmousemove = function(evt){

	var mx = evt.pageX;
	var my = evt.pageY;

	var radian = Math.atan2(my - ely, mx - elx);
	var angle = radian * 180 / Math.PI;

	element.style.transform = "rotate(" + angle + "deg)";
	element.style.WebkitTransform = "rotate(" + angle + "deg)";
	element.style.msTransform = "rotate(" + angle + "deg)";

}
Mueve el mouse por la escena para observar la animación

Posicionar elementos en el borde de una circunferencia

Para posicionar un elemento en el borde de una circunferencia o que se anime describiendo un círculo es necesario recurrir nuevamente a la trigonometría. Primero que todo deberíamos saber que la relación entre un punto de la circunferencia y su radio es la siguiente:

Donde x e y coresponden a las coordenadas de un punto cualquiera de la circunferencia y r al radio de la misma. Observemos el siguiente ejemplo para que podamos notar esta relación:

Desliza el mouse a ambos lados para observar la animación

Nos podemos dar cuenta que esta relación cumple con el teorema de Pitágoras ya que el triángulo formado es un triángulo rectángulo, por lo tanto si al menos tenemos dos datos de los mencionados podemos hallar el tercero.

Para aplicar el cálculo de Pitágoras en un ejemplo práctico, imaginemos que necesitamos generar puntos aleatorios en el borde de una circunferencia de un radio determinado, pues podríamos generar números aleatorios en el eje de las abscisas y después calcular el valor en las ordenadas, un método posible sería el siguiente:

// Generamos aleatoriamente un número positivo o negativo para escoger el cuadrante
var ax = Math.round( Math.random() ) * 2 - 1;
var ay = Math.round( Math.random() ) * 2 - 1;

// Generamos un número aleatorio entre 0 y el valor del radio
var x = Math.random() * radius;

// Calculamos las "y" aplicando Pitágoras
var y = Math.sqrt( Math.pow(radius, 2) - Math.pow(x, 2) );

// Calculamos el punto añadiendo la aleatoriedad de cuadrante
// y sumando el valor del centro de la circunferencia
var puntoX = x * ax + centerX;
var puntoY = y * ay + centerY;
Haz click sobre la escena para observar la animación

Visto como hallar puntos en una circunferencia utilizando el teorema de Pitágoras, vamos a ver cómo lograr hallar una serie de puntos pertenecientes a esta y que queden equidistantes, así como animar un punto a lo largo del perímetro usando para ello relaciones trigonométricas.

Como hemos visto anteriormente, el triángulo formado por las x, las y y el radio de la circunferencia es rectángulo. Por lo tanto responde a razones trigonométricas que se cumplen en este tipo de triángulos. Por ejemplo, en una circunferencia de radio r, con un ángulo θ formado por un punto {x, y} de la circunferencia, el centro de la misma y el eje de las abscisas se cumplirían las relaciones siguientes:
     
Donde θ es un valor entre 0 y . Por lo tanto cualquier punto de la circunferencia se podría describir de la manera siguiente:

Es decir, conociendo el ángulo y el radio de la circunferencia podríamos perfectamente calcular el punto respectivo a estos valores. Esta relación la podemos ver en el gráfico siguiente:

Mueve el mouse por la escena para observar la animación

Realicemos un ejemplo práctico en el que poder aplicar estos cálculos. Situaremos seis elementos equidistantes en el borde de una circunferencia, y después iremos calculando nuevas posiciones para crear una animación de estos a través del perímetro de la circunferencia, un ejemplo de código con jQuery podría ser el siguiente:

// Array de elementos producto de la selección con jQuery (contiene los seis elementos)
var elements = [elem0, elem1, elem2,..., elem5];

// Centro de la circunferencia en el formato
var centerX, canterY;

// Angulo de inicio y ángulo de separación
var startAngle = 0;
var sepAngle = (2 * Math.PI) / elements.length;

// Guardar las posiciones y el ángulo de cada elemento en memoria
var positions = [];

elements.each(function(index){

	positions[index] = {

		x : centerX + Math.cos( startAngle ) * radius,
		y : centerY + Math.sin( startAngle ) * radius,
		angle : startAngle

	};

	startAngle += sepAngle;

});

// Animar los elementos hasta el borde de la circunferencia
var sum = 0;

elements.each(function(index){

	$(this).animate({

		left : positions[index].x,
		top : positions[index].y

	}, function(){

		sum++;

		if(sum == element.length) animar();

	});

});

//  Ángulo de incremento de 2 grados
var inc = 2 * Math.PI / 180;

// Animar los elementos a lo largo del parímetro
function animar(){

  elements.each(function(index){
  
  	$(this).css({
  
  		left : centerX + Math.cos( positions[index].angle + inc ) * radius,
  		top : centerY + Math.sin( positions[index].angle + inc ) * radius
  
  	});
  
  });
  
  inc += inc;
  
  setTimeout( animar, 10 );

}
Haz click sobre la escena para observar la animación

Posicionar elementos en el borde de una elipse

El trabajo con la elipse es muy parecido al trabajo con la circunferencia, la gran diferencia entre estas dos figuras geométricas es que en el caso de una elipse no hay un radio sino dos ejes de diferente tamaño. Los puntos de una elipse de semiejes a y b cumplen la siguiente relación:

Donde x e y coresponden a las coordenadas de un punto cualquiera de la elipse. Observemos el siguiente ejemplo para que podamos notar esta relación:

Desliza el mouse a ambos lados para observar la animación

Sabiendo esta releación podríamos de manera sencilla generar puntos en una elipse si al menos conocemos tres de las variables, el proceso sería igual que el de la circunferencia así que no lo explicaremos.

Por otro lado, la relación de un punto de la elipse con respecto a un ángulo θ relativo al eje de las abscisas es mucho más complicada que la de la circunferencia:

Por lo que si se desea animar un elemento a lo largo del perímetro de una elipse es mucho más sencillo trabajar con una circunferencia y aumentar los valores calculados en las x o reducir los calculados en las y por lo que el resultado será cercano a lo elipsoidal.

Tomaremos el mismo ejemplo de la circunferencia realizado anteriormente y multiplicaremos por 1.5 los valores en las x, el resultado será el siguiente (se ha situado una elipse verdadera de un semieje horizontal 1.5 veces mayor que el radio de la circuenferencia para que se pueda comparar con el recorrido de los elementos):

Haz click sobre la escena para observar la animación

Y hasta aquí hemos recogido los principales cálculos matemáticos con los que nos encontramos a diario en los proyectos de aplicaciones web. Si crees que existen otros más, coméntanoslos para añadirlos en futuras entradas.

(5 votos, promedio: 4,20 de 5)
Comparte este artículo:

2 Comentarios

Puedes situar fragmentos de código dentro de etiquetas <pre></pre> y código HTML o XML entre etiquetas <xmp></xmp>.

Deja una respuesta

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


El periodo de verificación de reCAPTCHA ha caducado. Por favor, recarga la página.