WADDINGTONS Cada Questão Revela um Novo Jeito de Aprender

Força E Gravidade

Força E Gravidade

Um guia prático para simular força e gravidade em projetos de física

A maioria dos tutoriais que você vê na internet trata força e gravidade como se fossem dois conceitos separados que se encontram apenas nas fórmulas. Na prática, quando você vai implementar isso num projeto real, logo descobre que o problema nunca é a teoria. O problema é que o motor de simulação não consegue lidar com colisões em sequência quando a gravidade está escalada acima de 20m/s² sem um timestep fixo. Trabalho com simulações físicas há bastante tempo e já vi gente inteira perder dias porque ignorou essa questão. Vou explicar como fazer isso funcionar sem perder a cabeça.

O que realmente acontece com força e gravidade num motor de simulação

Força é vetor. Gravidade é, tecnicamente, uma aceleração constante aplicada a todos os corpos com massa. A maioria dos desenvolvedores novatos aplica a gravidade diretamente como uma força, e aí entra o primeiro erro. Se o seu objeto tem massa 5 e você aplica F = m × g, a gravidade vai variar conforme a massa do objeto, o que pode ser desejável ou não dependendo do seu caso. No meu primeiro projeto sério de simulação, eu queria que todos os objetos caíssem com a mesma aceleração independente da massa. Apliquei a gravidade como força em vez de aceleração pura. O resultado foi que objetos pesados caíam mais rápido no simulador, o que na física real não acontece por causa da resistência do ar, mas num vácuo simulado claramente estava errado. A correção foi simples: aplicar aceleração diretamente ao campo velocity em vez de somar força ao campo force acumulado. Isso parece óbvio agora, mas levei duas semanas para perceber o bug porque a simulação parecia plausível a olho nu. A diferença entre aplicar como força versus aceleração só fica evidente quando você começa a variar a massa dos objetos em cenários com gravidade alta ou timestep variável.

Implementação passo a passo

Se você está usando um motor como o Box2D, Matter.js ou customizando seu próprio integrador, o padrão geral segue estas etapas: Inicialize as propriedades básicas de cada corpo: massa, posição, velocidade e aceleração. A aceleração começa em zero a cada frame. Aplique forças externas. Neste estágio entram forças de mola, empuxo, arrasto, vento, qualquer coisa que não seja gravidade. Some todas ao acumulador de forças do corpo.

Equacao Da Forca Da Gravidade
Equacao Da Forca Da Gravidade

Adicione a gravidade. Aqui a decisão importante: aplique como aceleração direta ou como força. Se quer comportamento newtoniano puro (todos os corpos caem iguais), use aceleração. Se quer simular resistência do ar proporcional à massa, use força e depois divida por massa no próximo passo. Integre o movimento. O método mais básico é Euler explícito: velocity += acceleration × dt, position += velocity × dt. Funciona para simulações simples, mas se o seu timestep for maior que 0,03 segundos, a simulação começa a ganhar energia artificial e os objetos começam a flutuar ou acelerar descontroladamente. Resolva colisões. Detecte sobreposição entre corpos e aplique impulsos de reação. Este é o passo que mais causa problemas. Colisões encadeadas — quando um objeto cai em cima de outro que está em cima de um terceiro — exigem múltiplas iterações de resolução. O Box2D usa 8 iterações de posição e 3 de velocidade por padrão, o que resolve a maioria dos casos. Abaixo disso, você vê o famoso efeito "mola" onde os objetos vibram antes de estabilizar.

Problemas comuns que ninguém conta

O primeiro problema que você vai encontrar é tunneling. Quando um objeto se move rápido o suficiente, ele pode atravessar outro objeto entre dois frames sem que a detecção de colisão registre nada. A solução padrão é usar capsule casting ou CCD (continuous collision detection), mas isso custa de 3 a 5 vezes mais processamento. Num projeto meu com 200 objetos caindo, ativar CCD para todos travou a simulação completamente. Ativei CCD apenas para os objetos com velocidade acima de 50 unidades por segundo e o problema sumiu. O segundo problema é pilhas instáveis. Enfileirar objetos uns em cima dos outros parece simples, mas a menor imprecisão numérica faz a pilha tombar. A workaround que eu uso é aplicar um tiny damping global de 0,001 a 0,005 por frame. Isso estabiliza sem parecer artificial. Também recomendo usar um solver com mais iterações de posição — 10 a 20 faz diferença enorme em pilhas altas. O terceiro problema, que é o mais chato, é que a gravidade em motores de física muitas vezes não respeita a escala do seu mundo. Se suas unidades estão em centímetros em vez de metros, uma gravidade de 9,81 vai fazer tudo parecer que está na Lua. O Box2D foi projetado para funcionar com corpos entre 0,1 e 10 metros. Fora disso, os resultados ficam imprevisíveis. Eu já vi gente usar gravidade de 981 em simulações em centímetros e chamar de correção. Não é. É um paliativo que quebra a física em outros aspectos.

Quando não usar simulação de força e gravidade

Se o seu projeto é um jogo mobile com centenas de objetos e orçamento de 16ms por frame, simulação física completa pode não ser viável. Neste caso, considere aproximações: partículas com trajetórias parabólicas pré-calculadas para projéteis, ou um sistema de keyframe para objetos que caem em cenários previsíveis. Isso elimina completamente o custo de solve de colisões. Para animações cinemáticas onde a física é só aparente, use um rig simples com constraints. Ficou comprovado que simulações de tecidos ou correntes de cordas quase nunca precisam de solved físico em tempo real — uma animação baked com 60fps consome uma fração do processamento.

Exemplos De Forca De Gravidade
Exemplos De Forca De Gravidade

Recursos práticos

Para quem quer começar do zero, o Matter.js é a biblioteca mais acessível. Tem documentação em português, comunidade ativa e roda no browser sem compilador. O código para configurar gravidade e forças básicas leva menos de 50 linhas. Se você precisa de precisão física séria, o Box2D continua sendo o padrão da indústria. A versão C++ é a mais madura, mas existem bindings para Unity, Godot e Python. O Manuual do Box2D disponível no site oficial do Erin Catto ainda é a melhor referência técnica existente, apesar de não ter sido atualizado desde 2019. Para simulações mais avançadas com deformação de corpos macios, o projecto Soupsim ou o plugin de soft body do Blender oferecem soluções práticas sem escrever seu próprio integrador.

O mais importante é testar sempre com valores conhecidos. Se você aplicar gravidade 9,81m/s² num corpo em queda livre, após 1 segundo a velocidade deve ser exatamente 9,81m/s e a distância percorrida 4,905 metros. Se seus números não batem, o integrador ou o timestep estão errados antes de qualquer outra coisa.

Artigos Relacionados