Problema programación bolas de billar

Hola.

Tengo un problema de programación de movimiento de bolas de billar que no llego a resolver.

El algoritmo recorre cada una de las bolas de billar, las mueve a una nueva posición según su vector director y energía, comprueba si hay alguna colisión y si es así transmite la energía de las bolas y la coloca en la nueva posición.

El problema lo tengo en el caso 2 que menciono abajo:

Los círculos rellenos representan el instante inicial de simulación (t) y los círculos con el centro
en blanco el instante final de simulación (t+1). Los cuadrados son las cajas de colisión.

Caso 1: Movimiento de dos bolas que se entrecruzan

Imagen


Se mueve la bola roja a su posición final: no hay colisión con nada.
Se mueve la bola azul a su posición final y tampoco hay colisión con nada.
En la vida real esto no sucedería puesto que habría una colisión en el punto en que sus trayectorias se entrecruzan.


Solución al caso 1:
Imagen


Lo que hago es que las cajas de colisión en vez de rodear a las bolas rodean la trayectoria de cada bola y al superponerse veo que ha habido una posible colisión entre ellas.
Si ha habido posible colisión miro el instante de tiempo en que ha ocurrido y entonces muevo las bolas a la posición que en ese instante de tiempo tendrían (t + (t+1) / 2) y compruebo si hay colisión entre ellas.




Caso 2: Movimiento de 3 bolas (donde tengo el problema) (la caja verde debería rodear a la bola verde transparente, es que me ha salido mal el dibujo)

Imagen


El problema lo tengo porque en el caso de tres bolas el algoritmo me da que ha existido una colisión entre la caja verde y la caja roja y esto en la vida real no ocurriría ya que la bola roja y la bola azul colisionan antes y por lo tanto la bola roja no llega a colisionar con la verde.


Gracias.

Adjuntos

¿Programación concurrente? ¿Estas usando hilos?
así en lo que a tema de diseño parece puede ser que no estén bien las prioridades
por eso choca con la verde antes que con las demás, no sé
El algoritmo original usaba hilos pero este problema lo seguía teniendo.

Ahora utilizo un algoritmo clásico de programación de videojuegos de ir dibujando
una cosa detrás de otra.
zarkon escribió:El algoritmo original usaba hilos pero este problema lo seguía teniendo.

Ahora utilizo un algoritmo clásico de programación de videojuegos de ir dibujando
una cosa detrás de otra.

Pues hay un problema claro, hago conjeturas pero supongo que tendrás algo tal que así (C++):

for (short i = 0; i < N_Bolas;i++)
{
  // Comprobar colision de [i]
}


Suponiendo que la bola roja y verde tuvieran un índice menor que la azul, entonces detectarían su colisión antes de la azul.

Una forma de solucionarlo sería emplear distancias y responder solo a la distancia menor... Aunque creo que sería mejor disminuir los recorridos.
¿Es un ejercicio de programación que busca algo en concreto? ¿O es porque quieres hacer un billar? :P

Si es lo segundo, yo lo haría moviendo cada bola en un dt, y no calculando las posiciones finales.

(Vamos, como si fueran partículas).
Hola.

Cada bola se mueve un dt.
Lo que muestro no es la posición final del movimiento sino la posición
en el momento de simulación dt.

Por muy pequeño que sea dt siempre hay algún instante en el que la suma de las energías de las bolas
las hagan moverse un espacio mayor que su diámetro.

Raytracing no produce interacciones de movimiento en el trazado de rayos puesto que el rayo rebota y no provoca que el objeto en el que ha rebotado se mueva.

Sólo me queda el sistema de partículas pero no sé hasta que punto será rápido.

¿Existe algún algoritmo sencillo? (No necesito código, tan sólo la idea ó pseudocódigo)

EDITO: He conseguido resolver el problema pero el algoritmo requiere recursividad. Lo planteo de forma lineal:


1.- Se comprueba si el camino de la bola verde intersecta con el camino de la bola roja (true)

2.- Miramos el punto en que colisionan los caminos y retrocedemos la simulación al instante Tcolision1

3.- Antes de mirar si las bolas verde y roja colisionan (que en este punto si lo hacen, como hacía hasta ahora)
compruebo si los caminos actuales colisionan con otros caminos (el camino rojo colisionará con el azul).

4.- Miro el punto en que colisiona el camino rojo y azul y retrocedemos la simulación al instante TColision2
5.- Antes de mirar si las bolas azul y roja colisionan compruebo si los caminos actuales colisionan con otros caminos (false)

6.- Se comprueban si la bola azul y roja colisionan (true), la verde no colisiona con nada.

6- Se calculan las físicas y se colocan las bolas en sus posiciones.

7- Se mueve la simulación al instante de tiempo dt-TColision2
zarkon escribió:Hola.

Cada bola se mueve un dt.
Lo que muestro no es la posición final del movimiento sino la posición
en el momento de simulación dt.

Por muy pequeño que sea dt siempre hay algún instante en el que la suma de las energías de las bolas
las hagan moverse un espacio mayor que su diámetro.

Raytracing no produce interacciones de movimiento en el trazado de rayos puesto que el rayo rebota y no provoca que el objeto en el que ha rebotado se mueva.

Sólo me queda el sistema de partículas pero no sé hasta que punto será rápido.

¿Existe algún algoritmo sencillo? (No necesito código, tan sólo la idea ó pseudocódigo)

EDITO: He conseguido resolver el problema pero el algoritmo requiere recursividad. Lo planteo de forma lineal:


1.- Se comprueba si el camino de la bola verde intersecta con el camino de la bola roja (true)

2.- Miramos el punto en que colisionan los caminos y retrocedemos la simulación al instante Tcolision1

3.- Antes de mirar si las bolas verde y roja colisionan (que en este punto si lo hacen, como hacía hasta ahora)
compruebo si los caminos actuales colisionan con otros caminos (el camino rojo colisionará con el azul).

4.- Miro el punto en que colisiona el camino rojo y azul y retrocedemos la simulación al instante TColision2
5.- Antes de mirar si las bolas azul y roja colisionan compruebo si los caminos actuales colisionan con otros caminos (false)

6.- Se comprueban si la bola azul y roja colisionan (true), la verde no colisiona con nada.

6- Se calculan las físicas y se colocan las bolas en sus posiciones.

7- Se mueve la simulación al instante de tiempo dt-TColision2


No sabes cuanto te estas complicando la vida.
Stylish escribió:
zarkon escribió:Hola.

Cada bola se mueve un dt.
Lo que muestro no es la posición final del movimiento sino la posición
en el momento de simulación dt.

Por muy pequeño que sea dt siempre hay algún instante en el que la suma de las energías de las bolas
las hagan moverse un espacio mayor que su diámetro.

Raytracing no produce interacciones de movimiento en el trazado de rayos puesto que el rayo rebota y no provoca que el objeto en el que ha rebotado se mueva.

Sólo me queda el sistema de partículas pero no sé hasta que punto será rápido.

¿Existe algún algoritmo sencillo? (No necesito código, tan sólo la idea ó pseudocódigo)

EDITO: He conseguido resolver el problema pero el algoritmo requiere recursividad. Lo planteo de forma lineal:


1.- Se comprueba si el camino de la bola verde intersecta con el camino de la bola roja (true)

2.- Miramos el punto en que colisionan los caminos y retrocedemos la simulación al instante Tcolision1

3.- Antes de mirar si las bolas verde y roja colisionan (que en este punto si lo hacen, como hacía hasta ahora)
compruebo si los caminos actuales colisionan con otros caminos (el camino rojo colisionará con el azul).

4.- Miro el punto en que colisiona el camino rojo y azul y retrocedemos la simulación al instante TColision2
5.- Antes de mirar si las bolas azul y roja colisionan compruebo si los caminos actuales colisionan con otros caminos (false)

6.- Se comprueban si la bola azul y roja colisionan (true), la verde no colisiona con nada.

6- Se calculan las físicas y se colocan las bolas en sus posiciones.

7- Se mueve la simulación al instante de tiempo dt-TColision2


No sabes cuanto te estas complicando la vida.



¿Qué solución propones? Sólo tengo que moverme hacía atrás en la simulación hasta que las trayectorias no colisionen con otra diferente.
Desarchivo y lo muevo a su foro correspondiente :P
Sabio escribió:Desarchivo y lo muevo a su foro correspondiente :P


Se llegó a solucionar?
Ogunsoto escribió:
Sabio escribió:Desarchivo y lo muevo a su foro correspondiente :P


Se llegó a solucionar?

Diría que sí, zarkon en el reporte comentaba que había encontrado la solución.


Ho!
12 respuestas