PiR2
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.

Determinando se está no campo de visão

2 participantes

Ir para baixo

Determinando se está no campo de visão Empty Determinando se está no campo de visão

Mensagem por PedroX Dom 25 Fev 2018, 21:30

Recentemente um amigo me perguntou sobre um problema no código que ele estava desenvolvendo. Depois de ajudar com a solução do problema resolvi compartilhar o código (que foi idealizado por ele e modificado por mim), que deixei numa linguagem facilmente adaptável às populares linguagens de programação, especialmente C/C++ e Javascript. Antes que eu me esqueça, o código é livre para uso.

A ilustração abaixo mostra mais ou menos do que trata o código:
Determinando se está no campo de visão Ilustra_o

O ponto de onde partem as três linhas seria um jogador. Os círculos representam possíveis alvos. O código verifica se estes estão no campo de visão dele. As linhas preta e azul representam os limites do campo de visão, esquerdo e direito respectivamente. A linha vermelha é o ângulo central, matematicamente é a média dos outros dois. Todos os ângulos são tratados como respeitando a condição 0<=angulo<360.

Como se pode observar na imagem, os círculos verde e laranja estão no campo de visão do jogador. O círculo azul se encontra fora.

Em uma certa faixa de ângulos, não haveria nenhuma dificuldade em determinar se o alvo está no campo de visão do jogador. Bastaria verificar se o alvo está numa direção que seja maior que o limite direito e menor que o limite esquerdo, adotando os ângulos no sentido anti-horário. Porém, visto que os ângulos "reiniciam" em 360, surge um problema. A linha tracejada representa 0º. O círculo laranja representa essa condição problemática. Ele está num ângulo maior que o limite direito, porém, maior que o limite esquerdo também.

A solução é o código abaixo (comentários vem depois de // e são ignorados no código):

Primeira parte: Definição das variáveis
Código:
arco = 120; // 0<arco<=360 graus (é o campo de visão)
meio_arco = 0.5*arco;
angulo_visao = algumvalor; // este valor é variável, depende de onde o jogador está olhando
direcao_alvo = direcao_jogador_alvo(); // o código deve calcular essa direção previamente
angulo_direita = (angulo_visao + meio_arco) % 360; // em que % é a operação resto da divisão
angulo_esquerda = (angulo_visao - meio_arco + 360) % 360; // soma-se 360 para garantir que o número seja um ângulo positivo

Segunda parte: Determinando se está visível
Código:
if (angulo_visao >= meio_arco && angulo_visao < (360-meio_arco)){
    if (direcao_alvo >= angulo_direita && direcao_alvo <= angulo_esquerda)
         visivel = true;
}else{
     visivel = (direcao_alvo <= angulo_esquerda || direcao_alvo >= angulo_direita);
}

Alternativamente, usando "tabelas verdades", podemos simplificar a segunda parte até chegar a uma única expressão:
Código:
visivel = ( (direcao_alvo >= angulo_direita) + (direcao_alvo <= angulo_esquerda) + (angulo_visao < meio_arco ||  (angulo_visao >= (360-meio_arco))) ) >= 2;
Neste caso a linguagem de programação deve tratar true como 1 e false como 0.

O código final ficaria:
Código:
arco = 120; // 0<arco<=360 graus (é o campo de visão)
meio_arco = 0.5*arco;
angulo_visao = algumvalor; // este valor é variável, depende de onde o jogador está olhando
direcao_alvo = direcao_jogador_alvo(); // o código deve calcular essa direção previamente
angulo_direita = (angulo_visao + meio_arco) % 360; // em que % é a operação resto da divisão
angulo_esquerda = (angulo_visao - meio_arco + 360) % 360; // soma-se 360 para garantir que o número seja um ângulo positivo

visivel = ( (direcao_alvo >= angulo_direita) + (direcao_alvo <= angulo_esquerda) + (angulo_visao < meio_arco ||  (angulo_visao >= (360-meio_arco))) ) >= 2;

Informações adicionais

- % é um operador que em algumas linguagens é mod, e é igual ao resto da divisão do termo da esquerda pelo da direita

- Variáveis que devem ser notadas:
arco é uma variável de escolha do desenvolvedor e representa o campo de visão do jogador em graus
angulo_visao é uma variável que representa o ângulo médio do campo de visão do jogador, geralmente ela muda conforme o jogador muda a direção da sua visão
direcao_alvo é uma variável que deve mudar conforme a direção entre o jogador e o alvo, no caso você pode criar uma função para isso
PedroX
PedroX
Administração
Administração

Mensagens : 1040
Data de inscrição : 24/08/2011
Idade : 28
Localização : Campinas - SP

Ir para o topo Ir para baixo

Determinando se está no campo de visão Empty Re: Determinando se está no campo de visão

Mensagem por Dotted Chaos Seg 26 Fev 2018, 10:00

Tudo bom pessoal, meu nome é Fábio e sou o amigo que o PedroX citou acima.

Fiz uma implementação desse mecanismo usando o Pico-8 pra ilustrar legal o funcionamento:

http://campo-visao.bitballoon.com

Setas movem o "personagem" e teclas Z X giram o campo de visão.

Dotted Chaos
Iniciante

Mensagens : 1
Data de inscrição : 13/01/2018
Idade : 32
Localização : SP

Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos