Comunidad de diseño web y desarrollo en internet online

Fisica en Flash: Sistemas complejos, partículas y constrains

Simulacion de sistemas complejos II - Constrains

En este tutorial aprenderemos acerca de las relaciones que pueden existir entre varias partículas y como relacionando varias partículas podemos generar sistemas de partículas complejos que simulen objetos tales como cuerpos rígidos, blandos y articulados.
Definiremos entonces, a la relación entre dos partículas con el nombre de “Constrain”, que significa “forzar o limitar”. Efectivamente, son limitaciones a las que se someten las partículas en función del medio o de otras partículas.

Vamos a imaginarnos dos partículas en un medio ingrávido, sin rozamiento, a las que uniremos con un resorte muy duro. Las partículas pueden estar en cualquier posición del espacio siempre y cuando la distancia entre ambas sea igual a la distancia del resorte, ni menor y mayor.

Para simular el sistema, haremos uso de un bucle infinito, es decir, código que se ejecuta una y otra vez indefinidamente. Para cada iteración, supondremos que las partículas se encuentran a una distancia correcta, si movemos una de ellas para cualquier lado, la distancia entre ambas cambiará, puede darse el caso de que la misma sea mayor a lo deseado, menor o, en el mejor de los casos, igual. Para cada caso, vamos a proceder de la siguiente manera: Si la distancia es menor a la deseada, entonces vemos cuanto le falta a la distancia actual entre partículas y alejamos a cada partícula la mitad de ese faltante una de la otra. En el caso que la distancia sea mayor, entonces vemos cuanto sobra y acercamos cada partícula la mitad de ese sobrante una a la otra. Si la distancia es la correcta, entonces no hacemos nada.


Para pasar a código todo lo que acabo de decir, nos vamos a vales de una poderosa herramienta matemática llamada vectores. Los vectores son flechitas orientadas, que tienen un largo y una inclinación y señalan un punto en el plano(o el espacio). Las posiciones de las partículas(que son puntos), podemos expresarlas como vectores, los cuales tienen una coordenada x y una coordenada y. De las muchas propiedades que tienen los vectores, vamos a utilizar dos.
a. Cuando un vector se resta por otro vector de igual dirección y sentido, pero de distinto largo, el resultado es un vector que dice cuanto y en que sentido hay que estirar el menor para que iguale al mayor, esto es en el caso de que el vector que resta sea el menor. En el caso de que el que resta sea mayor, el resultado es otro vector que dice cuanto y en que sentido hay que reducir al mayor para que iguale al menor.


b. Si dividimos entre dos un vector nos queda uno con la misma dirección(inclinación) y sentido(para donde apunta la flecha) pero la mitad de largo.

Entonces calculamos la distancia entre las partículas restando los vectores que las representan, eso nos da la distancia actual, a eso le restamos la distancia deseada, lo que nos da una flechita orientada que nos dice como tenemos que mover las partículas para corregir sus respectivas posiciones.

Bueno ahora esa flechita orientada que resulta de la resta entre el vector que representa la distancia actual, presuntamente errónea, entre las partículas y el vector que representa la distancia deseada, la dividimos entre dos. El resultado de esa cuenta se la sumamos a la partícula que restaba en la cuenta que hicimos para calcular la distancia entre las partículas, y a la otra se la sumamos.
Todo ese cocoliche de procedimientos matemáticos ahora lo tenemos que implementar en el código, pero antes, necesitamos una clasecita actionscript con la que vamos a representar un vector, que es la siguiente
class Vector{
	var x:Number;
	var y:Number;
	var length:Number;
	function Vector(x, y){
	    this.x = x;
	    this.y = y;
	    this.length = Math.sqrt(x * x + y * y);
	}
} 
La clase anterior hay que crearla por separado en un archivo actionscript(con extensión .as), ya que flash no nos deja meter clases en un .fla
Bueno, ahora sí vamos a lo interesante, la siguiente función mantiene a dos partículas a una distancia predeterminada mientras se mueven por la pantalla. La misma se llama, muy apropiadamente, constrain.
//---Esta funcion es la que mantiene a las partícluas, frame tras frame a la distancia deseada.
// largo es la distancia deseada, p0 y p1 son las partículas, explicadas en el tutorial 1 de esta serie
function constrain(p0, p1, largo) {
	var correction = 0.025000; //factor de correccion (1)
	var dx = p1._x-p0._x;//distancia componente x
	var dy = p1._y-p0._y;//distancia componente y
	var d = new Vector(dx, dy);//vector distancia
        //---obtenemos el factor por el que hay que reducir el vector distancai entre partículas
	var r = (d.length-largo)/d.length;(2)
         //lo multiplicamos por cada componente del vector distancia entre partículas
	var x = d.x*0.500000*r;//(3)
	var y = d.y*0.500000*r;//(4)
        //ajustamos cada partícula
	p1._x = p1._x-(x-correction);
	p1._y = p1._y-y;
	p0._x = p0._x+(x+correction);
	p0._y = p0._y+y;
}

Vamos a analizar un poco el código. La variable correction en(1) dice que tan duro será el resorte. Las variables dx y dy son las componentes del vector distancia actual entre partículas. La formula en (2) obtiene el módulo(largo) del vector diferencia, esto es así debido a que si multiplicamos un vector por un escalar(un numero no vector) mayor que 1, el vector se estira, si en cambio, lo multiplicamos por un valor menor que 1, el vector se achica. En esta caso, la usaremos para achicar o agrandar(depende el resultado de la ecuación)el vector distancia entre partículas lo que le falto o sobre para igualarse al vector de distancia deseada, a esto se le llama "escalar" un vector.
En (3) y (4) calculamos el factor que hay que multiplicar las componentes de los vectores que representan las partículas, ya que cada partícula tiene que desplazarse exactamente la mitad de la distancia.

Como función adicional, vamos a utilizar una llamada distancia, que nos dice la distancia entre dos partículas, esto es útil para utilizar dos movielips como partículas y no tener que andar sacando cuentas a la hora de llamar a la función contrain.
Lo bueno de esto, es que cada partícula puede tener tantos constrains como queramos, formandose vinculos realmente complejos podemos simular estructuras de cualquier tipo.

En el próximo tutorial, juntamos los conceptos de partículas y contrains para generar un sistema complejo que es afectado por la fuerza de gravedad y los límites del escenario.

Saludos!!.

Importante: Algo que hay incluido en el archivo de ejemplo es una función para easy dragging que no viene al caso para lo que este tutorial pretende enseñar, la puse solamente para que el ejemplo quede mejor, ya que de no implementarla, al arrastrar una partícula, que está sometida al constrain, sufriría un desfasage con el puntero del mouse y no quedaría muy bien, si tenés ganas de investigarla acordate que el código para esta funcionalidad esta repartida entre la capa de código y los movieclips que representan las partículas.

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Descargar Archivo

Publica tu comentario

El autor de este artículo ha cerrado los comentarios. Si tienes preguntas o comentarios, puedes hacerlos en el foro

Entra al foro y participa en la discusión

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate