Actualmente estoy escribiendo una simulación 2D AI, pero no estoy completamente seguro de cómo verificar si la posición de un agente está dentro del campo de visión de otro.
Actualmente, mi partición mundial es una partición simple de espacio celular (una cuadrícula). Quiero usar un triángulo para representar el campo de visión, pero ¿cómo puedo calcular las celdas que se cruzan con el triángulo?
Similar a esta imagen:
Las áreas rojas son las celdas que quiero calcular, verificando si el triángulo interseca esas celdas.
Gracias por adelantado.
EDITAR:
Solo para agregar a la confusión (o tal vez incluso hacerlo más fácil). Cada celda tiene un vector min y max donde min es la esquina inferior izquierda y max es la esquina superior derecha.
collision-detection
intersection
Ray Dey
fuente
fuente
Respuestas:
Calcule las tres esquinas de su triángulo fov, gírelas para que estén orientadas de la manera correcta y tal, y luego haga una de:
1) haz una prueba de punto en triángulo para todos los objetivos potenciales
2) calcule el cuadro delimitador de este triángulo y realice una prueba de punto en triángulo para todos los objetivos potenciales en las celdas en este cuadro delimitador; este será un código muy sencillo para depurar
Un enfoque similar es usar un quadtree en lugar de una cuadrícula y hacer las intersecciones en eso. Si el acceso al mosaico O (1) lo está acelerando, simplemente probar todas las celdas en los límites del triángulo fov en el triángulo debería ser tan rápido como instantáneo. Como está buscando otras opciones, supongo que no lo es y que el O (1) en realidad está tomando un costo masivo de pérdida de caché mientras agota su caché. Por supuesto, podría mirar las instrucciones de captación previa para anotar su paseo de caja delimitador con ...
3) 'rasterice' este triángulo y verifique las celdas que 'pinta', probablemente el código más eficiente, pero tal vez solo marginalmente, ya que especularía que todo está dominado por los tiempos de pérdida de caché y depende de cuán complejas sean sus celdas y cuán ocupadas son.
Un enfoque alternativo es representar el FOV en un mapa de bits fuera de la pantalla y luego leer el valor de píxel para cada uno de sus objetos; no se puede 'desmezclar pintura' pero con un número limitado de objetos y al elegir cuidadosamente su pintura se puede deducir quién vio a quién. Este enfoque es similar a la cantidad de juegos en los que el usuario hizo clic: dibujan la escena fuera de la pantalla usando colores sólidos para las áreas de impacto. Las GPU son muy rápidas en el llenado de triángulos ...
fuente
La solución canónica en los renderizadores de software (que deben hacer este algoritmo exacto cada vez que rasterizan un triángulo) es, creo, escanear el triángulo una fila de píxeles a la vez. Los bordes izquierdo y derecho de cada fila se calculan caminando por los lados del triángulo con Bresenham , y luego se completa la fila entre ellos.
Estoy pasando por alto muchos detalles, pero esa es la idea básica. Si busca "renderizado de software" y "rasterización de triángulo", probablemente encontrará más detalles. Este es un problema bien resuelto. Su tarjeta gráfica está haciendo esto millones de veces por marco.
Si desea una solución más específica para roguelike, así es como implementé FOV en la mía. Parece que funciona bastante rápido. Es esencialmente un simple lanzador de sombras, trabajando en octantes a la vez, escaneando hacia afuera desde el reproductor.
fuente
Estoy usando una variación del algoritmo scanline para resolver exactamente el mismo problema. Comencé clasificando los tres puntos triangulares por su altura. Luego, básicamente verifico si dos bordes están a la izquierda o a la derecha. Para el lado con dos bordes, debe marcar la fila donde cambia qué borde delimita sus filas. Para el lado con un borde, siempre puedes usar eso.
Entonces, para cada fila, sé qué dos bordes la delimitan, y puedo calcular los límites superior e inferior en la dirección x. Suena bastante complicado, pero se condensa en solo unas pocas líneas de código. ¡Asegúrese de manejar el caso especial donde un borde está completamente horizontal!
fuente
¿Qué tal mantener un rango de columnas para cada fila que están en el triángulo? Lo que puede hacer es establecer la columna mínima y máxima para cada fila donde se encuentra cada punto, y donde cada línea de triángulo cruza una línea de separación de fila horizontal.
Salida:
fuente
Hay un trabajo de algoritmo realizado en la comunidad roguelike que se ocupa de FOV / LOS / iluminación en un mundo basado en mosaicos.
Quizás pueda encontrar algo en esta página que pueda usar para ayudar a resolver su problema: http://roguebasin.roguelikedevelopment.org/index.php?title=Field_of_Vision
Específicamente, el "FOV permisivo" podría ser el más aplicable a su situación.
fuente