If you're seeing this message, it means we're having trouble loading external resources on our website.

Se você está atrás de um filtro da Web, certifique-se que os domínios *.kastatic.org e *.kasandbox.org estão desbloqueados.

Conteúdo principal

Forças de mola

No começo dessa seção vimos como modelar o movimento harmônico simples mapeando a onda do seno para o intervalo de um pixel, e você modelou um pêndulo em uma mola usando a onda do seno. Embora usar a função sin()seja uma maneira rápida e simplificada de fazer as coisas funcionarem, ela não vai servir se o que quisermos for ter um pêndulo na ponta de uma mola em um espaço bidimensional que responda a outras forças no ambiente (vento, gravidade etc.). Para realizar uma simulação como essa (uma que é idêntica ao exemplo do pêndulo, só que agora há uma mola), precisamos modelar as forças de uma mola usando PVector.
A força de uma mola é calculada de acordo com a lei de Hooke, que tem esse nome devido a Robert Hooke, um físico britânico que desenvolveu a fórmula em 1660. Hooke enunciou a lei originalmente em latim: "Ut tensio, sic vis," ou “A extensão é proporcional à força.” Vamos pensar da seguinte forma:
<div class="callout">
A força da mola é diretamente proporcional à extensão da mola.
</div>
Em outras palavras, se você puxar muito o pêndulo, a força vai ser grande; se você o puxar pouco, a força será fraca. Matematicamente, a lei é enunciada da seguinte forma:
Fspring=k×x
  • k é constante, e seu valor vai dar dimensão à força. A mola é elástica ou rígida?
  • x se refere ao deslocamento da mola, isto é, à diferença entre o comprimento atual e o comprimento em repouso. O comprimento em repouso é definido como o comprimento da mola em um estado de equilíbrio.
Lembre-se, a força é um vetor, então precisamos calcular tanto sua magnitude quanto sua direção. Vamos ver mais um diagrama de mola e identificar tudo que podemos ter em um programa.
Vamos estabelecer as três variáveis iniciais seguintes, como mostrado no diagrama acima, com alguns valores razoáveis.
var anchor = new PVector(100, 10);
var bob = new PVector(110, 100);
var restLength = 20;
Primeiro, vamos usar a lei de Hooke para calcular a magnitude da força. Precisamos saber os valores de k e x. k é fácil; é simplesmente uma constante, então vamos inventar alguma coisa.
var k = 0.1;
x talvez seja um pouco mais difícil. Precisamos saber a “diferença entre o comprimento atual e o comprimento em repouso.” O comprimento em repouso é definido como a variável restLength. Qual é o comprimento atual? A distância entre a âncora e o pêndulo. E como podemos calcular essa distância? Que tal usarmos a magnitude de um vetor que aponta para o pêndulo a partir da âncora? (Observe que esse é exatamente o mesmo processo que aplicamos para calcular a distância na seção de Atração Gravitacional).
var dir = PVector.sub(bob, anchor);
var currentLength = dir.mag();
var x = restLength - currentLength;
Agora que temos os elementos necessários para a magnitude da força (-1 * k * x), precisamos descobrir a direção, um vetor unitário que aponta na direção da força. A boa notícia é que já temos esse vetor. Certo? Há um minuto pensamos:"Como podemos calcular aquela distância? Que tal usarmos a magnitude de um vetor que aponta para o pêndulo a partir da âncora?” Bem, aquele mesmo vetor é a direção da força!
No diagrama acima, podemos ver que, se esticarmos a mola para além do comprimento de repouso, deve haver uma força puxando-a de volta na direção da âncora. E se ela se encolhe, ficando menor que o comprimento de repouso, a força deve empurrá-la para longe da âncora. Essa direção reversa é incluída na fórmula com o -1. Então, tudo o que precisamos fazer é normalizar o PVector que usamos para calcular a distância! Vamos dar uma olhada no código e renomear essa variável PVector como “força”.
var k = 0.01;
var force = PVector.sub(bob, anchor);
var currentLength = force.mag();
var x = restLength - currentLength;
// Direção da força da mola, um vetor unitário
force.normalize();
// Juntando tudo: direção e magnitude!
force.mult(-1 * k * x);
Agora que temos o algoritmo funcionando para calcular o vetor força da mola, a pergunta continua: que estrutura de programação orientada a objetos devemos usar? Essa é, novamente, uma daquelas situações para a qual não há uma resposta “correta”. Há várias possibilidades; devemos fazer a escolha dependendo dos objetivos do programa e de acordo com nosso próprio estilo de programar. Contudo, como temos trabalhado com o objeto Mover, vamos continuar com essa mesma estrutura. Vamos pensar em nosso objeto Mover como o "pêndulo" da mola. O pêndulo precisa de vetores de posição, velocidade e aceleração para se mover pela tela. Perfeito – já temos isso! E talvez o pêndulo experimente a força da gravidade através do método applyForce(). Apenas mais um passo – precisamos aplicar a força da mola:
var bob = new Bob();

draw = function()  {
  // Nossa “força da gravidade de mentira”
  var gravity = new PVector(0, 1);
  bob.applyForce(gravity);
  // Também precisamos calcular e aplicar uma força de mola!!
  var springForce = \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_????
  bob.applyForce(spring);

  // Nossos métodos update() e display()
  bob.update();
  bob.display();
};
Uma opção seria escrever todo o código da força da mola dentro do laço draw() principal. Mas, pensando mais pra frente, quando você pode ter vários pêndulos e várias conexões de mola, faz sentido escrever um objeto adicional, um objeto Spring. Como mostrado no diagrama acima, o objeto Bob mantém o controle dos movimentos do pêndulo; o objeto Spring mantém o controle sobre a âncora da mola e o seu comprimento de repouso, e calcula a força da mola no pêndulo.
Isso nos permite codificá-los juntos assim:
var bob = new Bob();
var spring = new Spring();

draw = function()  {
  // A parte na qual criamos a força da gravidade
  var gravity = new PVector(0, 1);
  bob.applyForce(gravity);
  // Spring.connect vai calcular e aplicar a força de mola
  spring.connect(bob);

  // Nossos métodos update() e display()
  bob.update();
  bob.display();
};
Aqui, você pode perceber que isso é muito parecido com o que fizemos na seção de Gravidade com um objeto de atração. Lá, foi dito algo como:
var force = attractor.calculateAttraction(mover);
mover.applyForce(force);
Aqui, a situação análoga com uma mola deveria ser:
var force = spring.calculateForce(bob);
bob.applyForce(force);
No entanto, tudo o que fizemos nesse exemplo foi:
spring.connect(bob);
Mas por quê? Por que não precisamos chamar applyForce() no pêndulo? Claro, a resposta é que precisamos sim chamar applyForce() no pêndulo. Mas em vez de fazer isso em draw(), estamos mostrando que uma alternativa razoável (e algumas vezes preferível) é pedir ao método connect() que se encarregue de chamar applyForce() no pêndulo internamente.
Spring.prototype.connect(bob) {
  var force = /* aqui entram os cálculos */;
  bob.applyForce(force);
};
Por que fazer de uma forma com o objeto Attractor e de outra com o objeto Spring? Quando estávamos começando a aprender sobre forças, era mais claro mostrar todas as forças sendo aplicadas no laço draw() principal, e esperamos que isso tenha te ajudado a aprender sobre acúmulo de forças. Agora que já estamos mais acostumados com isso, talvez seja mais simples incorporar alguns detalhes aos próprios objetos.
Vamos juntar tudo isso no programa abaixo. Adicionamos algumas coisas: (1) o objeto Bob inclui funções para interatividade com o mouse, de forma que o pêndulo possa ser arrastado pela tela, e (2) o objeto Spring inclui uma função que limita o comprimento da conexão entre um mínimo e um máximo.

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?

Nenhuma postagem por enquanto.
Você entende inglês? Clique aqui para ver mais debates na versão em inglês do site da Khan Academy.