Conteúdo principal
Programação
Curso: Programação > Unidade 5
Lição 6: Movimento AngularApontando na direção do movimento
Vamos voltar para um de nossos primeiros exemplos, aquele em que um objeto
Mover
acelera em direção ao mouse.Você deve ter notado que quase todas as formas que desenhamos até agora são círculos. Isso é conveniente por várias razões, uma delas é que nós não precisamos considerar a questão da rotação. Se você rotacionar um círculo ele continua exatamente igual. No entanto, chega um momento na vida de todos os programadores de movimento em que eles querem desenhar alguma coisa na tela que aponte na direção do movimento. Talvez você esteja desenhando uma formiga, ou um carro, ou uma espaçonave. E quando dizemos "aponte na direção do movimento," o que estamos querendo realmente dizer é "rotacione de acordo com o vetor velocidade." Velocidade é um vetor, com um componente x e um y, mas para rotacionar um objeto em ProcessingJS nós precisamos de um ângulo. Vamos desenhar nosso diagrama trigonométrico mais uma vez, com um vetor velocidade do objeto:
OK. Sabemos que a definição da tangente é:
O problema disso é que nós sabemos a velocidade, mas não sabemos o ângulo. Nós temos que calcular o ângulo. É aqui que uma função especial conhecida como a inversa da tangente entra em cena, às vezes chamada de arco tangente ou tg-1. (Existem também uma inversa do seno e uma inversa do cosseno.)
Se a tangente de um valor a for igual a um valor b, a tangente inversa de b será igual a a. Por exemplo:
se | |
então |
Viu como isso é o inverso? Com isso, podemos calcular o ângulo:
se | |
então |
Agora que temos a fórmula, vamos ver em que parte da função display() do nosso mover ela deve entrar. Note que em ProcessingJS, a função para arco tangente é chamada
atan()
. O JavaScript também tem o Math.atan()
de forma nativa (assim como todas as funções trigonométricas básicas), mas vamos continuar usando a funções fornecidas pelo ProcessingJS.Mover.prototype.display = function () {
var angle = atan(this.velocity.y / this.velocity.x);
stroke(0, 0, 0);
fill(127, 127, 127);
pushMatrix();
rectMode(CENTER);
translate(this.position.x, this.position.y);
rotate(angle);
rect(0, 0, 30, 10);
popMatrix();
};
Agora o código acima está praticamente terminado e quase funciona. Mas nós ainda temos um grande problema. Vamos considerar os dois vetores velocidade representados abaixo.
Ainda que sejam superficialmente similares, os dois vetores apontam em direções bem diferentes—direções opostas, na verdade! Contudo, se aplicarmos a nossa fórmula para encontrar o ângulo de cada vetor...
V1 ⇒ ângulo = atan(3/-4) = atan(-0,75) = -0,644 radianos = -57 graus
V2 ⇒ ângulo = atan(-3/4) = atan(-0,75) = -0,644 radianos = -57 graus
V2 ⇒ ângulo = atan(-3/4) = atan(-0,75) = -0,644 radianos = -57 graus
...vamos obter o mesmo ângulo para os dois vetores. Isso não pode estar certo para os dois; os vetores apontam em direções opostas! Na verdade, esse é um problema muito comum em computação gráfica. Ao invés de simplesmente usar
atan()
com um monte de instruções condicionais para solucionar cenários positivos/negativos ProcessingJS (junto com JavaScript e quase todos os ambientes de programação) tem uma função chamada atan2()
que faz isso para você.Mover.prototype.display = function () {
var angle = atan2(this.velocity.y, this.velocity.x);
stroke(0, 0, 0);
fill(127, 127, 127);
pushMatrix();
rectMode(CENTER);
translate(this.position.x, this.position.y);
rotate(angle);
rect(0, 0, 30, 10);
popMatrix();
};
Para simplificar ainda mais, o próprio objeto
PVector
tem uma função chamada heading()
, que se encarrega de chamar atan2()
para você para que você possa obter o ângulo de direção 2D em radianos para qualquer PVector
.É assim que o programa ficará no final. Coloque seu mouse sobre ele e veja a rotação!
Este curso "Natural Simulations" é um derivado do "The Nature of Code" por Daniel Shiffman, usado sob a Creative Commons Attribution-NonCommercial 3.0 Unported License.
Quer participar da conversa?
- No Desafio: Virando o carro, ao apertar direita ou esquerda, o carro vira. O que não entendi foi, porque eu tenho que ficar segurando a tecla pra que ele efetivamente vire ao invés de apenas apertá-la e porque às vezes ele vira na diagonal, já que ele é programado para virar apenas 90º ou PI/2 rad?(1 voto)