A Matemática nos Games – Rotação de Ponto

Olá pessoal,

Começamos hoje um novo arco de posts técnicos. O assunto? Um elemento presente desde Tennis for Two de 1958 até o novo Battle Field 3 – a saudosa ciência conhecida como Matemática. Para alguns, um bixo de sete cabeças – para outros, nem tanto. Porém, sempre tendo um papel importantíssimo na história do desenvolvimento de jogos. Esta ciência muitas vezes não recebe a devida atenção por parte dos desenvolvedores. Muito programadores desconhecem que vários dos seus problemas podem ser resolvidos com um conhecimento mínimo de trigonometria. Estamos aqui para mudar esta realidade.

Falando em trigonometria, ela será a base para o nosso primeiro assunto. Para quem não recorda, ela é o segmento da matemática que foca o estudo das relação dos lados de um triângulo retângulo. Porém, a ideia aqui não será repetir os ensinamentos do meu professor de ensino médio, mas sim, através de exemplos práticos, mostrar a utilidade e aplicação da matemática nos games. Para isso, criaremos um case, um game básico, para justificar nossos ensinamentos. Neste primeiro post, vou utilizar um título que fez parte da minha infância. Logo quando ganhei o meu Phantom System (versão da Gradiente para o NES), peguei emprestado de um colega um divertido game de corrida chamado, Super Sprint.

Ok,  temos que dar um desconto, isso foi em 1991 :) . Apesar de simples, utilizando uma visão top-down da pista de corrida, Super Sprint rendeu boas horas de diversão. Vamos experimentar um pouco da sua mecânica através do protótipo a seguir. Clique e utilize as setas do teclado para girar e mover o carro.

Analisando o protótipo, você consegue imaginar o algoritmo por trás do game? Qual seria a técnica responsável por fazer o carro girar e movimentar-se em qualquer direção?

Temos basicamente dois movimentos para o carro, translação e rotação. Para obtermos o movimento de translação, bastaria somarmos a velocidade nas posições x e y . Algo como, se seta para direta pressionada, x += velocidade. Porém, Super Sprint é um pouco mais complexo que isso. Não podemos simplesmente somar a velocidade nos dois eixos. Você pode notar que podemos mover e girar o carro em qualquer direção. Observe que o movimento é realizado levando em conta o ângulo do veículo (canto superior direito). A seta para cima, sempre move o carro para frente, enquanto as setas para direita e esquerda aumentam e diminuem o ângulo de rotação.  Como faremos isso? Vamos primeiro ver um exemplo. Observe a imagem a seguir para entender bem o que precisamos. Através de um determinado ângulo (qualquer um) e um distância (velocidade) precisamos encontrar o ponto seguinte para movermos o nosso carrinho.

Figura 1

A posição atual do nosso carro seria x=10 e y=20. A velocidade, neste exemplo, está configurada para 20 pixels. Sendo assim, chegaríamos no  ponto p1 de coordenadas x=25 e y= 33. O que devemos fazer para chegar nestes valores? A matemática nos auxilia na solução desse problema através de um conceito chamado rotação de ponto. Você já ouviu falar de seno e cosseno? Entendeu como eles funcionam e qual a sua utilidade? Pois é, durante o ensino médio isso pode não ter ficad0 muito claro, mas vamos acabar com os seus problemas :) .

Figura 2

Observe a imagem a cima. A definição nos diz que, dado um círculo trigonométrico de centro (0,0) e raio de valor 1, o seno de um angulo X é sua representação no eixo Y. Já o Cosseno,  é a representação no eixo X. Lembre-se, cosseno (com sono), é o eixo deitado ;) . É importante também registrar que os pontos formam um triângulo retângulo (veremos a utilidade disso nos próximos posts).

O valor de seno ou cosseno para um ângulo X pode ser obtido através das funções Math.sin e Math.cos de sua linguagem de programação favorita, ou através da tabela trigonométrica.

Ok Everton, mas como isso irá me ajudar a fazer a movimentação do carro exatamente? Bom, a matemática vai fazer a pior parte. Com o ângulo em mãos, e utilizando seno e cosseno, vimos que é possível encontrar o ponto que seria a extremidade de uma reta de tamanho 1. Depois disso, basta multiplicarmos pelo valor desejado para obter o resultado. Vamos fazer uma prova com o exemplo da figura 1:

  • A posição atual é x=10 y=20
  • O ângulo de rotação é de 40º
  • A velocidade (distância a ser percorrida) é de 20 pixels
  • Cosseno de 40º é 0,766
  • Seno de 40º 0,6428
  • Multiplicando os valores de seno e cosseno pela velocidade de 20,relacionando-os a x e y, teremos:
    • x = 15,32
    • y = 12,85
  • Note que esta técnica parte do princípio que o ponto de equilíbrio está no centro do círculo. Sendo assim, teremos que fazer a translação do nosso carro somando sua posição atual (x=10,y=20) aos valores obtidos, resultando em:
    • x = 25,32
    • y = 32,85
  • Arredondando os valores, chegamos no resultado exato apresentado pela figura 1.

Vamos ver como ficaria o código genérico para este mecânica.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Em um método que executa de forma intermitente (pulso do game)
function onUpdate(event:Event)
{
   // Testa as teclas do teclado para modificar o ângulo
   if(left)
     angle -= velocity;
   if (right)
     angle += velocity;
   // Se a seta pra cima estiver pressionada, calcular o próximo ponto e somar na posição atual do carro
   if(up)
   {
     var newPoint:Point = getNextPoint(angle,velocity);
     car.x += newPoint.x;
     car.y += newPoint.y;
   }
 
   // Testa as extremidades dos ângulos, algumas linguagens suportam graus multiplos de 360 fazendo automaticamente a relação
   if(angle < 0 )
      angle = 360 + angle;    
   else if(angle > 360)
     angle = 0;
 
   car.rotation = angle;
}
 
// Método que calcula a rotação do ponto através de um angulo e um comprimeto
function getNextPoint(angle, lenght):Point
{
  var newPoint:Point = new Point();
  // Precisamos convertar o valor de graus para radianos devido a função da classe Math trabalhar com esta unidade.
  newPoint.x = Math.cos(convertDegreesToRadians(angle))* lenght;
  newPoint.y = Math.sin(convertDegreesToRadians(angle))* lenght;
  return newPoint;
}
 
//Método que converte um valor em graus para radianos
function convertDegreesToRadians(degrees:int)
{
    return (Math.PI * degrees) / 180;
}

E ai, o que acharam? Ficou mais claro a aplicação do Seno e Cosseno para encotrarmos o ponto rotacionado?O nosso Super Sprint ainda não está pronto. Precisamos acrescentar um pouco de física para deixá-lo mais próximo da versão original. Mas, isso fica para o próximo post ;)

Mandem suas dúvidas através dos comentários.

Grande abraço e até a próxima.

Autor: Everton Vieira Ver todos os posts de
Sou Bacharel em Análise de Sistemas pela Universidade Católica de Pelotas (UCPel) no ano de 1999. Minha paixão por games é de longa data. Porém, em 2003 tornei essa paixão uma profissão. Durante oito anos atuei como Game Designer e Arquiteto de Software em mais de 30 projetos de Serious Games (simuladores) para grandes empresas do país. Atualmente sou sócio-fundador da Izyplay Game Studio, onde exerço o cargo de Diretor de Criação. Além do envolvimento corporativo, também participei da organização da Pós Graduação em Arquitetura e Desenvolvimento de Jogos Digitais na FATEC SENAC Pelotas. Minha área de interesse e especialização é Game Design e Inteligência Artificial.

10 Comentários em "A Matemática nos Games – Rotação de Ponto"

  1. Eduardo Nunes Pereira 04/10/2011 at 18:30 - Reply

    Ótimo artigo, muito bom mesmo, não deixe o motor da galera esfriar, estamos esperando mais sobre o assunto, vlw.

  2. Bruno Rafante 05/10/2011 at 20:22 - Reply

    Ótimo artigo mesmo. Eu adoro matemática especialmente geometria analítica. Gostaria de falar sobre minha experiência para demonstrar algo interessante. Muitas pessoas odeiam matemática (ótimo, menos concorrente haha… brincadeiras à parte…) eu também não gostava (como qualquer garoto normal da minha época) Foi quando, estudando na época no ensino médio, peguei um exercício retirado de uma questão da UFMG (Universidade Federal de Minas Gerais) eu vi a luz! O exercício encheu meus olhos fiquei louco pela matemática (e princpialmente pela física) desde então comecei a estudar frenéticamente. O exercício mostrava a figura de um joguinho daqueles que vc controla um canhaozinho movendo o angulo dele para atirar em alvos que vem descendo. A questão pedia que usando equação da reta, você determinasse se o angulo da reta que representaria o tiro seria suficiente para atingir o centro de um objeto esférico (se atingisse, o alvo era destruido). Achei incrível, não sabia nada de programação ainda e aquilo abriu meus olhos para o desenvolvimento de jogos. Foi amor à primeira vista. Vi que com a Física eu poderia desenvolver não apenas jogos, mas minha própria Engine se eu quisesse. Afinal Talles, Torricelli, arquimedes, newton entre outros trouxeram coisas maravilhosas para contribuir com o desenvolvimento de jogos como por exemplo o cálculo de torque, velocidade entre outros. Acho que se as escolas utilizassem exercícios como aquele que eu fiz os alunos ficariam muito mais motivados a aprender matemática desde pequenos (fiz a prova mostrando isso pra um amigo de 15 anos e ele teve o mesmo insight a mesma epifania que eu tive na época). Uma pena eu ainda não ter descoberto qual a utilidade dos números complexos no desenvolvimento de jogos (embora tenho o palpite de que a parte imáginária do número seria o eixo Z no “plano” cartesiano). Bom, fica aí um grande abraço e um obrigado novamente pelo conteúdo cada vez mais aprofundado que vocês postam.

    • everton.vieira 05/10/2011 at 21:21 - Reply

      Olá Bruno,
      concordo plenamente com você. Considero um grande equívoco, até hoje, os ensinos fundamental e médio não abordarem a matemática da forma correta. Na minha opinião, o ideal seria mostrar primeiro a aplicação/problema/demanda e depois o conceito/solução. Os games são um prato cheio para motivar adolescentes a, não só entender, mas gostar desta importante ciência. Em relação a seu exemplo do canhão, com certeza ele irá aparecer em um dos posts deste arco ;)

    • MagmaZero 13/06/2015 at 20:08 - Reply

      Muito bom esse artigo :D , tenho 14 anos e não vou mentir, não gosto muito de matemática, mas eu tento entender o máximo possível, e o engraçado é que quando eu entendo alguma coisa eu acabo gostando. Eu estou estudando muito, principalmente matemática, para conseguir ser desenvolvedor de jogos um dia.

  3. Calvin 06/10/2011 at 11:00 - Reply

    Muito legal o post everton. Antes de começar a desenvolver nunca pensei que matematica seria util para alguma coisa. Mas depois que fiz meu primeiro jogo, vi que é muito legal esse mundinho xP

  4. Felipe 08/10/2011 at 22:09 - Reply

    Legal galera. Acompanho o podcast de vocês.

    Tb fiz um game baseado no Supersprint, foi minha primeira experiência. Confiram, é para JME :
    http://felipemenezesgames.blogspot.com/2010/11/meu-primeiro-game-para-celular.html

    Dentor do post tem o link de donwload.

    Nessa experiência, desenferrugei a matemática e +- simulei as colisões e etc como fizeram aqui.

    Abs

  5. Thiago 10/10/2011 at 08:16 - Reply

    Eu também fiz um jogo parecido para Android:
    http://www.thiagorosa.com.br/en/projects/tt-racing

    =)

    • everton.vieira 10/10/2011 at 11:12 - Reply

      Olha só, o pessoal ai mostrando o quanto os conceitos de rotação são comuns e importantes. Vários exemplos de aplicações ;)

  6. Paulo Coutinho 11/10/2011 at 19:16 - Reply

    Olá,

    Quero parabenizar pelo mais que excelente artigo. Já busquei em diversos locais sobre isso mas não encontrei nada até hoje.

    Continuem postando mais artigos sobre isso pois é de extrema importância.

    Obrigado.

    http://www.devgames.com.br

Deixar um Comentário