Comment simuler un pendule oscillant?


9

Je veux simuler une corde avec un poids attaché, se balançant d'avant en arrière comme un pendule. Toute physique réelle est exagérée; c'est simplement répéter sans cesse la même motion.

JQuery a une facilité de "swing" similaire à ce que je recherche. Comment ça marche?

Je pensais à tourner d'un angle à l'autre avec Math.easeOutExpo, mais les vrais pendules se relâchent différemment ...


2
Avoir une courbe sinusoïdale alimentant la vitesse angulaire du pendule, de telle sorte que le point zéro soit aux pics et que la valeur de vitesse la plus élevée soit au bas.
Shotgun Ninja

Réponses:


10

Eh bien, vous devrez utiliser un peu de physique, mais vous n'avez pas besoin de simuler de physique. Il existe des formules pour le mouvement du pendule que vous pouvez facilement utiliser pour régler la rotation de votre pendule. Pour les petites oscillations, le mouvement peut être approximé par un simple mouvement harmonique .

Le déplacement angulaire à un instant donné peut être approximé par:

entrez la description de l'image ici

Ceci est plus précis pour un petit maximum θ, mais sera probablement suffisamment précis pour vos besoins. Créez une fonction qui prend l'heure actuelle et génère l'angle pour lequel votre pendule doit être tourné, et faites pivoter votre sprite de cette quantité.


4

Voici un calcul sans déclenchement, dérivé de la physique et du déclenchement de 11e année. Il suppose que l'origine est le point le plus bas de la suspension du balancier pendulaire, que L est la longueur du pendule et que la convention graphique normale de y augmentant vers le bas et de x augmentant vers la droite est adoptée:

Mise à jour: j'ai foiré yAcceleration initialement; c'est plus simple.
Mise à jour # 2 : Ajout d'un contrôle temporel explicite et ajout d'unités de mesure.

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;
}

2
Le temps manque dans l'équation.
Maik Semder

@MaikSemder: L'unité de temps est définie comme étant le cycle d'animation, quel qu'il soit. Pourquoi le ferait-on autrement?
Pieter Geerkens

À l'heure actuelle, votre intégration d'accélération utilise un temps implicite de 1 unité. Si votre unité de temps de jeu est de quelques secondes, vous ne pouvez avoir qu'une seule image de simulation par seconde, il vous suffit de brancher l'heure explicitement et de vous débarrasser de ce problème. Le temps est déjà là, rendez-le explicite. Par exemple, le temps d'image varie mais vous avez besoin d'une vitesse constante et stable de l'animation indépendamment du temps d'image, également entre différentes plates-formes, ou vous voulez un effet slomo, beaucoup de raisons.
Maik Semder

1
C'était mon point, g vient de l'extérieur ou "du jeu". Vous avez maintenant l'unité de temps. Delta t est actuellement 1 de cette unité de temps. Pour une simulation en temps réel, ce n'est tout simplement pas très pratique, car votre jeu a sa propre "idée" du temps écoulé. En faire un paramètre explicite plutôt qu'une constante implicite peut rendre votre réponse utile pour un jeu.
Maik Semder

2
Nice :) la vitesse doit également être multipliée par "deltaT", afin de retirer le "déplacement" de la vitesse, de sorte qu'il puisse être ajouté à "x", voté
Maik Semder
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.