Como simulo um pêndulo oscilante?

9

Quero simular uma corda com um peso preso, balançando para frente e para trás como um pêndulo. Qualquer física real é um exagero; é apenas repetir sem parar o mesmo movimento.

O JQuery possui uma facilidade de "balanço" semelhante ao que estou procurando. Como funciona?

Eu estava pensando em girar de um ângulo para outro com Math.easeOutExpo, mas os pêndulos reais facilitam de maneira diferente ...

mjanisz1
fonte
2
Faça com que uma curva senoidal alimente a velocidade angular do pêndulo, de modo que o ponto zero esteja nos picos e o valor mais alto da velocidade esteja na parte inferior.
Shotgun Ninja

Respostas:

10

Bem, você terá que usar um pouco de física, mas não precisa simular nenhuma física. Existem fórmulas para o movimento do pêndulo que você pode usar facilmente para definir a rotação do seu pêndulo. Para pequenas oscilações, o movimento pode ser aproximado com um simples movimento harmônico .

O deslocamento angular em um momento específico pode ser aproximado com:

insira a descrição da imagem aqui

Isso é mais preciso para um pequeno θ máximo, mas provavelmente será preciso o suficiente para seus propósitos. Crie uma função que leva o tempo atual e gera o ângulo para o qual seu pêndulo deve ser girado e gire seu sprite nessa quantidade.

MichaelHouse
fonte
4

Aqui está um cálculo sem trigonometria, derivado do Trig 11 e da Física de Grau 11. Ele assume que a origem é o ponto mais baixo da suspensão do pêndulo, que L é o comprimento do pêndulo e que é adotada a convenção gráfica normal de y aumentando para baixo ex de aumento para a direita:

Atualização: Eu errei o yAcceleration inicialmente; isso é mais fácil.
Atualização 2 : Adicionado controle de tempo explícito e unidades de medida adicionadas.

const float gravity = 9.8;     // units of metres/sec/sec
const float deltaT  = 0.001;   // equals 0.001 sec or 1 millisecond

var xVelocity = 0.010;         // units metres/sec equals 10 cm/sec 
var x = 0.0;                   // units metres
var y = 0.0;                   // units metres

while (true) {
  var xAcceleration = -gravity * (x/L) * (L-y)/L;

  x += (xVelocity + (xAcceleration/2 * deltaT)) * deltaT;
  y  = Math.SQRT(L*L - x*x) - L; 

  xVelocity += xAcceleration * deltaT;
}
Pieter Geerkens
fonte
2
Falta tempo na equação.
Maik Semder
@MaikSemder: A unidade de tempo é definida como o ciclo de animação, seja o que for. Por que alguém faria de outra maneira?
Pieter Geerkens
No momento, sua integração de aceleração usa um tempo implícito de 1 unidade. Se a sua unidade de tempo de jogo for segundos, você poderá ter apenas 1 quadro de simulação por segundo, basta plugar explicitamente o tempo e se livrar desse problema. O tempo já está aí, apenas explique. Por exemplo, o tempo do quadro está variando, mas você precisa de uma velocidade constante estável da animação, independentemente do tempo do quadro, também entre plataformas diferentes, ou deseja um efeito slomo, por vários motivos.
Maik Semder
11
Esse foi o meu ponto, g vem de fora ou "do jogo". Agora você tem a unidade de tempo. O Delta t agora é 1 dessa unidade de tempo. Para uma simulação em tempo real, isso não é muito conveniente, já que seu jogo tem sua própria "idéia" de tempo decorrido. Torná-lo um parâmetro explícito e não uma constante implícita pode tornar sua resposta útil para um jogo.
Maik Semder
2
Nice :) velocidade deve ser multiplicado com "deltaT", bem como, a fim de obter o "deslocamento" para fora da velocidade, por isso pode ser adicionado a "x", upvoted
Maik Semder