Question

J'ai un objet qui fait face à une direction particulière avec (par exemple) un champ de vision de 45 degrés et une plage de vue limite. J'ai effectué toutes les vérifications initiales (nœud Quadtree, et distance), mais je dois maintenant vérifier si un objet particulier se trouve dans ce cône de vue (dans ce cas, décidez de ne suivre que cet objet si nous pouvons le voir).

Hormis le fait de lancer un rayon pour chaque degré de Direction - (FieldOfView / 2) à Direction + (FieldOfView / 2) (je le fais pour le moment et c'est horrible), quelle est la meilleure façon de faire cette vérification de visibilité?

Était-ce utile?

La solution

Calculez l'angle entre votre direction de la vue (comprise comme un vecteur) et le vecteur qui commence par vous et se termine par l'objet. S'il se trouve dans FieldOfView / 2, vous pouvez afficher l'objet.

Cet angle est:

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

Autres conseils

J'ai travaillé dans l'industrie du jeu vidéo, et je peux dire que faire des fonctions de trigonométrie comme arccos chaque image est loin d'être idéal. Au lieu de cela, vous calculez à l'avance le cosinus de l'angle du cône:

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

Ensuite, chaque cadre, vous pouvez rapidement vérifier si un point tombe à l'intérieur de ce cône en le comparant au produit scalaire du cône et du.

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;

Il n’existe pas de fonctions trigonométriques, juste une certaine multiplication, division et addition. La plupart des moteurs de jeu ont une fonction normalisée () optimisée pour les vecteurs.

Cela fonctionne à cause de cette équation:

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

Si vous normalisez les vecteurs (A - & An), l'équation est simplifiée:

An · Bn = cos(Θ)

Obtenir l'angle entre le vecteur de titre du spectateur et le vecteur de spectateur à la cible. Si cet angle est inférieur à (FieldOfView / 2), la cible se trouve dans le champ de vision du visualiseur.

Si vos vecteurs sont 2D ou 3D, cela fonctionnera de la même manière. (En 3D, si vous avez un tronc de vue au lieu d'un cône, vous devez séparer les angles en deux composants.) Il vous suffit de trouver l'angle entre les deux vecteurs.

Si vous souhaitez tester des cibles supérieures à un seul point, vous aurez besoin de plusieurs points pour chaque cible, tels que les coins d'un cadre de sélection. Si le vecteur du spectateur vers l’un de ces points donne un angle à l’intérieur du champ de vision, ce coin de la boîte est visible.

Si vous faites de la 3D et pouvez définir la plage de visualisation comme une frustration, vous pouvez utiliser quelque chose de similaire à ceci Frustrum Culling .

Déjà de bonnes réponses, mais je voulais juste vous donner un lien vers le blog de Wolfire. Ils ont récemment lancé une série d'algèbre prenant le "champ de vision". équation à titre d'exemple. Allez le lire , son bien écrit et facile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top