ENUNCIADO:
Se pretende simular un juego de petacos (Pimball).
La práctica se divide en dos partes. A continuación contaremos la parte común, para después especificar cada parte en concreto.
(Para la realización de esta práctica hemos utilizado el libro 'Physics for Flash Games, Animation and Simulations')
(Para la realización de esta práctica hemos utilizado el libro 'Physics for Flash Games, Animation and Simulations')
Contamos con tres clases:
Pimball: Programa principal, donde se crean los objetos principales (el tablero y el array de bolas), se actualizan las partículas (llamando al método 'update' de Particle), se recogen los eventos de teclado, ...
Particle: Aquí tenemos el constructor de partículas (localización, velocidad, aceleración, radio). También aplicamos la gravedad, e integramos con Euler (semi), es decir, calculamos la velocidad, y luego la localización y la aceleración.
Tablero: Clase Plano y clase Tablero.
Un plano está formado por cuatro puntos: 'x' e 'y' de cada uno de los dos puntos que se unen para formar una superficie plana.
El tablero está formado por un array de planos.
El método más relevante es 'checkCollisions (Particle b)'; con este detectamos las colisiones con el plano y redireccionamos las partículas.
Calculamos:
- los vectores distancia entre los puntos del plano y la posición de la bola.
- la proyección de los anteriores vectores sobre el plano
- el vector distancia perpendicular entre la bola y el plano
Si las proyecciones entran en el módulo del plano, calculamos:
- si la bola atraviesa el plano (v.perpendicular < radio), invertimos la normal del plano
- el ángulo entre la velocidad de la bola y el plano
- el redireccionamiento de la bola (según la fórmula del libro Δs = radio + v.distancia • normal / sin (θ) )
- la descomposición de la velocidad (normal y tangencial al plano)
- invertir la componente normal y aplicar elasticidad, para sacar la velocidad de salida de las partículas tras el choque.
Calculamos:
- los vectores distancia entre los puntos del plano y la posición de la bola.
- la proyección de los anteriores vectores sobre el plano
- el vector distancia perpendicular entre la bola y el plano
Si las proyecciones entran en el módulo del plano, calculamos:
- si la bola atraviesa el plano (v.perpendicular < radio), invertimos la normal del plano
- el ángulo entre la velocidad de la bola y el plano
- el redireccionamiento de la bola (según la fórmula del libro Δs = radio + v.distancia • normal / sin (θ) )
- la descomposición de la velocidad (normal y tangencial al plano)
- invertir la componente normal y aplicar elasticidad, para sacar la velocidad de salida de las partículas tras el choque.
PARTE I: Colisiones partícula-plano (Diseño del escenario)
Como hemos comentado, en la clase Tablero calculamos la colisión de los planos con las bolas [ checkCollisions(Particle b) ], y en la clase Particle aplicamos la gravedad e integramos con Euler Semi-implícito.
PARTE II: Colisiones partícula-partícula (Varias bolas)
En cambio, en esta parte hemos añadido el método 'collision(Particle p) en la clase Particle. Para la detección de choque entre dos partículas, comparamos (p2 − p1).magnitude() < r1 + r2. Si es así, calculamos:
- la descomposición de la velocidad en normal [ velocidad.project(dist) ] y tangencial [ velocidad - normal ]
- la restitución:
· [ L = r1 + r2 − distancia.magnitude() ]
· la diferencia entre las normales [ vrel = (normalp1 − normalp2).magnitude() ]
· la nueva posición de la partícula [ a la posición de las partículas le sumamos ' mult(normal, -L / vrel) ' ]
- las velocidades de salida:
· Escalar: u1 = normal.projection(dist)
· Módulo: v1 = ((masa1−masa2)∗unitario1+2∗masa2∗uunitario2) / (masa1+masa2)
· Vector normal′ : necesitamos vectores paralelos al vector 'd' de módulo 'v1' y/o 'v2', por tanto multiplicamos 'v' por un vector unitario 'unitD' en la dirección de 'd' [ normalV1 = PVector.mult(unitD, v1); ]
· Velocidad final tras la colision = normal′ + tangencial
Creamos una variable booleana 'plano_puntos', que pasamos como parámetro al crear un plano. Nos indica si dicho plano suma puntos en el score. Así, observamos que hay determinados planos que hacen aumentar el indicador de puntos.
*Parte I:
*Parte II (sin gravedad):
*Vídeo Parte II (con gravedad):
· Vector normal′ : necesitamos vectores paralelos al vector 'd' de módulo 'v1' y/o 'v2', por tanto multiplicamos 'v' por un vector unitario 'unitD' en la dirección de 'd' [ normalV1 = PVector.mult(unitD, v1); ]
· Velocidad final tras la colision = normal′ + tangencial
Creamos una variable booleana 'plano_puntos', que pasamos como parámetro al crear un plano. Nos indica si dicho plano suma puntos en el score. Así, observamos que hay determinados planos que hacen aumentar el indicador de puntos.
*Parte I:
*Parte II (sin gravedad):
*Vídeo Parte II (con gravedad):
No hay comentarios:
Publicar un comentario