Estou trabalhando em algum movimento AI onde não há obstáculos e o movimento é restrito ao plano XY. Estou calculando dois vetores, v , a direção oposta do navio 1 ew , o vetor apontando da posição do navio 1 para o navio 2.
Estou então calculando o ângulo entre esses dois vetores usando a fórmula
arccos((v · w) / (|v| · |w|))
O problema que estou tendo é que arccos
apenas retorna valores entre 0 ° e 180 °. Isso torna impossível determinar se devo virar à esquerda ou à direita para enfrentar o outro navio.
Existe uma maneira melhor de fazer isso?
Mathf.DeltaAngle()
.Respostas:
É muito mais rápido usar um produto cruzado 2D. Nenhuma função trigonométrica dispendiosa envolvida.
Se você ainda precisa dos ângulos reais, recomendo o uso
atan2
.atan2
lhe dará o ângulo absoluto de qualquer vetor. Para obter o ângulo relativo entre qualquer vetor, calcule seus ângulos absolutos e use subtração simples.fonte
arccos
. Dessa forma, você usará apenas uma função trigonométrica, mas ainda terá o ângulo real. No entanto, recomendo essa otimização até ter certeza de que o rastreamento do ângulo da IA está causando um impacto notável no desempenho do seu jogo.if( cross == -0.0f )
vsif( cross == 0.0f )
parece extremamente frágil.Use arcsin do produto cruzado 2D (ou seja, o componente z do vetor produto cruzado). Isso lhe dará de 90 a 90, o que permitirá saber se você deve ir para a esquerda ou direita.
Tenha cuidado porque A cruz B não é igual a B cruz A.
Outra estratégia (mas provavelmente não tão direta) é calcular o "cabeçalho" dos dois vetores usando atan2 e depois descobrir se A apontando para graus X precisa ir para a esquerda ou direita para ir para B apontando para graus y.
fonte
Use vetores para redirecionar o navio. É assim que os "comportamentos de direção" funcionam - você nunca precisa calcular o ângulo, basta usar os vetores que possui. Isso é computacionalmente muito mais barato.
O vetor
w
(vetor do navio 1 ao navio 2) é toda a informação que você precisa. Modifique o vetor de velocidade do navio 1 ou o vetor de aceleração do navio 1 (ou mesmo o vetor de cabeçalho diretamente) usando uma versão ponderada dew
.A magnitude de quão longe o navio 1 está fora do rumo (o quanto v não combina com w) pode ser encontrada usando (
1 - dot(v,w)
)dot(v,w)
é maximizado quandov
ew
alinhado exatamente)1 - dot(v,w)
) fornece 0 quandov
ew
está completamente alinhado, fornecidov
ew
normalizado)fonte
Existe uma maneira simples de encontrar o ângulo absoluto de um vetor através da geometria normal.
por exemplo vetor V = 2i - 3j;
valor absoluto de x coeficiente = 2;
valor absoluto de coeficiente y = 3;
ângulo = atan (2/3); [o ângulo estará entre 0 e 90]
Com base no ângulo do quadrante será alterado.
se (coeficiente x <0 e coeficiente y> 0) então ângulo = ângulo 180;
se (coeficiente x <0 e coeficiente y <0) então ângulo = 180 + ângulo;
se (coeficiente x> 0 e coeficiente y <0) então ângulo = ângulo de 360;
se (coeficiente x> 0 e coeficiente y> 0) então ângulo = ângulo;
depois de encontrar o ângulo do primeiro e do segundo vetores, basta subtrair o ângulo do primeiro vetor do segundo vetor. Então você obterá um ângulo absoluto entre dois vetores.
fonte
Talvez eu deva postar uma pergunta um pouco diferente e responder a mim mesma; esta é a pergunta mais próxima que eu poderia encontrar da que eu tinha.
Estou fazendo um trabalho 2D na tela html, onde tenho ângulos de rotação em radianos em vez de vetores. Eu precisava do "ângulo de virada" (ta) para ir do "cabeçalho atual" (h) para o "cabeçalho alvo" (t).
Aqui está a minha solução:
fonte