3 Stimmen

Helfen Sie mir bei Rigid Body Physics/Transformationen

Ich möchte eine Schieberegler-Beschränkung instanziieren, die es einem Körper ermöglicht, zwischen Punkt A und Punkt B zu gleiten. Zur Instanzierung der Zwangsbedingung weise ich die beiden Körper zu, die gebunden werden sollen, in diesem Fall einen dynamischen Körper, der an die statische Welt gebunden ist, z. B. eine Schiebetür. Der dritte und vierte Parameter sind Transformationen, Bezugsrahmen A y Bezugsrahmen B . Zur Erstellung und Bearbeitung von Transformationen unterstützt die Bibliothek Quaternionen, Matrizen und Euler-Winkel.

Die Standard-Schieberegler-Beschränkung verschiebt den Körper entlang der X-Achse. Meine Frage ist: Wie stelle ich die beiden Transformationen so ein, dass Körper B entlang einer Achse gleitet, die durch seinen eigenen Ursprung und einen zusätzlichen Punkt im Raum gegeben ist?

Ich habe es ganz naiv versucht:

frameA.setOrigin(origin_of_point); //since the world itself has origin (0,0,0)
frameA.setRotation(Quaternion(directionToB, 0 rotation));

frameB.setOrigin(0,0,0); //axis goes through origin of object
frameB.setRotation(Quaternion(directionToPoint,0))

Allerdings scheinen die Quaternionen nicht so zu funktionieren, wie ich es erwartet habe. Meine mathematischen Kenntnisse sind nicht sehr gut, wenn mich also jemand aufklären könnte, warum das nicht funktioniert, wäre ich sehr dankbar. Was passiert, ist, dass der Körper entlang einer Achse gleitet, die orthogonal zur Richtung ist. Wenn ich den Rotationsteil im Quaternion-Konstruktor variiere, wird der Körper um diese Gleitrichtung gedreht.

Bearbeiten: Der Rahmen ist die Geschossphysik. Die beiden Transformationen sind die Art und Weise, wie das Schiebergelenk an jedem Körper in Bezug auf das lokale Koordinatensystem des jeweiligen Körpers befestigt ist.

Bearbeiten2 Ich könnte auch die Rotationsanteile der Transformationen durch eine orthogonale Basis festlegen, aber dann müsste ich eine orthogonale Basis zuverlässig aus einem einzigen Vektor konstruieren. Ich hoffte, dass Quaternionen dies verhindern würden.

Bearbeiten3 Ich habe mit dem folgenden Verfahren einen begrenzten Erfolg:

btTransform trafoA, trafoB;
trafoA.setIdentity();
trafoB.setIdentity();

vec3 bodyorigin(entA->getTrafo().col_t);
vec3 thisorigin(trafo.col_t);
vec3 dir=bodyorigin-thisorigin;
dir.Normalize();

mat4x4 dg=dgGrammSchmidt(dir);
mat4x4 dg2=dgGrammSchmidt(-dir);

btMatrix3x3 m(
    dg.col_x.x, dg.col_y.x, dg.col_z.x,
    dg.col_x.y, dg.col_y.y, dg.col_z.y,
    dg.col_x.z, dg.col_y.z, dg.col_z.z);
btMatrix3x3 m2(
    dg2.col_x.x, dg2.col_y.x, dg2.col_z.x,
    dg2.col_x.y, dg2.col_y.y, dg2.col_z.y,
    dg2.col_x.z, dg2.col_y.z, dg2.col_z.z);

trafoA.setBasis(m);
trafoB.setBasis(m2);

trafoA.setOrigin(btVector3(trafo.col_t.x,trafo.col_t.y,trafo.col_t.z));
btSliderConstraint* sc=new btSliderConstraint(*game.worldBody, *entA->getBody(), trafoA, trafoB, true);

GramSchmidt spiegelt jedoch immer einige Achsen der TrafoB-Matrix und die Tür erscheint auf dem Kopf stehend oder von rechts nach links. Ich hatte gehofft, dies auf elegantere Weise lösen zu können. Bearbeiten4 Ich habe eine Lösung gefunden, aber ich bin mir nicht sicher, ob dies zu einer Singularität im Constraint Solver führt, wenn der obere Vektor mit der Gleitrichtung übereinstimmt:

btTransform rbat = rba->getCenterOfMassTransform();
btVector3 up(rbat.getBasis()[0][0], rbat.getBasis()[1][0], rbat.getBasis()[2][0]);
btVector3 direction = (rbb->getWorldTransform().getOrigin() - btVector3(trafo.col_t.x, trafo.col_t.y, trafo.col_t.z)).normalize();

btScalar angle = acos(up.dot(direction));
btVector3 axis = up.cross(direction);
trafoA.setRotation(btQuaternion(axis, angle));
trafoB.setRotation(btQuaternion(axis, angle));
trafoA.setOrigin(btVector3(trafo.col_t.x,trafo.col_t.y,trafo.col_t.z));

1voto

MarkusQ Punkte 21488

Kann es sein, dass Sie die Sache viel zu kompliziert machen? Es klingt wie eine einfache parametrische Übersetzung ( x = p*A+(1-p)*B ) würde es tun. Die ganze Sache mit der Rotation/Orientierung ist ein Ablenkungsmanöver, wenn Ihr Vergleich mit der Schiebetür stimmt.

Wenn Sie dagegen versuchen, eine Interpolation zwischen zwei Orientierungen zu erreichen, müssen Sie zusätzliche Grenzen setzen, da es im allgemeinen Fall keine eindeutige Lösung gibt.

-- MarkusQ

0voto

Gareth Rees Punkte 62623

Es wäre hilfreich, wenn Sie sagen könnten, welches Framework oder welche API Sie verwenden, oder die Dokumentation für die Funktion, die Sie aufrufen, kopieren und einfügen könnten. Ohne diese Art von Details kann ich nur raten:

Hintergrund: Eine Quaternion stellt eine 3-dimensionale Drehung in Kombination mit einem Maßstab dar. (Normalerweise möchte man die Komplikationen, die mit der Verwaltung des Maßstabs verbunden sind, nicht haben, also arbeitet man mit Einheitsquaternionen, die nur Drehungen darstellen). Matrizen und Euler-Winkel sind zwei alternative Möglichkeiten zur Darstellung von Drehungen.

Ein Bezugsrahmen ist eine Position plus eine Drehung. Stellen Sie sich ein Objekt vor, das sich an einer bestimmten Stelle im Raum befindet und dann so gedreht wird, dass es in eine bestimmte Richtung zeigt.

Bild A muss also wahrscheinlich die Anfangsposition und die Drehung des Objekts darstellen (wenn sich der Schieberegler an einem Ende befindet), und Bild B die Endposition und die Drehung des Objekts (wenn sich der Schieberegler am anderen Ende befindet). Insbesondere sollten die beiden Drehungen wahrscheinlich gleich sein, da Sie das Objekt starr verschieben wollen.

Aber wie gesagt, das ist nur eine Vermutung.

Update: ist dies Physik der Kugeln ? Es scheint nicht viel an Dokumentation zu geben, oder?

0voto

Eugene Yokota Punkte 92703

Vielleicht sind Sie auf der Suche nach slerp ?

Slerp ist die Abkürzung für sphärisch lineare Interpolation, eingeführt von Ken Shoemake im Zusammenhang mit Quaternionen-Interpolation zum Zweck der 3D-Drehung zu animieren. Es bezieht sich auf eine Bewegung mit konstanter Geschwindigkeit entlang einem Großkreisbogen mit Einheitsradius, gegeben den Enden und einem Interpolations Parameter zwischen 0 und 1.

Letzten Endes braucht man immer noch die traditionelle Rotationsmatrix, um die Dinge zu drehen.

bearbeiten : Also, ich bin immer noch raten, aber ich nehme an, dass das Rahmenwerk kümmert sich um die slerping und Sie wollen die beiden Transformationen, die Anfang Zustand und den Endzustand beschreibt?

Sie können affine Transformationen übereinander stapeln. Nur muss man dabei rückwärts denken. Nehmen wir zum Beispiel an, die Schiebetür befindet sich im Anfangszustand bei (1, 1, 1) und zeigt nach Osten, und Sie wollen sie um (0, 1, 0) nach Norden schieben. Die Tür würde dann bei (1, 1, 1) + (0, 1, 0) enden.

Für den Anfangszustand drehen Sie die Tür nach Osten. Dann wenden Sie eine weitere Translationsmatrix an, um die Tür nach (1, 1, 1) zu verschieben. Für den Endzustand drehen Sie die Tür ebenfalls nach Osten und verschieben sie dann nach (1, 1, 1), indem Sie erneut die Translationsmatrix anwenden. Als Nächstes wenden Sie die Translationsmatrix (0, 1, 0) an.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X