Calcul de la force de rotation d'un sprite 2D

35

Je me demande si quelqu'un a une manière élégante de calculer le scénario suivant.

J'ai un objet de (n) nombre de carrés, de formes aléatoires, mais nous allons prétendre qu'ils sont tous des rectangles.

Nous avons affaire à aucune gravité, alors considérons l'objet dans l'espace, dans une perspective descendante. J'applique une force à l'objet sur un carré spécifique (comme illustré ci-dessous).

Appliquer une force

Comment calculer l'angle de rotation, basé sur la force appliquée, à l'emplacement appliqué? Si appliqué dans le carré central, il irait tout droit. Comment doit-il se comporter plus je me déplace du centre? Comment calculer la vitesse de rotation?

jgallant
la source
Que voulez-vous qu'il arrive à la force dans le temps lorsque l'objet tourne? Cela s'applique-t-il toujours à la même place dans la même direction? Est-ce qu'il "balaie" le long du bord de l'objet? Avec les informations que vous donnez, vous ne pouvez obtenir que la force de rotation correspondante (ou couple), mais si vous voulez en déduire une vitesse de rotation, vous devez soit fournir une impulsion (plutôt qu'une force), soit expliquer comment la force devrait être appliquée au fil du temps.
Sam Hocevar
Honnêtement, c’est probablement une meilleure question pour physics.stackexchange.com, car c’est une question de mécanique de base.
BlueRaja - Danny Pflughoeft

Réponses:

44

Vous essayez de calculer le couple. Le couple dépend de la force appliquée F, du point d'application et du centre de gravité de l'objet.

1) Centre de la messe . Définit le centre de masse de l'objet.

2) Point d'application : définissez le point auquel la force agit.

3) Moment Arm : La distance entre les deux points définis ci-dessus.

Point centerofMass
Point applicationPoint
Vector momentArm = applicationPoint - centerofMass

4) Force angulaire : Divisez votre force F en deux vecteurs orthogonaux, un parallèle à la ligne en 3) et un perpendiculaire. La composante parallèle n'affecte pas le moment cinétique. La perpendiculaire fait. Vous pouvez calculer la composante parallèle par projection vectorielle. Vous pouvez soustraire cela de l'original pour obtenir le composant perpendiculaire. En pseudocode ( dotsignifie produit scalaire)

Vector myForce
Vector momentArm

parallelComponent = momentArm * (dot(myForce, momentArm) / dot(momentArm, momentArm))
angularForce = myForce - parallelComponent

5) Couple : La composante perpendiculaire de la force multipliée par la longueur du bras du moment.

Vector angularForce
Vector torque = angularForce * momentArm.Length

Pour aller du couple à la vitesse angulaire:

1) Moment d'inertie : définition du degré d'inertie en rotation d'un objet donné. Par exemple, il faut plus de couple pour faire tourner une longue barre qu'une sphère de même masse. Si le réalisme ne vous préoccupe pas, vous pouvez prétendre que le moment d'inertie est relatif à la masse ou ignorer totalement la forme et la masse de l'objet.

2) accélération angulaire :

Vector angularAcceleration = torque / momentOfInertia

3) Vitesse angulaire : La vitesse angulaire continuera à augmenter tant que le couple est appliqué. Donc, une formule sera grossièrement "La vitesse angulaire à l'instant T est la somme cumulative de l'accélération angulaire jusqu'à T ". Ceci est exprimé en pseudocode par

void Update(float elapsedSeconds):
    orientation += 0.5 * angularVelocity * elapsedSeconds;
    angularVelocity += angularAcceleration * elapsedSeconds;
    orientation += 0.5 * angularVelocity * elapsedSeconds;
Jimmy
la source
Excellente information, cependant, la partie qui me manque le plus est celle de savoir comment déterminer la force de couple. J'ai tous les composants en place comme vous l'avez décrit.
Jgallant
@ Jon: vous avez les composants, ce qui signifie que vous avez les étapes 1 à 3 et vous ne savez pas comment calculer l'étape 4? C'est principalement l'étape délicate. Je vais ajouter un peu plus de détails ici.
Jimmy
3
L'orientation étant la somme cumulée de la vitesse angulaire, elle orientation += angularVelocity * elapsedSecondsest fausse, car elle surestime la vitesse sur le pas de temps, ce qui signifie que des valeurs de trame différentes donneront des orientations différentes. Une bonne formule serait la suivante: float oldVelocity = angularVelocity; angularVelocity += angularAcceleration * elapsedSeconds; orientation += 0.5f * (angularVelocity + oldVelocity) * elapsedSeconds;. De plus, puisqu'il n'y a pas de gravité, je suggère d'utiliser «centre de masse» à la place. +1 pour la très bonne explication cependant.
Sam Hocevar
1
Une partie de la force perpendiculaire agira pour accélérer le centre de masse, et à mesure que la force est appliquée plus près du centre de masse, ce facteur augmente. La réponse est bonne et très claire, mais elle semble être incomplète à cet égard.
Sam Watkins
Pour répondre à mon propre commentaire, je lis les articles de Chris Hecker sur la physique: chrishecker.com/Rigid_body_dynamics . Il s'avère qu'une force ou une impulsion en tout point a l'effet bien connu sur le centre de masse selon F = ma ou a2 = a1 + p, comme si le corps n'était pas capable de pivoter. Cela découle de la loi de conservation de la quantité de mouvement linéaire. La composante de la force perpendiculaire au rayon provoque également un couple et une modification du moment cinétique, comme décrit dans la réponse de Jimmy.
Sam Watkins
7

si les forces ne sont pas trop fortes, il est beaucoup plus facile de simuler la rotation en utilisant plusieurs points et ressorts les reliant. dans ce cas, vous vous contentez d'assumer votre forme en plusieurs points reliés par des ressorts. chaque point représente la masse et tout ce qui est en forme a une masse égale à zéro.

spring & dots

dans l'image ci-dessus, le point noir représente les masses et la ligne rouge représente les ressorts. ensuite, pour appliquer la force, il vous suffit de l'appliquer au point le plus proche et vous verrez que votre objet pivotera comme vous le souhaitez. Pour que votre forme ressemble à une structure solide, il est préférable de définir des ressorts avec une valeur d'amortissement élevée et une valeur k élevée.

Ali1S232
la source