Animación de partículas con MATLAB

 

Últimamente se ha podido comprobar que incluyo en el blog cosas interesantes que hago en la universidad. Es curioso, porque esto no lo he hecho hasta ahora, y ahora que lo hago a menudo se trata de asignaturas que poco tienen que ver con la carrera.

Pero bueno, yendo al tema, resulta que estoy aprendiendo animación con MatLab. Obviamente hay formas de programar animación mejores, pero al ser un curso muy “para principiantes”, y dado nuestro manejo más bien escaso en programación en C (o de cualquier tipo) que nos proporciona la carrera, hacerlo en MatLab, que más o menos se controla, supone una ventaja a pesar de las limitaciones.

Lo de “animación” debería matizarse, ya que la gracia no está solamente en mover objetos, sino en que éstos lo hagan siguiendo las leyes de la física, y ahí está lo interesante (y lo difícil). De ahí que, más que animación, deberíamos hablar de “animación basada en simulación de sistemas dinámicos”, por rimbombante que suene, donde se entiende por “sistema dinámico” como un sistema físico real (o algo que represente lo mejor posible la realidad).

Para empezar, nos enseñan a simular el comportamiento del sistema más simple que hay, el de la partícula. Las partículas tienen en cada instante (lo que para un programa de ordenador es un paso discreto) una cierta posición y velocidad, así como una fuerza ejercida sobre ella, como por ejemplo la gravedad. Estas variables convenientemente actualizadas y relacionadas entre si, pueden dar la sensación de un sistema real de partículas.

 

Fuentes y fuegos artificiales

El primer video es un caso muy simple de simulación de partículas, en las que éstas forman una especie de “fuente”, comenzando en un punto con una cierta velocidad y dejando que la gravedad haga el resto. Se ve un caso en el que hay colisiones con el suelo, algo relativamente sencillo, y el último caso tiene algo de más gracia, ya que intenté imitar unos fuegos artificiales.

 

Fuentes de partículas y fuegos artificiales

 

Colisiones con superficies curvas

En el siguiente vídeo las colisiones ya no son tan sencillas de programar, ya que se tratan de superficies curvas, como una esfera. Las colisiones constan de dos partes principalmente: detectar que has chocado (más bien sencillo) y actualizar la posición y velocidad correctas tras el choque (aquí está lo difícil, si se quiere hacer bien).

Más concretamente, las simulaciones del vídeo son estas:

1. Colisiones de partículas con dirección aleatoria con una esfera desde el interior.
2. Un conjunto de partículas con simetría cilíndrica colisionando con la esfera desde el interior. Esta simulación fue en realidad un error, porque intentaba otra cosa, pero el resultado fue tan curioso que lo grabé.
3. “Plano” de partículas que cae sobre el exterior de una esfera. Colisión también con las paredes y el suelo (amortiguadas).
4. ¡Todo junto!… y con colorines.

 

Colisiones con esferas

Próximamente, haré una entrada sobre sistemas de 1 dimensión en lugar de partículas independientes, es decir de sistemas tipo “cuerdas”.

 


Esta entrada pertenece a la colección Animación con MatLab.

28 comentarios

  1. Manuel Ruilova Valle. · · Responder

    Me puedes ayudar con el código de matalb, en la simulaciones de colisiones de partículas a mi correo ..muchas gracias necesito de urgencia….Mi correo es marv.1990@hotmail.com

  2. A los que me pedís el código entero por un examen, lamento deciros que el objetivo de este blog es en parte educativo, y no considero que copiar y pegar el código contribuya con ese objetivo de aprender Matlab, en este caso.
    Si no teneis ninguna noción de matlab, en primer lugar me parece extraño que tengáis un examen, y en segundo lugar hay buenos tutoriales para iniciarse en matlab en la web, y sería largo hacer uno aquí.

    Para los que ya tengan nociones básicas de matlab, puedo explicar en qué consiste la animación y las colisiones por si sirve de ayuda:

    La simulacion consiste en el dibujo de un punto (hay funciones para eso), con unas coordenadas (x,y,z) o (x,y) si son solo 2D.
    Primero hay que actualizar la velocidad de la particula, que depende de la aceleración en la posición en la que esté. Si solo hay gravedad, la aceleración siempre es la misma y vale (0,0,-9,8) o (0,-9,8) en 2D.
    Si V es el vector velocidad y G el de la gravedad que he puesto antes, entonces la nueva velocidad es:
    V = V + G*h, donde h es el intervalo de tiempo entre un instante y el siguiente, que se puede escoger como una constante.

    Para calcular las coordenadas (x,y,z) se necesita saber la velocidad de las particulas a dibujar. Si la posición es el vector P y la velocidad el vector V, el calculo de la nueva posición P es:
    P = P+V*h, donde h es el intervalo de tiempo entre un paso y el siguiente. asi se actualiza la posición en cada paso.

    Estas actualizaciones, junto con el dibujo del punto, deben hacerse muchas veces, sobreponiendo cada vez el nuevo dibujo al anterior. Para eso suele utilizarse algún loop (while o for).

    Para las colisiones hay que hacer dos cosas: la primera es detectar que hay una colisión, y la segunda es recalcular la V y la P como si la particula rebotara. Si por ejemplo la superficie es el suelo, el caso mas fácil, entoces saber si se ha chocado consiste en comprobar si la nueva P calculada tiene una coordenada vertical por debajo del suelo. Si el suelo es z=0, por ejemplo, entonces hay que comprobar si la z de nuestro vector P es menor que 0.
    Para corregir la velocidad basta con cambiar el signo de la componente vertical de la velocidad.
    Para corregir la posición hay que calcular el punto de colisión Pc (sabiendo el punto antes de chocar Pa y el de después Pd, será uno intermedio donde z=0 de la recta que los une). El vector que va del punto anterior a la colisión hacia el punto de colisión (Pc – Pa) es el mismo que el que va del punto de colisión al nuevo que queremos calcular, pero con la componente vertical cambiada de signo. Si os dibujais los verctores en un papel lo vereis más fácil.

    La colisión con otras superficies se basa en los mismos dos pasos de detección y corrección, pero pueden tener una geometría más compolicada.
    Si tengo tiempo explicaré esto mismo mejor en un post en el futuro.

    Saludos.

  3. La idea no es copiar el codigo porque mi examen es diferente, solo que el rebote de las particulas es el principio del mismo…. como muevo los puntos es mi pregunta ‘ç??????ya que lo puedo realizar en una trayectoria ya determinada por una funcion y aqui lo hacen de manera aleatoria

    1. Ya entiendo tu problema. Digamos que lo que tu hacías no era simulación numérica, puesto que no usas métodos numéricos, si no que ya conoces todos los puntos de la trayectoria desde el principio. Eso está bien si sabes como es el movimiento siempre, y si tienes una función explícita tipo x=f(t) o y=f(t).
      El enfoque que explico yo y que uso es distinto. No se conoce la trayectoria explícitamente, si no que se calcula cada nuevo punto en función del anterior calculado y de la velocidad. Y la velocidad se calcula en función de la aceleración en un punto (por ejemplo la gravedad) como explico antes.

      Es cuerpo principal del programa es un loop, como un ‘for’, por ejemplo. Dentro del ‘for’ calculas la velocidad nueva, la posición nueva, y dibujas esa posición con un plot o un plot3, por ejemplo.
      Al volver a entrar en el ‘for’, volverás a calcular una nueva velocidad y un nuevo punto en función del calculado antes, y al hacer de nuevo el plot, se te borrará el anterior plot y se te sustituirá por el nuevo plot. La sucesión de todos los plots da la apariencia de movimiento.

      Un ejemplo muy básico del programa sería este:

      ———————————————-
      clear
      figure(1)

      %condiciones iniciales
      x=[0;0;0];
      v=[0;0;4];
      F=[0;0;-9.8];

      %paso
      h=0.01;

      %haces la simulación tan duradera como quieras
      for step=1:500

      %limpias lo que haya
      clf;

      %dibujas el punto
      plot3(x(1),x(2),x(3),’o’);

      %manejas el gráfico para que se vea bien
      title([‘step : ‘ num2str(step)]);
      axis([-0.2 0.2 -0.2 0.2 0 1]);
      view(3)
      drawnow;
      pause(0.01);

      %calculas la nueva posición y velocidad
      v=v+F*h;
      x=x+v*h;

      %compruebas si la nueva posición a atravesado el suelo, y si es así, la actualizas.
      if(x(3)<0)
      x(3)=-x(3);
      v(3)=-v(3);
      end

      end
      ——————————————————————————

      Este es el esquema básico, pero por supuesto se puede hacer mucho más complicado con otras superficies o con más de una partícula.

      Saludos.

    2. brother de verdad necesitamos el codigo, tenemos que presentar el examen hoy, no calculas la gran ayuda que nos darias facilitandonos los codigos. !!! porfas amigo talvez alguna manera de cominicarons contigo por interno, osea de mantera no tan publica como por aki, algun fb o algo!!??

  4. Monserrate · · Responder

    Buenas noches, disculpa estoy teniendo problemas al realizar un programa de simulación en matlab.
    La simulación consiste en el choque de n partículas pero los datos de la velocidad(en x ,y, z) deben estar en forma randómica y no se como realizar esa parte; además tengo que calcular las velocidades finales con su respectivo ángulo, los momentos de cada partícula y el momento del sistema.
    Intento brindarte una idea panorámica del proyecto, pero solo espero que puedas darme ciertas guías ya que nunca he usado matlab.

    Espero que puedas ayudarme y gracias de antemano.

    1. Hola. Supongo que cuando dices que la posiciones son aleatorias, te refieres a las posiciones iniciales. Una vez las condiciones iniciales están fijadas, las leyes de la dinámica hacen el resto, así que las posiciones estarán determinadas por la velocidad, y la velocidad por la aceleración (F/m) de cada partícula. Así que lo único que puede ser realmente aleatorio son las condiciones iniciales (las dos variables, posición y velocidad, por que el sistema es de segundo orden).

      No sé cómo guardas las posiciones, velocidades y aceleraciones. Yo las guardo en matrices 3xn (3 filas, n columnas), donde la primera fila es la componente x, la segunda la y, y la última la z.

      Para generar condiciones iniciales aleatorias simplemente puedes usar la función ‘rand’. Lo único malo que tiene es que, aunque los números son aleatorios, siempre se generan los MISMOS números aleatorios de una ejecución a otra. Antes de comenzar el bucle (en el que se calculan las nuevas velocidades y posiciones), debes calcular las condiciones iniciales. Por ejemplo, si tenemos 5 particulas, podemos ir añadiendo partículas (columnas) a la matriz con un ‘for’:

      %————————————-
      nx=[];
      nv=[];
      na=[];

      for n=0:5

      nx=[nx [rand;rand;rand]];
      nv=[nv [rand;rand;rand]];
      na=[na [0;0;-9.8]];

      end
      %————————————-

      Al final tendrás tres matrices 3×5 de 5 partículas con sus posiciones, velocidades y aceleraciones iniciales.

      Ten en cuenta un detalle MUY IMPORTANTE: rand es una función que solo da un número entre 0 y 1. Sí quieres un número entre a y b, tendrás que hacer ‘a + (b-a)*rand’. Para más información sobre esta función visita la documentación de Matlab: http://www.mathworks.es/es/help/matlab/ref/rand.html

      En el resto deberás ser más especifico para que pueda ayudarte. No sé a qué te refieres con velocidad final. Si es la del final de la simulación, serán los últimos valores que tengas en tu matriz de velocidades. El ángulo de la velocidad es el ángulo de un vector en tres dimensiones, y solo está definido respecto a una recta, o respecto a un plano (midiendo el ángulo respecto a la normal al plano). ¿Te refieres al ángulo respecto al plano horizontal, por ejemplo?

      El momento cinético es el producto de la masa y la velocidad. Yo la masa siempre la considero 1 para todas las partículas, por eso uso indistintamente la fuerza como una aceleración, pero puedes usar el valor que desees. Si asignas una masa distinta a cada partícula, las deberás guardar en un vector 1xn. Luego se trataría de multiplicar cada columna del vector de masas (que serán solo números) por cada columna de la matriz de velocidades (cada una será un vector de 3 componentes), y tendrás la matriz 3xn de momentos cinéticos. Si la masa es la misma para todas las partículas, el cálculo es tan sencillo como multiplicar esa masa por la matriz de velocidades.

      El momento del sistema es simplemente la suma vectorial de todas las columnas de la matriz de momentos cinéticos calculada antes. Al final tendrás un solo vector 3×1.

      Si eres principiante en Matlab te recomiendo algún manual como este PDF: http://mat21.etsii.upm.es/ayudainf/aprendainf/Matlab70/matlab70primero.pdf, y que consultes mucho la documentación del programa.

      Una última pregunta, ¿los choques de partículas son entre ellas o con alguna cosa(pared, suelo)? El problema es muy diferente en ambos casos.

      Espero haberte servido de ayuda.
      Un saludo.

  5. Brayan Bj · · Responder

    Muy Buenas Noches , te escribo para pedirte ayuda con respecto a la parte del choque entre partículas , en que te basaste para realizar los cálculos de la trayectoria de salida , que se da después del choque ??, entiendo que cuando hay un choque entre partículas , las posiciones deben ser las mismas , y eso se logra con un if , además que para calcular un choque entre dos partículas en 2d, necesitas la dirección de las partículas y la velocidades de las dos y el coeficiente de restitución , sabiendo que el choque es oblicuo, pero para tres dimensiones no sé cómo hacerle , si me podrías decir como realizaste el análisis para tu programa en la parte del choque entre las dos partículas por favor , aunque también hay la posibilidad de que se dé el choque entre dos o más partículas , como lograste hacerlo , porque no me sale y no tengo mucha idea de cómo realizar esa parte …, te agradecería mucho si me brindas tu ayuda , muchas gracias de antemano.
    Que tengas un buen día :D.

    1. Hola, en realidad nunca he hecho choque ENTRE partículas, sino con particulas y otras cosas como planos o esferas. Es más sencillo detectar el chique con un objeto fijo y de geometría sencilla, que de todas las partículas entre si. Pero aunque no lo haya hecho nunca puedo decirte lo que yo haría y darte algunos consejos:

      Empieza con solo dos o tres. Es un problema que claramente aumenta el tiempo de cálculo exponencialmente con el numero de particulas, así que empezaría con pocas.

      Cuando hagas simulaciones, nunca pidas que dos números coincidan exactamente. Prque nunca lo harán. Imagina que cada partícula, aunque solo guardes una posición concreta, tiene como una esfera de acción alrededor de un cierto radio. Si otra oartícula entra dentro de ese radio de acción, ya puedes considerar que colisionan. Pero no pongas como condición que dos partículas tengan exactamente la misma posición porque en una aimulación aleatoria es estadísticamente improbable. Un punto es un concepto geométrico y no tiene volumen, y las partículas reales si tienen.

      Elige el paso de integración y las velocidades adecuadas para que los saltos de una posición a otra sean relativamente cortos, y al simulación se vea suave. Ademas ayudará a que se detecte el choque de dos partículas que debe chocar, en lugar de que salten una sobre la otra. Es cuestión de ir probamdo valores.

      Como yo no he hecho choque entre partículas, no podria decirte como calcular las velocidades de salida. Si sabes hacerlo en 2d, intenta generalizarlo en 3d. Te aconsejo que pienses en vectores y en la conservación del momento cinético. Yo no lo he hecho, así que no podría explicarte cómo es, lo siento.

      El problema es complicado prque para cada particula hay que buscar si está dentro del radio de acción de alguna otra. Teniendo en cuenta que es algo recíproco (si una está en el radio de accion d otra, la otra tambien lo esta de la primera) seguro que hay formas eficientes a nivel de coste de tiempo para hacer todas las combinaciones de parejas entre partículas. Si solo hay dos, hay una pareja. Si hay 3, son 3 parejas. Con 4 son 6. Con 5 son 10…

      Por ultimo hay que tener en cuenta cuando se corrije la posicion despues del choque que se puede acabar dentro de otro radio de acción ,por lo que habría que volver a corregir.

      Yo te aconsejo que lo hagas para 2. Y luego intentes generalizarlo. Es un problema más dificil que las colisiones que enseño en el post,

      Un saludo,

  6. Omar Delgado · · Responder

    Ola que tal por favor ayudame con el codigo de colisiones o fuegos artificiales por favor a este correo domar0.2@hotmail.es te lo agradeceria muchisimo

  7. […] menos explicaré las infinitas posibilidades que hay de simular partículas. Lo que mostré en la entrada de simulación de partículas eran algunos ejemplos que se me ocurrieron a mí, como los fuegos artificiales o la colisión con […]

  8. tengo un problema necesito graficar ne 3d un movimiento parabólico me podrías ayudar como hacerlo

    1. En este blog hay tutoriales de simulaciones con MatLab, que puedes encontrar en el último enlace del post ‘Animaciones con MatLab’.
      El de tiro parabólico es en 2D, pero solo hay que cambiar los vectores de 2 dimensiones por unos de 3, la función de dibujo ‘plot’ por ‘plot3’, y la especificación de los límites del dibujo (la función axis).

      Un saludo.

  9. ¿como es la simulación del problema de tres cuerpos?

¿Qué te parece?

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: