Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 4

Ângulo do Vetor com `atan2(y, x)`

Recommended resources

Olá! Na lição anterior, vimos como decompor um vetor de direção em suas componentes x e y usando seno e cosseno. Essa é a base para mover um personagem ou lançar raios em uma direção específica. Essencialmente, fomos de "ângulo" para "componentes".

Nesta aula, concluiremos nosso módulo fundamental de trigonometria aprendendo a fazer a operação inversa, que é igualmente crucial. Nosso objetivo é utilizar a função atan2(y, x) para determinar o ângulo de um vetor a partir de suas componentes cartesianas. Imagine que você tem um vetor que representa a direção de seu personagem até um item; com atan2, você pode calcular o ângulo exato que o personagem precisa virar para encarar o item. Esta é a ferramenta que nos permite ir de "componentes" de volta para "ângulo".

O Problema com a Tangente Inversa Simples (atan)

A partir da geometria do triângulo retângulo, sabemos que a tangente de um ângulo é a razão entre o cateto oposto (y) e o cateto adjacente (x).

Naturalmente, para encontrar o ângulo a partir das componentes, poderíamos pensar em usar a função inversa da tangente, chamada arco-tangente (atan em programação):

No entanto, essa abordagem tem duas falhas críticas que a tornam inadequada para a programação de jogos e gráficos.

  1. Ambiguidade de Quadrante: A divisão y/x perde informações sobre os sinais individuais de x e y. Por exemplo, um vetor (2, 2) tem y/x = 1. Um vetor (-2, -2), que aponta na direção diametralmente oposta, também tem y/x = 1. A função atan não tem como saber qual dos dois vetores você quer e, por padrão, retorna um ângulo entre -90° e +90° (-π/2 e +π/2 radianos). Ela não consegue distinguir entre o primeiro e o terceiro quadrante, ou entre o segundo e o quarto.
  2. Divisão por Zero: Se x = 0 (o vetor aponta diretamente para cima ou para baixo), a expressão y/x resulta em uma divisão por zero, causando um erro no programa.

O vídeo a seguir, do canal Djordje Romanic, demonstra de forma excelente por que a função arctan convencional é insuficiente.

atan, atan2 and Standard Angle

Este vídeo explica o problema fundamental da função arctan padrão ao tentar determinar o ângulo de um vetor em qualquer quadrante.

Assista ao trecho que demonstra o problema. O autor usa um exemplo no segundo quadrante (com x negativo e y positivo) para mostrar como o arctan retorna um ângulo incorreto no quarto quadrante. Isso ilustra visualmente a ambiguidade que mencionamos.


A Solução Elegante: atan2(y, x)

Para resolver esses problemas, as bibliotecas de matemática e linguagens de programação fornecem uma função especializada: atan2(y, x).

A atan2 é projetada especificamente para calcular o ângulo de um vetor (x, y). Suas principais vantagens são:

  • Recebe y e x como argumentos separados: Ao invés de receber a razão y/x, a função analisa os sinais de x e y individualmente. Isso permite que ela determine sem ambiguidade em qual dos quatro quadrantes o vetor se encontra.
  • Retorna um ângulo no círculo completo: A atan2 retorna um ângulo no intervalo de -180° a +180° (ou -π a +π radianos), cobrindo todos os 360 graus do círculo.
  • Lida com x = 0: A função é implementada para retornar os ângulos corretos (+90° ou -90°) quando x é zero, evitando erros de divisão.

A imagem a seguir ilustra perfeitamente como a atan2 calcula o ângulo correto para pontos em cada um dos quatro quadrantes.

Esta imagem mostra quatro exemplos de vetores, um em cada quadrante. Para cada vetor, a função `atan2(y, x)` calcula o ângulo correto em relação ao eixo x positivo, variando de -180° a +180°.

A discussão a seguir, de um fórum para desenvolvedores de jogos, é um excelente recurso que resume por que a atan2 é a ferramenta certa para esta tarefa.

What are atan and atan2 used for in games?

Esta discussão do Game Development Stack Exchange explica de forma prática por que a atan2 é essencial em jogos.

Primeiro, leia a resposta inicial, que introduz o atan, aponta o problema da divisão por zero e apresenta o atan2 como a solução. Em seguida, leia a próxima seção, que explica a ambiguidade do atan(y/x). O autor destaca que 3/4 e -3/-4 dão o mesmo resultado, o que torna impossível para o atan distinguir os quadrantes.


Como a atan2 Funciona Internamente

Agora que sabemos o que a atan2 faz, vamos entender como ela faz isso, algo importante para a sua tese. A atan2 funciona essencialmente como uma função definida por partes, com uma lógica para cada quadrante.

O vídeo do Djordje Romanic, que vimos antes, agora nos mostrará essa lógica interna.

atan, atan2 and Standard Angle

Este trecho do vídeo detalha a lógica por trás da atan2, explicando como ela ajusta o resultado da arctan para cada quadrante e como lida com casos especiais.

Assista à explicação de como o ângulo é calculado em cada um dos quatro quadrantes. Note como ele adiciona ou subtrai π (180°) ao resultado de arctan(y/x) para corrigir o ângulo nos quadrantes 2 e 3. Em seguida, veja como os casos especiais (quando x=0 ou quando x=0 e y=0) são tratados.

Em resumo, a lógica é a seguinte (usando radianos):

  • Quadrante 1 (x > 0, y > 0): atan(y/x)
  • Quadrante 2 (x < 0, y > 0): atan(y/x) + π
  • Quadrante 3 (x < 0, y < 0): atan(y/x) - π
  • Quadrante 4 (x > 0, y < 0): atan(y/x)
  • Eixo Y positivo (x = 0, y > 0): π/2
  • Eixo Y negativo (x = 0, y < 0): -π/2

Essa lógica interna é o que torna a atan2 tão robusta e confiável.


Aplicação Prática em Python

Como seu projeto será em Python, é útil ver como usar a função na prática. A atan2 faz parte da biblioteca padrão math.

import math




# Vetor no 2º quadrante
x = -3
y = 4




# Calcula o ângulo em radianos
angle_rad = math.atan2(y, x) 




# Converte para graus para melhor visualização
angle_deg = math.degrees(angle_rad)

print(f"Componentes: (x={x}, y={y})")
print(f"Ângulo em radianos: {angle_rad}") # Saída: 2.214...
print(f"Ângulo em graus: {angle_deg}")   # Saída: 126.87...

Note que o ângulo está correto, no segundo quadrante (entre 90° e 180°). Se tivéssemos usado math.atan(y/x), o resultado seria aproximadamente -53.13°, um ângulo no quarto quadrante, completamente errado.

É extremamente importante prestar atenção na ordem dos argumentos!

atan, atan2 and Standard Angle

O mesmo vídeo que vimos antes faz um alerta crucial sobre a implementação da atan2 em diferentes linguagens.

Assista ao breve aviso do autor sobre a ordem dos argumentos. Ele menciona que Python e Matlab usam atan2(y, x), enquanto o Microsoft Excel, por exemplo, usa atan2(x, y).

Felizmente para nós, a maioria das linguagens de programação voltadas para computação científica e jogos (Python, C++, C#, Java, JavaScript) segue a convenção atan2(y, x).

Para finalizar, o artigo a seguir do MarkAIcode serve como uma ótima referência sobre o uso da função em Python e suas melhores práticas.

Python atan() and atan2() Functions

Este artigo focado em Python resume as diferenças e oferece dicas práticas.

Leia a seção introdutória, que define math.atan() e math.atan2() em Python. Em seguida, leia sobre a diferença chave entre elas, que é a capacidade de lidar com os quadrantes. Por fim, revise a seção "Best Practices", que reforça a importância de usar atan2 para múltiplos quadrantes e a ordem correta dos argumentos (y, x).


Conclusão

Com esta lição, fechamos o ciclo da nossa trigonometria fundamental. Aprendemos a ir de um ângulo para componentes (x, y) e, agora, a voltar de componentes (x, y) para um ângulo. A função atan2 é uma ferramenta indispensável em seu arsenal para o desenvolvimento do raycaster.

Pontos-chave da aula:

  • A função arctan(y/x) é insuficiente para determinar o ângulo de um vetor porque perde informação de sinal e falha quando x=0.
  • A função atan2(y, x) resolve esses problemas ao analisar os sinais de x e y separadamente, determinando o quadrante correto.
  • atan2 retorna um ângulo no círculo completo (-π a +π radianos ou -180° a +180°).
  • Em Python e na maioria das linguagens de programação, a sintaxe é math.atan2(y, x) e o resultado é em radianos.

Este conhecimento encerra nosso primeiro módulo. Na próxima lição, iniciaremos o Módulo 2: Álgebra Vetorial para o Plano 2D. Vamos formalizar o conceito de vetores e aprender as operações fundamentais (soma, subtração, etc.), que nos permitirão manipular posições e direções de forma sistemática e eficiente.