Línea de visión diagonal con dos esquinas.

9

En este momento estoy usando el algoritmo de línea de Bresenham para la línea de visión. El problema es que he encontrado un caso de borde donde los jugadores pueden mirar a través de las paredes. Ocurre cuando el jugador mira entre dos esquinas de una pared con un espacio en el otro lado en ángulos específicos.

Estuche de borde de línea de visión

El resultado que quiero es que el mosaico entre dos paredes se marque como no válido.

Resultado deseado

¿Cuál es la forma más rápida de modificar el algoritmo de línea de Bresenham para resolver esto? Si no hay una buena solución, ¿hay un algoritmo más adecuado? Cualquier idea es bienvenida. Tenga en cuenta que la solución también debe ser compatible con 3d.

Editar: Mi solución simple fue verificar si ambas esquinas están cerradas cuando cambian las coordenadas x e y de una línea. Para ver el código fuente de trabajo y una demostración interactiva del producto completo, consulte http://ashblue.github.io/javascript-pathfinding/

Azul ceniza
fuente
2
¿Hay alguna diferencia si cambias el punto de inicio y final? Quizás entonces podría aceptar los resultados si ambos cálculos devuelven una línea de visión no obstruida. También puede encontrar algunos de los artículos de LOS útiles en RogueBasin.
thalador
1
De cualquier manera, esos dos bloques negros diagonales en 4-5 no están conectados a una pared en primer lugar, y lo digo porque implícitamente estás permitiendo el movimiento diagonal. Debes cuadrar esa diagonal para convertirla en un muro contiguo o hacer que tu caminante de línea cuadre sus movimientos diagonales en lugar de ir puramente diagonal como 2-3 y 4-5.
Patrick Hughes
Voltearlo parecía una buena idea, pero no resuelve el problema. Lo único que se me ocurre es verificar y ver si una de las dos esquinas está vacía. Aunque parece caro.
Ash Blue
55
"Parece caro" nunca es suficiente justificación para no intentar algo. "Será demasiado caro" en general, suponiendo que pueda probar que algo será demasiado lento.
Mokosha
3
El único cambio al algoritmo requerido es que si X e Y cambian en el mismo paso, primero cambien X y luego Y, esto eliminaría las diagonales por completo.
Patrick Hughes

Respuestas:

7

Eric Lippert escribió una excelente serie sobre la generación de la línea de visión en C # con Shadow Casting en una cuadrícula plana rectangular.

Entre otras cuestiones, Eric se ocupó de varias preguntas que deben responderse sobre los requisitos de la línea de visión, que dan resultados diferentes y dan ejemplos de un par de resultados diferentes. Uno de los artículos trata en profundidad la circunstancia de "mirar a la vuelta de la esquina" que ocurrió en una versión temprana de su algoritmo.

He adaptado el algoritmo de Eric a una cuadrícula hexagonal aquí , y lo utilicé con éxito en grandes cuadrículas hexagonales (> 400 x 700) con un radio de visibilidad extenso (> 60 hexes). Esta implementación calcula y muestra el campo de visión completo tan rápido como puedo parpadear, usando una sola CPU i7. Esto es sin duda lo suficientemente rápido para cualquier uso que espero utilizar.

Actualización : línea de visión con elevación:
la implementación de cuadrícula hexagonal vinculada a la anterior calcula la línea de visión con elevación, no solo obstáculos. Las notas de documentación también analizan una decisión adicional que debe tomarse con respecto a los cálculos de elevación: la altura del objetivo y la altura del observador. La selección predeterminada es hacer que ambos sean iguales, lo que crea un campo de visión simétrico, pero también se puede seleccionar tierra a tierra y ojos de observador a tierra. (El código es de código abierto bajo licencia MIT)

Pieter Geerkens
fuente
Realmente estoy cavando Shadow Casting, pero me he encontrado con un problema. Tener problemas para encontrar información sobre cómo escalar el algoritmo para operar con un eje z. Lamento mencionar esto, pero ¿tiene algún recurso sugerido para que funcione en 3D?
Ash Blue
@AshBlue: ver el apéndice arriba
Pieter Geerkens
Estoy mirando tu base de código. Tiene cosas geniales, pero parece que no encuentro un algoritmo de dibujo lineal similar a Bresenham adaptado a hexes. ¿Lo haces con LOS?
MLProgrammer-CiM
@EfEs: FieldOfView es el objeto devuelto; ShadowCastingFov * .cs genera el campo de visión al proyectar sombras. Si tiene preguntas específicas sobre el código, es mejor hacerlas en la sección Discusiones del sitio; preguntas más generales que estoy feliz de responder aquí.
Pieter Geerkens
@PieterGeerkens Puede encontrar la pregunta aquí gamedev.stackexchange.com/questions/57087/…
MLProgrammer-CiM
1

¿Qué pasa si para el cálculo de LOS tiene una cuadrícula separada de "mayor resolución" que llena los espacios en las esquinas? Estaba pensando en algo como esto:

ingrese la descripción de la imagen aquí

La izquierda es la sección del bloque original de 4 cuadrados.

La derecha es la versión de "alta resolución", ya que puede ver que cada cuadrado original se subdividió en cuartos y se ha llenado una de las esquinas. No estoy seguro de que el algoritmo genere eso, pero puede calcularse previamente del mapa actual

Significa que el espacio de coordenadas se cuadruplica pero no imagino que sea un problema de rendimiento significativo.

Davy8
fuente
Estoy bastante seguro de que la resolución más alta se vería exactamente igual que la original. Al dividir una cuadrícula en una cuadrícula más pequeña, obtienes la misma representación visual, solo que con una cuadrícula más pequeña. Cada cuadrado solo se convierte en 4 cuadrados más pequeños en el mismo lugar.
MichaelHouse
@ Byte56 Correcto, quise decir que se aplicaría una lógica adicional después de dividirla para agregar los bloques adicionales a esa copia. La lógica para hacerlo es un ejercicio que le queda al lector.
Davy8
Puede generar fácilmente la cuadrícula de alta resolución difuminando el original. Luego defina un umbral de, digamos, 0.5para que las celdas de alta resolución se llenen o no. Por lo tanto, usar una cuadrícula de alta resolución me parece bastante hacky.
danijar