Para que são utilizados atan e atan2 nos jogos?

48

Estou tendo problemas para entender Math.tan()e Math.atan()e Math.atan2().

Eu tenho conhecimento básico de trigonometria, mas o uso de SIN, COS e TAN etc para o desenvolvimento de jogos é muito novo para mim.

Estou lendo alguns tutoriais e vejo que, usando a tangente, podemos obter o ângulo em que um objeto precisa ser girado pela quantidade de faces a outro objeto, por exemplo, meu mouse. Então, por que ainda precisamos usar atan ou atan2?

sutoL
fonte
atan é usado para determinar o ângulo, útil para milhares de coisas diferentes. Você tem uma pergunta real sobre o seu uso ou está apenas procurando ajuda geral em matemática?
BlueRaja - Danny Pflughoeft
5
Você definitivamente precisa entender a matemática / geometria por trás dessas funções; uma vez que você os domine, eles se tornarão parte do seu "entendimento do mundo", como a gramática básica que você usa todos os dias para falar. Quando você conseguir "falar matemática / geometria", verá que essas funções são ferramentas simpy para obter um resultado, o mais natural de usar.
FXIII
Esses tutoriais estão errados ou você não entendeu. Você usa atan2 () para obter o ângulo de um objeto para outro. Como isso funciona é explicado abaixo.
Jhocking 9/07
graças as pessoas para as respostas, agora estou arrependido de não pagar mais atenção na aula
sutoL

Respostas:

94

A fórmula tangente é esta:

tan(angle) = opposite/adjacent

Consulte este desenho:

Diagrama de um triângulo retângulo, com um ângulo teta e seus lados opostos e adjacentes marcados

Onde afica o lado adjacente, oé o lado oposto e thetaé o ângulo. Da mesma forma, seno e cosseno são sin (ang) = o / he cos (ang) = a / h, onde hestá o lado mais longo: http://www.mathwords.com/s/sohcahtoa.htm

Enquanto isso atan(abreviação de tangente ao arco , também conhecida como tangente inversa ) é o inverso de tan, assim:

atan(opposite/adjacent) = angle

Portanto, se você conhece os valores dos lados oposto e adjacente (por exemplo, subtraindo as coordenadas do objeto das coordenadas do mouse), pode obter o valor do ângulo com atan.

No desenvolvimento de jogos, porém, pode acontecer com bastante frequência que o lado adjacente seja igual a 0 (por exemplo, a coordenada x de um vetor sendo 0). Lembrando que tan(angle) = opposite/adjacento potencial para um erro desastroso de dividir por zero deve ser claro. Portanto, muitas bibliotecas oferecem uma função chamada atan2, que permite especificar os parâmetros xe y, para evitar a divisão por zero e fornecer um ângulo no quadrante direito.

diagrama atan2

(diagrama cortesia de Gareth, por favor vote sua resposta também)


O uso da trigonometria no desenvolvimento de jogos é bastante comum, especialmente com vetores, mas geralmente as bibliotecas ocultam o trabalho de trigonometria para você. Você pode usar sin / cos / tan para muitas tarefas que envolvem manipulações geométricas para encontrar um valor em um triângulo. Tudo o que você precisa é de 3 valores (comprimentos laterais / valores de ângulo) para encontrar os outros valores de um triângulo retangular, por isso é bastante útil.

Você pode até usar a natureza "ciclista" das funções seno e cosseno para comportamentos especiais em um jogo, por exemplo, eu vi cos / sin usado muito para fazer um objeto girar em torno de outro.

Jesse Emond
fonte
8
Vale ressaltar que a Wikipedia descreve outros usos para o Atan2 ( não o atan), além de apenas evitar a divisão por zero. Por exemplo, ele se corrige para o quadrante que está sendo usado, onde normalmente você teria que fazer tudo isso sozinho.
21811 doppelgreener
Na verdade, nota muito importante aqui. Atualizando minha resposta.
precisa
Você não se bronzeava e retrocedia no seu primeiro parágrafo longo? Você usaria atan para obter o ângulo (ou seja, inverter a equação) e tan para obter a razão dos lados (ou seja, exatamente o que a equação diz).
Jhocking 9/07
Bem, se você sabe que o / a é igual a, por exemplo, 3, se você deseja o ângulo que faz em (3), foi isso que eu quis dizer: se você quiser isolar o ângulo, use atan na razão. Se você quiser isolar a proporção, use bronzeado no ângulo.
precisa
Vou mudar sua redação então, porque parece que você estava dizendo o contrário.
Jhocking 9/07
64

insira a descrição da imagem aqui

Gareth Rees
fonte
1
Seria indelicado editar a resposta principal para incluir esse diagrama? Esse diagrama é ótimo e se encaixaria bem logo após a explicação escrita de Jesse sobre atan2 ().
Jhocking 9/07
1
Vá em frente: seja meu convidado! Excluirei esta resposta depois que você terminar.
Gareth Rees
7
Não não. Mantem! É creditado e as pessoas ainda devem votar aqui para o diagrama.
precisa
12

Aqui está uma maneira ligeiramente diferente de pensar sobre as funções trigonométricas - incluindo atan () e atan2 () - que eu acho úteis (explicações em termos de "oposto / adjacente" me confundem por algum motivo).

x, y, r, teta

Você pode ir de um ponto a outro movendo x unidades horizontalmente e y verticalmente (chamadas coordenadas retangulares ou cartesianas ) ou movendo a distância r em um ângulo de Ɵ (chamadas coordenadas polares em 2D).

Digamos que temos uma coordenada polar (r, Ɵ) e queremos convertê-la para (x, y).

cos (Ɵ) fornece a proporção de r que se encontra ao longo do eixo x :

  • Se r = 1 então x = cos (Ɵ).
  • Se r = 100 então x = 100 * cos (Ɵ).
  • Em geral x = r * cos (Ɵ).

Da mesma forma, sin (Ɵ) fornece a proporção de r que se encontra ao longo do eixo y :

  • Se r = 1 então y = sin (Ɵ).
  • Se r = 100 então y = 100 * sin (Ɵ).
  • Em geral y = r * sin (Ɵ).

Que tal converter a coordenada retangular (x, y) em coordenada polar (r, Ɵ)?

r é a hipotenusa do triângulo retângulo formada por x e y , portanto:

  • r = sqrt (x x + y y)

tan (Ɵ) fornece a inclinação - a elevação ao longo da corrida - da linha com o comprimento r . Assim:

  • tan (Ɵ) = y / x
  • Ɵ = atan (y / x)

No entanto, ao executar y / x, calcular 3/4 dá a mesma resposta que calcular -3 / -4. Da mesma forma -3/4 dá a mesma resposta que 3 / -4. Portanto, temos atan2 (y, x) que lida com os sinais individuais corretamente e evita um erro de divisão por zero / infinito.

  • Ɵ = atan2 (y, x)
AbePralle
fonte
4

Jesse e Sid estão basicamente certos, mas eu suspeito que você realmente está buscando informações sobre o problema.

Atan2 () é necessário, pois atan () não informa o ângulo da horizontal que você precisa, pois não lida com quadrantes.

Isso significa que o uso de atan para vetores (-2,2) e (2, -2) dará o mesmo valor. Você deveria então ativar o sinal de seus argumentos e adicionar pi ao resultado. Além disso, você tem o caso especial de dividir por zero para considerar que Jesse mencionou. Também atan2 () funciona melhor que atan quando x está próximo de 0

Então, se você quiser o ângulo de um vetor entre -pi e pi

x = -2
y = 2
angle = Math.Atan2(y, x)

ou

x = -2
y = 2
angle = calculateAngle(y, x);

double CalculateAngle(double y, double x)
{
    double angle = 0;
    if (x == 0)
    {
        if (y == 0)
            angle = 0;
        else if (y > 0)
            angle = Math.PI/2;
        else
            angle = -Math.PI/2;
    }
    else
    {
        angle = Math.Atan(y/x);
        if (x < 0)
        {
            if (y > 0)
            {
                angle += Math.PI;
            }
            else if (y < 0)
            {
                angle -= Math.PI;
            }
            else
            {
                angle = Math.PI;
            }
        }
    }
    return angle;
}
LukeN
fonte
1
"Isso significa que usar atan para vetores (-2,2) e (2,2) dará o mesmo valor." Se este for o caso, seu atan está incrivelmente quebrado, porque um deles deve ser -π / 4 e o outro π / 4. Que vergonha para todos que votaram nesse lixo.
O código ainda está errado. Você está testando para y==0depois se dividir xno outro ramo.
sam hocevar 10/09/12
0

Esclarecerei algumas coisas de maneira concisa. Consulte os tutoriais de trigonometria online para obter uma explicação detalhada.

Seja um ângulo. Então tan (a) = tan (a + 2 * pi).

atan é bronzeado inverso, ou seja, fornece o ângulo dado ao bronzeado. Quando você chama atan (tan (a + 2 * pi)), a resposta será a. Isso será inadequado para o seu aplicativo.

O atan2 terá dois argumentos para ajudar nesta situação exata. atan toma x e y, que são basicamente cos (a) e pecado (a).

atan2 (sin (a), cos (a)) = a atan2 (sin (a + 2 * pi), cos (a + 2 * pi)) = a + 2 * pi / * sin e cos tem sinais diferentes, levando para uma resposta diferente * /

Por favor, encontre alguns tutoriais para explicar por que é assim.

Seu código deve ser algo como isto:

if (mouseMoved)
{
  double angle = atan2(mousey - objecty, mousex - objectx);

  object. setTransform to Rotate(angle);

  // If you want to print it
  print radian_to_degrees(angle); // Because angle is in radian 360 degrees = 2*Pi radians
}
Sid Datta
fonte
tan(a) = - tan(-a), A equação que você quis expressar era talveztan(a) = tan(pi+a)
Ali1S232
0

Um uso atan2que encontrei no meu código é "ângulo assinado".

Normalmente, a maneira como você encontra o ângulo entre dois vetores é

inline float angleWith( const Vector2f& o ) const
{
    return acosf( this->normalizedCopy().dot(o.normalizedCopy()) ) ;
}

Mas isso não diz qual deles "leva" (ou seja, "mais à frente no sentido horário" do que o outro). Essas informações podem ser importantes para o rastreamento de gestos.

Você pode encontrar o ângulo do eixo x (1,0)para ambos os vetores, mas existe um problema grave de ambiguidade: um vetor com um ângulo de 315 graus retorna 45 graus usando o cosmétodo acima e um ângulo de 45 graus. Você pode fazer uma verificação de sinal ypara corrigir isso ou usar atan2.

// Returns + if this leads o.
// more expensive than unsigned angle.
inline float signedAngleWith( const Vector2f& o ) const
{
  float aThis = atan2f( y, x );
  float aO = atan2f( o.y, o.x ) ;
  return aThis - aO ;
}
bobobobo
fonte
0

Observe que o atan não está quebrado. arctan ou tan inverso é apenas uma função entre -PI / 2 e PI / 2. Ele repete esse padrão, mas não é uma função que é um problema para um computador, pois não lida com várias respostas.

É o mesmo para entre -PI / 2 e PI / 2 e acos entre 0 e PI. Esses são os intervalos mais simples para uma função ocorrer. Para atan e asin, ele passa do mais negativo para o mais positivo. Para acos, passa do mais positivo para o mais negativo. (isso ajuda a interpolar respostas mais precisas)

então asin, acos e atan são as funções matemáticas.

atan2, no entanto, é muito mais útil para programação, pois fornece a revolução completa (PI em radianos ou 360 graus ou 400 gradianos). Note que eles produziram apenas um para o bronzeado, não para o pecado ou cos. Bronzeado é o único que usa horizontal e vertical (x, y)

Deuce
fonte