Frage

Ich habe ein Objekt, das heißt eine bestimmte Richtung gerichtet mit (zum Beispiel) ein 45-Grad-Sichtfeld und ein Grenzsichtbereich. Ich habe alle anfänglichen Prüfungen (Quadtree Knoten und Distanz) getan, aber jetzt muss ich überprüfen, ob ein bestimmtes Objekt innerhalb dieser Sichtkegel ist, (in diesem Fall nur zu entscheiden, das Objekt zu folgen, wenn wir es sehen können).

Neben einen Strahl für jeden Grad von Direction - (FieldOfView / 2) vom Gießen bis Direction + (FieldOfView / 2) (ich tue, dass der Moment an, und es ist schrecklich), was der beste Weg ist, diese Sichtbarkeit Prüfung zu tun?

War es hilfreich?

Lösung

Berechnen Sie den Winkel zwischen Blickrichtung (als Vektor verstanden) und der Vektor, der an Sie beginnt und endet im Objekt vorhanden. Wenn es unter fieldOfView fällt / 2, können Sie das Objekt anzuzeigen.

Dieser Winkel ist:

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

Andere Tipps

Ich habe in der Videospiel-Industrie gearbeitet, und ich kann sagen, dass wie arccos trigonometrische Funktionen macht jeden Rahmen ist weniger als ideal. Stattdessen Sie precompute den Kosinus des Winkels für den Kegel:

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

Dann wird jeder Frame können Sie schnell überprüfen, ob ein Punkt innerhalb dieses Kegels fällt durch den Vergleich, dass mit dem Punktprodukt des Kegels und die.

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;

Es gibt keine trigonometrischen Funktionen, um nur einige Multiplikation, Division und Addition. Die meisten Spiele-Engines haben eine optimierte normalize () Funktion für Vektoren.

Das funktioniert, weil diese Gleichung:

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

Wenn Sie die Vektoren zu normalisieren (A -> An) wird die Gleichung vereinfacht:

An · Bn = cos(Θ)

Erhalten Sie den Winkel zwischen dem Fahrtrichtungsvektor des Betrachters und dem Vektor von Betrachter zu zielen. Wenn dieser Winkel kleiner als (fieldOfView / 2), dann ist das Ziel im Blickfeld des Betrachters aus gesehen.

Wenn Sie Ihre Vektoren 2D oder 3D sind, werden diese auf die gleiche Weise arbeiten. (In 3D, wenn Sie eine Ansicht Stumpfes statt Kegel haben, dann werden Sie die Winkel in zwei Komponenten trennen müssen.) Sie müssen nur den Winkel zwischen den beiden Vektoren finden.

Wenn Sie Ziele testen wollen, als einen einzigen Punkt größer sind, werden Sie mehrere Punkte für jedes Ziel, wie die Ecken eines Begrenzungsrahmens müssen. Wenn der Vektor von Betrachter zu einem dieser Punkte einen Winkel innerhalb des Sichtfeldes gibt, dann, dass Ecke des Kastens sichtbar ist.

Wenn Sie 3D tun und kann den Sichtbereich als frustrum definieren, dann können Sie etwas Ähnliches wie diese Frustrum Culling Technik.

Gute Antworten schon, aber ich wollte Ihnen nur einen Link zu dem Wolfire Blog geben, begann sie vor kurzem eine Algebra-Serie, die das „Sichtfeld“ nimmt Gleichung als ein Beispiel. Gehen Sie es lesen , seine gut geschrieben und leicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top