Spielephysik mit Zwangsbedingungen ed
Niesitzen.
böse Test-Editier-Aktion!
Zwangsbedingungen ed
Definition ed
Mathematisch gesehen kann man die Bewegung einschränken, indem man Funktionen der Objekt-Positionen definiert und fordert, dass diese immer Null sein sollen ( \( C ( \vec{P_1}, \vec{P_2},... ) \stackrel{\mathrm{!}}= 0 \) ).
Will man zum Beispiel, dass zwei Objekte A und B immer den selben Abstand d zueinander haben, so definiert man dazu eine Funktion \( C ( \vec{P_A}, \vec{P_B} ) = \left| \vec{P_A} - \vec{P_B} \right| - d \) . Will man das Objekt A auf einer Ebene mit Normalenvektor \( \vec{n} \) und Abstand d zum Koordinaten-Ursprung halten, so ist die Funktion \( C ( \vec{P_A} ) = \langle \vec{P_A} , \vec{n} \rangle - d \) .
Es können auch mehrere Zwangsbedingungen gleichzeitig gestellt werden, dazu werden die einzelnen C-Funktionen zu einer vektorwertigen Funktion zusammengefasst, deren Komponenten alle einzeln Null sein sollen. Von hier an soll C vektorwertig sein!
Physik ed
Da trotz eines Gelenkes weiterhin die Newtonschen Bewegungsgleichungen gelten sollen, müssen Zwangsbedingungen die Bewegung durch Erzeugung von Kräften steuern, diese nennt man Zwangskräfte. Die Aufgabe wird es sein, aus den schon wirkenden Kräften und den Zwangsbedingungen die nötigen Zwangskräfte zu berechnen.
Liegt zum Beispiel ein Objekt auf einer horizontalen Ebene, wärend es die Gravitation nach unten zieht, muss die Zwangskraft das Objekt mit gleicher Stärke nach oben ziehen, damit es in der Ebene "schwebt".
Bewegungsgleichungen ed
Punktmassen ed
Diese Ideen sind hauptsächlich aus der Dokumentation der Bibliothek OpenDynamics (ODE) und den Artikeln der SIGGRAPH-Gruppe geklaut, deswegen werde ich mich auch an deren Nomenklatur halten...
Aus den einzelnen Variablen der Teilchen lassen sich "kollektive" vektorwertige Variablen bauen mit einer höheren Zahl von Komponenten (bei N Objekten 3N Komponenten):
Position \( q := \left( \begin{array}[c] \vec{P_1} \\ \vdots \\ \vec{P_N} \end{array} \right) \) , Geschwindigkeit \( \dot{q} := \left( \begin{array}[c] \vec{V_1} \\ \vdots \\ \vec{V_N} \end{array} \right) \) , bisherige Kraft \( Q_0 := \left( \begin{array}[c] \vec{F_1} \\ \vdots \\ \vec{F_N} \end{array} \right) \) , sowie die Massen
$ M := \left( \begin{array}{cccccc}
m_1 & 0 & 0 & & & \\
0 & m_1 & 0 & & & \\
0 & 0 & m_1 & & & \\
& & & m_2 & & \\
& & & & \ddots & \\
& & & & & m_N \\
\end{array} \right)
$ Außerdem benötigt man die partiellen Ableitungen der C-Funktionen nach den Koordinaten q, diese ergeben eine Matrix \( J := \frac{ \partial C }{ \partial q } := \left( \frac{ \partial C_i }{ \partial q_j } \right)_{ij} \) . Bei s Zwangsbedingungen ist das eine \( s \times 3N \) -Matrix.
Unter der Vereinfachung, dass C explizit zeitunabhängig ist , gilt für die totale Zeitableitung \( \dot{C} = \frac{ \partial C }{ \partial q } \dot{q} = J \dot{q} \) und die zweite Zeitableitung ist \( \ddot{C} = \dot{J} \dot{q} + J \ddot{q} \) . Es wird gefordert, dass C immer Null sein soll, somit sind auch dessen beide Zeitableitungen Null!
$ \dot{J} \dot{q} + J \ddot{q} = 0 $ Die Newtonsche Bewegungsgleichung ("Kraft gleich Masse mal Beschleunigung") lässt sich mit unseren Variablen schreiben als \( Q = M \ddot{q} \Rightarrow \ddot{q} = W Q = W ( Q_0 + Q_C ) \) . Im letzten Schritt wurde die Kraft Q in die bereits bekannte Kraft \( Q_0 \) und die unbekannte Zwangskraft \( Q_C \) aufgeteilt. Das ergibt insgesamt:
$ J W Q_C = - \dot{J} \dot{q} - J Q_0 $ Nun ein komplizierterer Schritt! Die Menge aller Koordinaten q, für die die Funktion C(q) Null ist, spannen eine Fläche im 3N dimensionalen Raum der q-Koordinaten auf. Man fordert, dass die Zwangskraft stets senkrecht zu dieser Fläche steht. Da die Zwangskraft nun auch zu den Geschwindigkeiten senkrecht ist, wird durch die Zwangsbedingungen keine Arbeit verrichtet (d'Alambertsches Gesetz).
Mit einer größeren Portion Phantasie kommt man zum Schluss, dass die Zwangskraft im Bild der zu J transponierten Matrix sein muss (!). Das bedeutet, es gibt einen s dimensionalen Vektor \( \lambda \) , für den \( Q_C = J^T \lambda \) gilt. (Man kann sich dazu vorstellen, dass die Spaltenvektoren von \( J^T = \left( \frac{ \partial C_j }{ \partial q_i } \right)_{ij} = \left( abla C_i \right)_{i} \) gerade der Gradient einer einzelnen C-Komponenten-Funktion ist und somit jeweils senkrecht auf der Null-Fläche steht) Also insgesamt:
$ J W J^T \lambda = - \dot{J} \dot{q} - J Q_0 $ Dieses lineare Gleichungssystem muss nun in jedem Berechnungsschritt der Engine nach \( \lambda \) gelöst werden und dann ergibt sich die Zwangskraft durch \( Q_C = J^T \lambda \) .
Allerdings gilt diese Formel nur in einer perfekten Welt, denn sie folgte nur aus der Bedingung, dass die Beschleunigung (2. Ableitung) von C verschwindet. Ist allerdings die erste Ableitung oder gar schon C selbst ungleich Null, so ändert diese Gleichung auch nichts daran. Das ist schrecklich! Computer berechnen nur gerundete Werte, diese Fehler würden sich mit der Zeit aufaddieren, weswegen Objekte, die eigentlich durch ein Gelenk verbunden sind, auseinander driften. Noch schlimmer ist sogar, dass im Falle einer Zwangs-Kreisbahn automatisch eine Spiralbahn entsteht (Problem der Euler-Methode, die aus den anliegenden Kräften die Objektbahnen bestimmt). Deswegen wird die Formel durch Dämpfungsterme verbessert:
$ \begin{array}{|c|}
\hline
J W J^T \lambda = - \dot{J} \dot{q} - J Q_0 - k_s C - k_d \dot{C} \\
\hline\(^_^)/
...neue Kraft,....explizit M und W angeben...
Beispiele ed
ganz viel Vandalismus!!!!