Perdón por el pobre título, pero no tenía una mejor manera de expresarlo ...
Así que hay un juego increíble de Nintendo (¡sí!) En Wii llamado WiiPlay . Hay 9 minijuegos, ¡y mi favorito se llama Tanques! . Se trata de destruir tanques enemigos COM sin que te destruyan a ti mismo. Aquí hay una captura de pantalla de un nivel:
Una forma de destruir tanques es disparando balas. Existe este tanque enemigo verde lima que dispara balas de alta velocidad que rebotan (contra las paredes y los bloques) dos veces. Puedes ver cómo el tanque del jugador puede ser destruido instantáneamente si se queda donde está ahora, ya que ese tanque de cal en el centro puede disparar una bala que sigue el camino verde que dibujé en la imagen.
Como programador aficionado, me he estado preguntando cómo puede determinar el tanque de cal en qué dirección debe disparar para golpear el tanque del jugador.
Lo pensé yo mismo, pero no se me ocurrió ningún algoritmo posible. Explicaré mis conclusiones en caso de que inspiren a alguien. Solo por simplicidad durante mi explicación, supongo que una pared es cualquier superficie contra la cual una bala puede rebotar . Un rectángulo aislado de bloques forma así cuatro paredes.
Llegué a la conclusión de que los 2 puntos en los que la bala rebota siempre se encuentran en un lado de un paralelogramo o se convierten en vértices opuestos de un paralelogramo. El tanque enemigo que dispara y el tanque del jugador al que apunta no son necesariamente los otros 2 vértices, sino que definitivamente se encuentran en las líneas colineales a cualquiera de los cuatro lados del paralelogramo. Aquí hay una ilustración de las 4 formas posibles en que se puede formar un paralelogramo:
HOR-VER significa que la bala primero golpea una pared horizontal, luego golpea una pared vertical.
Y luego estoy atascado. Pensé en moverme alrededor de una línea que conecta el tanque enemigo y el tanque del jugador alrededor del mapa para ver si forma un paralelogramo con dos golpes con cualquier muro, pero esto no siempre funciona porque el tanque enemigo y el tanque del jugador no están necesariamente coincidente con los vértices del paralelogramo.
Además, no estoy seguro del flujo general del algoritmo. ¿El algoritmo toma alguna de las siguientes 2 estructuras, o tal vez estoy equivocado con ambas?
- Siga descubriendo posibles caminos y marque siempre uno como el mejor (puede ser el más corto, el más oscuro, el más inevitable, o una evaluación combinada y ponderada basada en múltiples criterios) y olvide el resto. El que queda después de todo el cálculo es el mejor para tomar.
- Primero determine todas las paredes primero alcanzables con la bala (la bala no necesita rebotar contra ninguna otra pared para alcanzar cada una de estas paredes), luego determine todos los rangos alcanzables en cada una de estas paredes (a veces es imposible alcanzar un punto lejano en una pared sin rebote si hay otra pared cerca de usted), luego determine de nuevo todas las paredes accesibles con rebote, y todos los rangos alcanzables en estas paredes. Estos 4 procesos se pueden realizar de manera similar al trazado de rayos. Durante cada proceso, si el rayo golpea el tanque del jugador, descubra el camino de la bala de acuerdo con ese rayo.
En mi opinión, este algoritmo es difícil de entender porque:
- se puede disparar una bala en cualquier dirección; y
- hay infinitos puntos en cualquier pared, como en matemáticas, donde hay infinitos puntos en una línea.
Pero la gente de Nintendo lo logró de todos modos, así que ... ¿alguien con una idea?
fuente
Respuestas:
Dada una línea de visión directa, el problema es obviamente trivial. Sin embargo, estamos tratando con la reflexión. Descubrir adecuadamente qué partes de la escena se pueden ver es un desafío cuando se implementa la reflexión como parte de un rastreador de rayos, ya que esto podría perder algunas aberturas. Una "búsqueda binaria" entre dos ángulos prometedores tampoco es viable: debido a los reflejos, el espacio realmente visible no es continuo, por lo que la heurística "si está a la derecha de A y a la izquierda de B, debe haber un objetivo la solución entre A y B " no está permitida , y perderá soluciones" creativas ". En cambio, recomendaría implementar la reflexión volviendo a ejecutar el trazador desde una posición virtual, la posición donde parece estar nuestro tanque de disparo cuando se ve en el espejo:
La ventaja es que el rayo reflejado es ahora una línea recta que se origina en la posición virtual. Traté de ilustrar la técnica en el siguiente boceto:
X marca la posición de disparo, (X) el objetivo. Las áreas coloreadas son visibles.
Línea de visión directa: el objetivo no es visible. Sin embargo, podemos golpear las superficies (1) y (2).
Una reflexión Hay dos posiciones de disparo virtuales dentro de los obstáculos. La posición inferior tiene LOS directo al objetivo, por lo que tenemos nuestra primera solución de disparo: la trayectoria de la bala es la parte del rayo entre el objetivo y la superficie del espejo inferior, y entre el punto de colisión del espejo y la posición de disparo real.
Dos reflexiones: la posición virtual superior desde la primera reflexión puede ver parte del obstáculo inferior a través de la superficie del espejo. Como se permiten dos reflexiones, podemos reflejar esta posición en el obstáculo inferior. Las posiciones están marcadas como (I) la posición real, (II) la posición virtual desde la primera reflexión, y (III) la posición virtual desde la segunda reflexión.
Desde (III), tenemos LOS directo al objetivo (X), por lo que hemos encontrado otra solución de disparo. La trayectoria de la bala es a lo largo de la línea X – III hasta el segundo punto de colisión del espejo, luego a lo largo de la línea III – II entre los puntos de colisión del espejo, y finalmente a lo largo de la línea II – I desde el primer punto de colisión del espejo hasta la posición real I.
En realidad, la posición virtual inferior desde la primera reflexión también podría reflejarse en el obstáculo superior, pero esto no conducirá a ninguna solución directa.
Una vez que pueda averiguar qué partes de los obstáculos son visibles (y, por lo tanto, se pueden usar para reflejar la bala), la implementación de la duplicación a través de una búsqueda de profundidad parecería sencilla. Para encontrar superficies de espejo adecuadas, se pueden usar las técnicas descritas en Nicky Case's Sight & Light : en lugar de probar 360 vectores, que pueden perder aberturas y también es un desperdicio, lanzamos rayos solo al borde de los obstáculos.
fuente
Simplemente extendiendo la idea de Karl Bielefeldt para reflexiones de 2 paredes:
A y B se dan (los tanques). Primero debe enumerar todos los muros que A puede ver y una lista de todos los muros que B puede ver. Luego haces parejas donde la primera pared está en la lista de puños y la segunda pared es diferente de la primera pared y está en la segunda lista. Debe realizar esta prueba para todos los pares de paredes posibles (a menos que encuentre una manera de eliminar candidatos). Una vez que encuentre R y S para un par de paredes determinado, verifique
1) si A tiene visión directa de R
2) si R pertenece al muro1 (el muro es solo un segmento, no toda la línea)
3) si R tiene acceso directo a S
4) si S pertenece a wall2 (la pared es solo un segmento, no toda la línea)
5) si S tiene acceso directo a B.
Para encontrar R y S : Dado que conoce wall1, puede determinar la ecuación de línea tangente a wall1, ya que R pertenece a la línea tangente a wall 1, tiene una relación entre las 2 coordenadas de R (que termina con un grado de libertad para R) De manera similar a S (tiene una relación entre las coordenadas S ya que este punto pertenece a la línea tanget con wall2). Entonces ahora tiene 2 grados de libertad y debe tener 2 ecuaciones independientes adicionales para determinar una solución. Una ecuación es:
la otra ecuación es:
Observe que en las ecuaciones anteriores A, A ', B, B' son conocidas o pueden calcularse directamente. R 'y S' son función de las coordenadas de R y S y las ecuaciones de la pared. No terminé las matemáticas, así que no sé cómo se verán las ecuaciones.
fuente
Puede aprovechar el hecho de que el ángulo que sale del rebote debe ser el mismo que el ángulo que ingresa. Para una pared horizontal dada con coordenada
c
y y dos tanques fijos con coordenadas(a,b)
y(d,e)
, solo hay un ángulo que satisface la ecuación a continuación.Simplemente resuelva para
x
obtener la distancia a lo largo de la pared a la que debe apuntar. Dos paredes funcionan igual. Solo tienes dos ecuaciones y dos incógnitas.fuente
Tiene diagramas claros que muestran cómo dirigir los rayos, por lo que dejaré los detalles sobre cómo determinar un par de superficies reflectantes.
Vamos a llamar a la superficie que debe ser golpeado primera superficie A , y la segunda, B .
Trate de golpear los bordes (visibles) de B al disparar contra una . En otras palabras, determine los puntos donde uno vería reflejos de los extremos de B si mirara el espejo A terminado . Esto debe ser fácil de hacer, solo tiene que manejar un punto de reflexión.
Ahora usted sabe dos rayos que golpean los bordes (visibles) de B . Llamémosles rayos extremos Calcule sus reflexiones en B; deben ir a algún lugar más allá de tu objetivo. Puede determinar si el objetivo se encuentra entre ellos, es decir, a la izquierda de un rayo pero a la derecha del otro, o viceversa. Esto es trivial si se usa la ecuación general de la línea recta .
Si el objetivo no está entre los rayos del borde, obviamente no puedes golpearlo con ningún rayo intermedio; elige otro par de superficies.
Si el objetivo está entre los rayos, busque el rayo de impacto intermedio mediante búsqueda binaria. Tienes dos ángulos de disparo correspondientes a los rayos del borde, tu ángulo de golpe se encuentra entre ellos. Siempre que el diámetro angular de su objetivo, como se ve desde el punto de disparo, no sea excesivamente pequeño, necesitará pocas iteraciones hasta que encuentre la dirección de un rayo de golpe.
Aquí hay una foto:
Aquí los dos rayos del borde se muestran en rojo y azul. Aparentemente puedes encontrar un rayo emitido en un ángulo más pequeño que el rojo pero mayor que el rojo para que ese rayo llegue al objetivo verde.
fuente
En primer lugar, ¿recuerdas en la clase de física cuando hablaste sobre la refracción de la luz? Bueno, su problema puede resolverse utilizando esos principios. El ángulo de incidencia es igual al ángulo de reflexión. por lo que el tanque enemigo debe atravesar todos los ángulos posibles para el primer rebote para que el segundo rebote pueda golpear al jugador. Sigue con la idea del trazado de rayos también. Ahora, esto se complica cuando el jugador se está moviendo, pero debería ser una buena idea comenzar un algoritmo
fuente