Pergunta

I têm um objecto, que está virada para uma direcção particular com (por exemplo) um campo de 45 graus de vista, e uma gama vista limite. Eu fiz todas as verificações iniciais (nó Quadtree, e à distância), mas agora eu preciso verificar se um determinado objeto é dentro dessa visão cone, (Neste caso, para decidir apenas para seguir esse objeto se podemos vê-lo).

Além de lançar um raio para cada grau de Direction - (FieldOfView / 2) para Direction + (FieldOfView / 2) (eu estou fazendo isso no momento e é horrível), qual é a melhor maneira de fazer essa verificação visibilidade?

Foi útil?

Solução

Calcule o ângulo entre a direcção view (entendida como um vetor) eo vetor que começa em você e termina no objeto. Se ele cai sob fieldOfView / 2, você pode ver o objeto.

Esse ângulo é:

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

Outras dicas

Eu trabalhei na indústria de videogames, e eu posso dizer que fazendo funções trigonométricas como arccos cada quadro é inferior a ideal. Em vez disso, você precompute o cosseno do ângulo para o cone:

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

Em seguida, cada quadro pode consultar rapidamente se um ponto cai dentro daquele cone comparando isso com o produto do ponto do cone e o.

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;

Não há funções trigonométricas, apenas algumas multiplicação, divisão e além. A maioria dos motores de jogo tem uma função de normalizar otimizada () para vetores.

Isso funciona porque desta equação:

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

Se você normalizar os vetores (A -> An), a equação é simplificada:

An · Bn = cos(Θ)

Pegue o ângulo entre o vetor título do espectador e o vetor de espectador-alvo. Se este ângulo for menor do que (fieldOfView / 2), então o alvo é no campo do espectador de vista.

Se seus vetores são 2D ou 3D que isso vai funcionar da mesma maneira. (Em 3D, se você tem uma vista tronco em vez de cone, então você vai precisar para separar os ângulos em dois componentes.) Você só precisa encontrar o ângulo entre os dois vetores.

Se você quiser alvos de teste que são maiores do que um único ponto, você vai precisar de vários pontos para cada alvo, tais como os cantos de uma caixa delimitadora. Se o vector de espectador a qualquer um desses pontos dá um ângulo dentro do campo de visão, então que canto da caixa é visível.

Se você está fazendo 3D e pode definir o intervalo de visualização como um frustrum, então você pode usar algo semelhante a isto frustrum Culling técnica.

Boas respostas já, mas eu só queria dar-lhe um link para o blog Wolfire, que recentemente iniciou uma série de álgebra que levam o "campo de visão" equação como um exemplo. Go lê-lo , o seu bem escrito e fácil.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top