Domanda

Ho un oggetto, che è rivolto verso una direzione particolare con (per esempio) un campo visivo di 45 gradi e un intervallo di vista limite. Ho eseguito tutti i controlli iniziali (nodo Quadtree e distanza), ma ora ho bisogno di verificare se un particolare oggetto si trova all'interno di quel cono di vista (in questo caso, decido di seguire quell'oggetto solo se possiamo vederlo).

Oltre a lanciare un raggio per ogni grado da Direction - (FieldOfView / 2) a Direction + (FieldOfView / 2) (lo sto facendo al momento e è orribile), qual è il modo migliore per eseguire questo controllo di visibilità?

È stato utile?

Soluzione

Calcola l'angolo tra la direzione della tua vista (inteso come un vettore) e il vettore che inizia verso di te e termina sull'oggetto. Se rientra in FieldOfView / 2, puoi visualizzare l'oggetto.

Quell'angolo è:

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

Altri suggerimenti

Ho lavorato nel settore dei videogiochi e posso dire che fare trig come arccos ogni fotogramma è meno che ideale. Invece, pre-calcoli il coseno dell'angolo per il cono:

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

Quindi, ogni frame è possibile verificare rapidamente se un punto cade all'interno di quel cono confrontandolo con il prodotto punto del cono e il

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;

Non ci sono funzioni di attivazione, ma solo alcune funzioni di moltiplicazione, divisione e aggiunta. La maggior parte dei motori di gioco ha una funzione normalize () ottimizzata per i vettori.

Funziona a causa di questa equazione:

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

Se normalizzi i vettori (A - > An), l'equazione è semplificata:

An · Bn = cos(Θ)

Ottieni l'angolo tra il vettore di intestazione dello spettatore e il vettore dallo spettatore alla destinazione. Se tale angolo è inferiore a (FieldOfView / 2), la destinazione si trova nel campo visivo dello spettatore.

Se i tuoi vettori sono 2d o 3d funzionerà allo stesso modo. (In 3D, se hai una vista frustum anziché un cono, dovrai separare gli angoli in due componenti.) Devi solo trovare l'angolo tra i due vettori.

Se vuoi testare bersagli che sono più grandi di un singolo punto, avrai bisogno di più punti per ogni bersaglio, come gli angoli di un rettangolo di selezione. Se il vettore dal visualizzatore a uno di questi punti fornisce un angolo all'interno del campo visivo, allora quell'angolo del riquadro è visibile.

Se stai facendo 3D e puoi definire l'intervallo di visualizzazione come un errore, puoi usare qualcosa di simile a questo tecnica Frustrum Culling .

Buone risposte già, ma volevo solo darti un link al blog Wolfire, hanno recentemente iniziato una serie di algebra che prende il "campo visivo" equazione come esempio. Vai a leggere , è ben scritto e facile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top