Calcolo della forza di rotazione di uno sprite 2D


35

Mi chiedo se qualcuno abbia un modo elegante di calcolare il seguente scenario.

Ho un oggetto di (n) numero di quadrati, forme casuali, ma faremo finta che siano tutti rettangoli.

Non abbiamo a che fare con la gravità, quindi considera l'oggetto nello spazio, da una prospettiva dall'alto verso il basso. Sto applicando una forza all'oggetto in un quadrato specifico (come illustrato di seguito).

Applicare una forza

Come faccio a calcolare l'angolo di rotazione, in base alla forza applicata, nella posizione applicata. Se applicato nella piazza centrale, andrebbe dritto. Come dovrebbe comportarsi più mi allontano dal centro? Come calcolo la velocità di rotazione?


Cosa vuoi che accada alla forza nel tempo mentre l'oggetto ruota? Si applica sempre allo stesso quadrato nella stessa direzione? "Scorre" lungo il bordo dell'oggetto? Con le informazioni fornite, è possibile ottenere solo la forza di rotazione corrispondente (ovvero la coppia), ma se si desidera dedurre una velocità di rotazione da quella, è necessario fornire un impulso (anziché una forza) o spiegare come la forza dovrebbe essere applicata col passare del tempo.
Sam Hocevar,

Onestamente, questa sarebbe probabilmente una domanda migliore per physics.stackexchange.com, in quanto si tratta interamente di una meccanica di base.
BlueRaja - Danny Pflughoeft,

Risposte:


44

Stai cercando di calcolare la coppia. La coppia dipende dalla forza applicata F, dal punto di applicazione e dal centro di massa dell'oggetto.

1) Centro di messa . Definire il centro di massa dell'oggetto.

2) Punto di applicazione : definire il punto in cui la forza agisce.

3) Moment Arm : la distanza tra i due punti sopra definiti.

Point centerofMass
Point applicationPoint
Vector momentArm = applicationPoint - centerofMass

4) Forza angolare : dividi la tua forza F in due vettori ortogonali, uno parallelo alla linea in 3) e uno perpendicolare. La componente parallela non influisce sul momento angolare. Quello perpendicolare lo fa. È possibile calcolare il componente parallelo mediante proiezione vettoriale. È possibile sottrarlo dall'originale per ottenere il componente perpendicolare. In pseudocodice ( dotsignifica punto-prodotto)

Vector myForce
Vector momentArm

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

5) Coppia : la componente perpendicolare della forza moltiplicata per la lunghezza del braccio del momento.

Vector angularForce
Vector torque = angularForce * momentArm.Length

Per andare dalla coppia alla velocità angolare:

1) Momento d'inerzia : una definizione di quanta inerzia rotazionale ha un determinato oggetto. Ad esempio, per ruotare una barra lunga è necessaria una coppia maggiore rispetto a una sfera della stessa massa. Se non sei preoccupato per il realismo, puoi far finta che il momento d'inerzia sia relativo alla massa, oppure potresti ignorare completamente la forma e la massa dell'oggetto.

2) Accelerazione angolare :

Vector angularAcceleration = torque / momentOfInertia

3) Velocità angolare : la velocità angolare continuerà ad aumentare fino a quando viene applicata la coppia. Quindi una formula sarà approssimativamente "Velocità angolare al momento T è la somma cumulativa dell'accelerazione angolare fino a T. " Questo è espresso in pseudocodice come

void Update(float elapsedSeconds):
    orientation += 0.5 * angularVelocity * elapsedSeconds;
    angularVelocity += angularAcceleration * elapsedSeconds;
    orientation += 0.5 * angularVelocity * elapsedSeconds;

Grandi informazioni, tuttavia, la parte con cui sono più poco chiaro è come determinare quale dovrebbe essere la forza di coppia. Ho tutti i componenti a posto come hai descritto.
Jgallant,

@Jon: hai i componenti, il che significa che hai i passaggi 1-3 e non riesci a capire come calcolare il passaggio 4? Questo è principalmente il passo difficile. Aggiungerò un po 'più di dettagli lì.
Jimmy,

3
L'orientamento essendo la somma cumulativa della velocità angolare, orientation += angularVelocity * elapsedSecondsè errato perché sopravvaluta la velocità nel corso del tempo, il che significa che framerate diversi daranno orientamenti diversi. Una formula corretta potrebbe essere: float oldVelocity = angularVelocity; angularVelocity += angularAcceleration * elapsedSeconds; orientation += 0.5f * (angularVelocity + oldVelocity) * elapsedSeconds;. Inoltre, poiché non esiste gravità, suggerisco di utilizzare invece il "centro di massa". +1 per l'ottima spiegazione però.
Sam Hocevar,

1
Parte della forza perpendicolare agirà per accelerare il centro di massa e, man mano che la forza viene applicata più vicino al centro di massa, questo fattore aumenta. La risposta è buona e molto chiara, ma sembra essere incompleta al riguardo.
Sam Watkins,

Per rispondere al mio commento, sto leggendo gli articoli di Chris Hecker sulla fisica: chrishecker.com/Rigid_body_dynamics . Si scopre che una forza o un impulso in qualsiasi punto ha l'effetto ben noto sul centro di massa secondo F = ma o a2 = a1 + p, come se il corpo non fosse in grado di ruotare. Ciò deriva dalla legge di conservazione del momento lineare. La componente della forza perpendicolare al raggio provoca anche una coppia e un cambiamento nel momento angolare, come descritto nella risposta di Jimmy.
Sam Watkins,

7

se le forze non sono troppo forti è molto più semplice simulare la rotazione usando più punti e molle che le collegano. in quel caso devi solo assumere che la tua forma sia composta da più punti collegati da molle. ogni punto rappresenta la massa e ogni altra cosa in forma ha una massa pari a zero.

primavera e punti

nella figura sopra il punto nero rappresenta le masse e la linea rossa rappresenta le molle. quindi per applicare la forza devi solo applicarlo al punto più vicino e vedrai il tuo oggetto ruotare come preferisci. per rendere la tua forma simile a una struttura solida è meglio definire molle con un alto valore di smorzamento e un alto valore di k.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.