Problemas con las colisiones

Temas relacionados con la programación y la actualización audiovisual
User avatar
Anderson
Usuario avanzado
Posts: 70
Joined: Sun Jan 09, 2005 9:43 pm
Contact:

Problemas con las colisiones

Postby Anderson » Thu Apr 26, 2007 4:41 pm

¡¡¡HOLA A TODOS!!!. 8)

Como ya mencioné en otro thread, estoy teniendo bastantes problemas con el asunto de las las colisiones en la demo que estoy haciendo. En concreto, con las colisiones entre la pelota y las raquetas cuando chocan contra los laterales.

El mundo físico, como tal, está compuesto por 4 bounding boxes que componen el recinto del juego (techo, suelo, pared izquierda y pared derecha), mas 2 bounding boxes que no se ven dada la posición de la cámara, delante y detrás de cada raqueta, para detectarse que se ha marcado un tanto alcontrario; la pelota, por su parte, poseen su propio bounding box.

-Si se detecta que ha habido una colisión entre el bounding box de la pelota y los bounding boxes que son el techo ó el suelo, se modifica la componente Z del vector director de la pelota.

-Si la colisión ha sido contra los boundings de las paredes, la componente del vector
director de la pelota que se modifica será la Y.

-Si se detecta que ha sido contra una de las raquetas... depende, y aquí viene el tema; dependiendo de la cara del bounding box de la raqueta contra el que colisione el bounding box de la pelota, deberá modificarse la componente X, Y ó Z del vector director de la pelota.

Por ello, el método funciona bién contra el mundo físico, pero no muy bién en el caso de las raquetas y la pelota. Si la pelota choca contra los laterales de una raqueta...¡¡¡a saber qué le da por hacer!!!. Quzás "se mete dentro" de la raqueta y comienza a rebotar dentro de ella. Quizás hace un movimiento "extraño"
hacia adelante y hacia trás 3 o 4 veces y luego se va para otro lado. Más o menos, con los parámetros físicos actuales de la pelota, la cosa "se salva", pero en cuanto los cambias en la configuarción (o simplemente, cuando ya programe mejor lo de variar los ángulos de inclinación) volveremos a las andadas.

Los algoritmos de detección de colisiones que he visto, independientemente de funcionar mediante "lanzar un rayo", comprobación de planos, uso de normales, etc. sólo detectan si "ha habído ó no colisión", pero no ayudan a implementar algo que "devuelva" contra qué parte de un Bounding Box se ha colisionado. Así que he programado lo siguiente:

Lo que hago es generar un array de puntos dada la posición y las dimensiones del BoundingBox de la pelota, y mandárselo al componente principal del juego para comprobar si ha chocado contra el Bounding box de la entidad especificada. Éste devuelve true o false y devuelve un array con los aquellos puntos enviados previamoente que han colisionado.

Ahora, la lógica de la pelota debe revisar punto a punto en qué parte del Bounding de la pelota se encuentra dicho punto, y al final, dependiendo de dónde se encuentren la
mayoría de puntos, ese será la cara del bounding de la pelota que se considerará que ha colisionado, tomandose la medida opoutuna al recpecto.

Quizás es que, simplemente, este planteamiento no es correcto de base y haya que pensar en otra cosa totalmente distanta, pero no se me ocurre nada más por este camino.

Perdonad si al texto ha sido algo largo y farragoso, pero quería explicar con detalle el problama. :P

Gracias. 8)
:P
User avatar
Popolon
Usuario avanzado
Posts: 474
Joined: Tue May 13, 2003 2:31 pm
Location: Lloret de Mar
Contact:

Postby Popolon » Fri Apr 27, 2007 6:11 pm

La solución que comentas de generar un array de puntos no es común, pero creo que no está mal. Lo único que tienes que tener en cuenta es que deberías generar suficientes puntos para que la colisión sea realista.

En realidad lo único que necesitas es el vector de colisión. Es decir:
- C es el centro de la bola
- la bola se mueve a una velocidad V
- imaginate que la bola choca contra un objeto cualquiera (paredes o raquetas) en un punto P de la bola
- El vector PC (el que va del punto P al punto C) es el vector de colisión
- podemos descomponer la velocidad V en dos componentes:
- V1 que es la proyección de V sobre el vector PC. Es cedir: V1 = (V * PC) * V / norma(V) (donde V * PC quiere decir el proucto escalar)
- V2 = V - V1
- la velocidad de la bola después de la colisión tiene que ser: W = V2 - V1 (es decir, invertimos la velocidad en la dirección del vector de colisión).
- Si quieres que los choques no sean elásticos (es decir si quieres que la bola se frene cada vez que choque, entonces puedes hacer W = V2 - V1*elasticidad (donde elasticidad es un número entre 0 y 1)

Tu método del array de puntos no es más que una manera de obtener el punto P (el punto P es la media de todos los puntos que están en colisión con la raqueta). También puedes probar otros métodos más analíticos como en cada frame evaluar el volumen de la intersección entre la bola y la raqueta y el punto P es simplemente el centro de éste volumen (fíjate que tu método del array de puntos es una aproximación del método del volumen).

Si implementas el método del vector de colisión ni siquiera hace falta que trates las bounding boxes de las raquetas y las paredes de manera separada.

Bueno, pues eso. No se si te servirá de ayuda, pero bueno
Si lo que he escrito ya lo sabías y el problema no es ese, dímelo. :)

venga, ánimo con el juego!!!

(por cierto, Newton no se encarga por si sola de las colisiones?)
User avatar
Anderson
Usuario avanzado
Posts: 70
Joined: Sun Jan 09, 2005 9:43 pm
Contact:

Postby Anderson » Mon Apr 30, 2007 11:03 pm

No se si te servirá de ayuda, pero bueno
Si lo que he escrito ya lo sabías y el problema no es ese, dímelo. :)
He estado llevando detenidamente en papel la explicación que me has dado, sumamente esclarecedora. Este método que me has planteado supone la libertad de no tener que estar pendiente de saber con cual parte del mundo físico y/o con cuál lado de la raqueta ha chocado la pelota y así, modificar la coordenada X, Y ó Z del vector director. Lo típico: había estado repsando los conceptos de álgebra y geometría, había visto algoritmos de "calibre semejante" al que me has presentado en libros y demás, pero... "¡sí, muy bonito, ¿y ahora qué hago con esto?!". :( Pero gracias a esta explicación creo haber entendido cosas muy importantes y, por ello, te agradezco enormemente dicha explicación, y te aseguro que me ha sido de gran ayuda. Un concepto que, de momento, me ha resultado algo totalmente nuevo, es del "vector de colisión". Por ello, te agradezco enormemente esta explicación, y te aseguro que me ha sido de gran ayuda.

Sólo una cosa: Desde luego, si en el juego las raquetas y la pelota se movieran exclusivamente en el plano XZ, o en el XY... en resumen, como si fuera el clásico Pong en 2D... ¡¡¡ESTUPENDO, SERÍA EL MÉTODO PERFECTO!!!. :D

Pero como en este Pong la pelota se mueve a lo largo de los tres ejes de coordenadas, y no sólo de dos... aquí es donde me falta un poco de visión. ¿Servirá también así?. ¿No hay que añadir algo más?.

Creo saber hallar el plano en el que se mueve el vector V la pelota hallando la normal a dicho plano de esta manera:

(Sistema de coordenadas left-handed)

1º)Tomo como "referencia inicial" el vector [0, 1, 0]

2º) realizo el producto vectorial w = [0,1,0] X V

3º) Realizo el producto vectorial n = V X w

n sería la normal que utilizaré para hallar la proyección de V sobre PC. Algo así, ¿verdad?. :)

Y con respecto a "evaluar el volumen de la intersección entre la bola y la raqueta, y el punto P es simplemente el centro de éste volumen"... habrá colisión en dicho centro si éste, que es el punto P, se encuentra dentro de los dos, yo lo he entendido así... :P
(por cierto, Newton no se encarga por si sola de las colisiones?)
P.D. Efectivamente, Newton se encargaría de generar el mundo físico especificado, con sus entidades físicas, y de la gestión de las colisiones entre ellas. Pero digamos que, antes de pasar ya a utilizar un engine de física, quería agotar todas las posibilidades en lo que se refiere a "trastear por mí mismo" en todo lo referente a este tema. :wink: Crear algo "pequeño", como este Pong, por ejemplo, y ya subir "otro peldaño" más adelante (el peldaño de utilizar un engine de física; otros "peldaños superiores" serían game engines como Haddd, Ogre o Quest3D). :lol:
User avatar
Popolon
Usuario avanzado
Posts: 474
Joined: Tue May 13, 2003 2:31 pm
Location: Lloret de Mar
Contact:

Postby Popolon » Wed May 02, 2007 4:21 pm

Hey! Me alegro que te haya servido!! :)

No hay problema con que sea 3D, para calcular la proyección de un vector V sobre otro vector W tienes que hacer ésto (independientemente de si es 2D, 3D o nD):

1) a = V * W/norma(W) (producto escalar) <- (fíjate que en mi mensaje anterior me olvidé de dividir aquí por la norma!!! hay que hacerlo)
2) Z = a * W/norma(W)

Es decir:
1) producto escalar de V por un vector unitario en la dirección de W. Ésto nos da 'a', que es de hecho la longitud de la proyección de V sobre W
2) Pero como queremos convertir eso a un vector, simplemente multiplicamos 'a' por un vector unitario en la dirección de 'W'.

Sobre lo que propones para calcular el plano sobre el que se mueve el vector V, no lo pillo (mis mates están un poco oxidadas). Pero me parece que hay algún error, pq mira lo que pasaría si hacemos lo que propones:
1) coges un vector [0,1,0]
2) producto vectorial entre [0,1,0] y V nos da un vector w que es perpendicular a [0,1,0] y V y que tiene como longitud el área del paralelipípedo definido por [0,1,0] y V
3) Si ahora haces de nuevo el producto vectorial entre V y w, obtendrás un vector n que será perpendicular a V y w (fíjate que forzosamente tiene que ser paralelo a [0,1,0]) y que tiene como longitud el area del paralelipípedo definido por V y w

Lo que obtienes al final es un vector paralelo a [0,1,0] (es decir [0,A,0], donde A es el área que comentaba ántes). O sea que me parece que o bién yo he cometido algún error, o hay algo raro ahí :)

Bueno, pos eso, que no hay problema con que sea 3D :)
User avatar
Anderson
Usuario avanzado
Posts: 70
Joined: Sun Jan 09, 2005 9:43 pm
Contact:

Postby Anderson » Wed May 02, 2007 11:55 pm

Sobre lo que propones para calcular el plano sobre el que se mueve el vector V, no lo pillo (mis mates están un poco oxidadas). Pero me parece que hay algún error, pq mira lo que pasaría si hacemos lo que propones:
1) coges un vector [0,1,0]
2) producto vectorial entre [0,1,0] y V nos da un vector w que es perpendicular a [0,1,0] y V y que tiene como longitud el área del paralelipípedo definido por [0,1,0] y V
3) Si ahora haces de nuevo el producto vectorial entre V y w, obtendrás un vector n que será perpendicular a V y w (fíjate que forzosamente tiene que ser paralelo a [0,1,0]) y que tiene como longitud el area del paralelipípedo definido por V y w

Lo que obtienes al final es un vector paralelo a [0,1,0] (es decir [0,A,0], donde A es el área que comentaba ántes). O sea que me parece que o bién yo he cometido algún error, o hay algo raro ahí :)



¿Y si te dijera que, en el otro post que pusiste, leí "normal" en lugar de "norma"?. :lol: :lol: :lol: :lol: :lol: ¡¡¡Leñes, es que yo siempre digo "módulo"!¡¡. :P

Por eso, creí qe había que sacar "un vector normal a V" y te comenté lo de antes. :roll: De todos modos, te comento: tendrás un vector paralelo a [0,1,0] si el ángulo que forman [0,1,0] y V es 90º. :wink:

Al ser 90º, significa que V está dentro ó será paralelo a un plano (que llamaré ALPHA) cuya normal es [1,0,0]. Bajo estas circunstancias, [0,1,0] x V darán un vector W que también se encontrará dentro de ALPHA o paralelo a él. Así que el plano BETA que forman los vectores V y W será el propio ALPHA ó uno paralelo a ALPHA, por lo que. como tú muy bien dices, V x W dará un vector que será el [0,1,0] o uno paralelo a él, y la cosa no parece tener utilidad. :)

Pero si el ángulo que forman [0,1,0] y V es distinto de 90º, al hallar W vemos que el plano BETA que forman V y W... ¡ya no es paralelo a ALPHA (ni es ALPHA)!. Es otro plano distinto, que tendrá una normal que ya no será [0,1,0], y que hallaremos mediante V x W.

Este es el método que utlizábamos para, una vez hallado el vector Walk de la cámara, hallar los vectores Right y Up. Aquí V sería como el Walk, W sería como el Right ,y el vector M = V X W como el Up. 8)

En cualquier caso... gracias por la puntualización (eso me pasa, de todos modos, por no volver a consultar el libro de Geometría, ¡si es que...!). :roll:

P.D. Entre las indicaciones que me das y el hecho de que acabo de adquirir el status de "Usuario Avanzado", yo creo que lo lograré. :lol: :lol: :lol: :lol: :lol:
User avatar
addax
Administrador
Posts: 905
Joined: Mon Mar 31, 2003 10:17 pm
Location: Madrid
Contact:

Postby addax » Fri May 04, 2007 10:08 am

P.D. Entre las indicaciones que me das y el hecho de que acabo de adquirir el status de "Usuario Avanzado", yo creo que lo lograré. :lol: :lol: :lol: :lol: :lol:
Yo apuesto a que sí 8) :D
Salu2,
Alex
User avatar
Popolon
Usuario avanzado
Posts: 474
Joined: Tue May 13, 2003 2:31 pm
Location: Lloret de Mar
Contact:

Postby Popolon » Fri May 04, 2007 6:30 pm

jejeje, ok, intentaré usar "módulo" a partir de ahora, pq suena más diferente de "normal" :D

Pero bueno, yo creo que ahora que eres usuario avanzado no hay problema que se resista!

Return to “Desarrollo”

Who is online

Users browsing this forum: No registered users and 4 guests