Pregunta

Tengo un objeto, que se enfrenta a una dirección particular con (por ejemplo) un campo de visión de 45 grados y un rango de visión límite. He realizado todas las comprobaciones iniciales (nodo Quadtree y distancia), pero ahora necesito verificar si un objeto en particular está dentro de ese cono de vista (en este caso, decidir si seguir ese objeto solo si podemos verlo).

Además de lanzar un rayo para cada grado desde Dirección - (FieldOfView / 2) a Direction + (FieldOfView / 2) (lo estoy haciendo en este momento y es horrible), ¿cuál es la mejor manera de hacer esta verificación de visibilidad?

¿Fue útil?

Solución

Calcule el ángulo entre la dirección de su vista (entendida como un vector) y el vector que comienza en usted y termina en el objeto. Si se encuentra en FieldOfView / 2, puede ver el objeto.

Ese ángulo es:

arccos(scalarProduct(viewDirection, (object - you)) / (norm(viewDirection)*norm(object - you))).

Otros consejos

He trabajado en la industria de los videojuegos, y puedo decir que hacer funciones trigonométricas como arccos en cada cuadro es menos que ideal. En su lugar, calcula previamente el coseno del ángulo para el cono:

float cos_angle = cos(PI/4); // 45 degrees, for example

Luego, puede comprobar rápidamente cada cuadro si un punto cae dentro de ese cono comparándolo con el producto de punto del cono y el.

vector test_point_vector = normalize(test_point_loc - cone_origin);
float dot_product = dot(normalized_cone_vector, text_point_vector);
bool inside_code = dot_product > cos_angle;

No hay funciones trigonométricas, solo algunas multiplicaciones, divisiones y sumas. La mayoría de los motores de juego tienen una función normalizada () optimizada para vectores.

Esto funciona debido a esta ecuación:

A · B = |A| * |B| * cos(Θ)

Si normaliza los vectores (A - > An), la ecuación se simplifica:

An · Bn = cos(Θ)

Obtenga el ángulo entre el vector de rumbo del espectador y el vector del espectador al objetivo. Si ese ángulo es menor que (FieldOfView / 2), entonces el objetivo está en el campo de visión del espectador.

Si sus vectores son 2d o 3d, esto funcionará de la misma manera. (En 3D, si tiene una vista frustum en lugar de cono, entonces necesitará separar los ángulos en dos componentes). Solo necesita encontrar el ángulo entre los dos vectores.

Si desea probar objetivos que son más grandes que un solo punto, necesitará varios puntos para cada objetivo, como las esquinas de un cuadro delimitador. Si el vector del espectador a cualquiera de estos puntos da un ángulo dentro del campo de visión, entonces esa esquina del cuadro es visible.

Si está haciendo 3D y puede definir el rango de visualización como un frustrum, entonces puede usar algo similar a esto técnica de Frustrum Culling .

Buenas respuestas ya, pero solo quería darte un enlace al blog de Wolfire, recientemente comenzaron una serie de álgebra que toma el campo de visión " ecuación como un ejemplo. Ve a leerlo , es Bien escrito y fácil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top