Nachdem ich so viel über Transformationen gelesen habe, ist es Zeit, einen Trackball für meine App zu implementieren. Ich verstehe, dass ich einen Vektor vom Ursprung bis zum Klicken mit der Maus und dann einen anderen vom Ursprung bis zum Loslassen der Maus erstellen muss.
Meine Frage ist, muss ich die (x, y) Pixelkoordinaten in Weltkoordinaten umwandeln oder sollte ich einfach alles im Bildraum tun (wenn man bedenkt, dass der Bildraum die 2D-Projektion der Szene in Pixeln ist)?
BEARBEITEN
Die Antwort von Richie Sams ist sehr gut. Ich denke jedoch, dass ich einen etwas anderen Ansatz verfolge. Bitte korrigieren Sie mich, wenn ich falsch liege oder etwas missverstehe.
In meiner Anwendung habe ich eine SimplePerspectiveCamera
Klasse , die das empfängt position
der Kamera, die position of the target
wir betrachten, den up
Vektor, der fovy
, aspectRatio
, near
und far
Distanzen.
Mit diesen baue ich meine View- und Projektionsmatrizen. Wenn ich nun vergrößern / verkleinern möchte, aktualisiere ich das Sichtfeld und aktualisiere meine Projektionsmatrix. Wenn ich schwenken möchte, bewege ich die Position der Kamera und schaue nach dem Delta, das die Maus erzeugt.
Schließlich kann ich für Rotationen entweder eine Winkelachsentransformation oder Quaternionen verwenden. Dazu speichere ich die Pixelkoordinaten dort, wo die Maus gedrückt wurde und wenn sich die Maus bewegt, speichere ich auch die Pixelkoordinaten.
Für jedes Paar von Koordinaten kann ich den Z-Wert gegeben berechnen die Formel für eine Kugel, dh sqrt (1-x ^ 2-y ^ 2), dann nach Vektoren berechnen , die aus dem ich gehen target
zu PointMousePressed
und von target
zu PointMouseMoved
tun Kreuzprodukt Um die Rotationsachse zu ermitteln, verwenden Sie eine beliebige Methode, um die neue Kameraposition zu berechnen.
Mein größter Zweifel ist jedoch, dass die (x, y, z) -Werte in Pixelkoordinaten angegeben sind und bei der Berechnung der Vektoren, die ich verwende target
, ein Punkt in Weltkoordinaten ist. Beeinflusst diese Vermischung des Koordinatensystems nicht das Ergebnis der Rotation, die ich versuchen möchte?
z
Wert einer Kugel mit Radius berechnen kannr
, bin mir jedoch nicht sicher, ob diese Kugel im Welt- oder Bildraum lebt und welche Auswirkungen dies hat. Vielleicht überdenke ich das Problem.Antworten:
Angenommen, Sie meinen eine Kamera, die sich aufgrund der Mausbewegung dreht:
Eine Möglichkeit zur Implementierung besteht darin, die Kameraposition und ihre Drehung im Raum zu verfolgen. Hierfür bieten sich sphärische Koordinaten an, da Sie die Winkel direkt darstellen können.
Die Kamera befindet sich bei P, das durch m_theta, m_phi und m_radius definiert ist. Wir können uns frei drehen und bewegen, wo immer wir wollen, indem wir diese drei Werte ändern. Wir schauen uns jedoch immer m_target an und drehen es. m_target ist der lokale Ursprung der Kugel. Es steht uns jedoch frei, diesen Ursprung im Weltraum zu bewegen, wo immer wir wollen.
Es gibt drei Hauptfunktionen der Kamera:
In ihrer einfachsten Form sind Rotate () und Zoom () trivial. Die beiden Modifikationen m_theta, m_phi und m_radius lauten:
Schwenken ist etwas komplizierter. Ein Kameraschwenk ist definiert als Bewegen der Kamera nach links / rechts und / oder nach oben / unten in Bezug auf die aktuelle Kameraansicht. Am einfachsten können wir dies erreichen, indem wir unsere aktuelle Kameraansicht von sphärischen Koordinaten in kartesische Koordinaten konvertieren. Dies gibt uns eine nach oben und rechts Vektoren.
Also, zunächst wandeln wir unser sphärisches Koordinatensystem kartesisch zu unserem bekommen Look Vektor. Als nächstes machen wir das Vektorkreuzprodukt mit dem Welt- Up- Vektor, um einen richtigen Vektor zu erhalten. Dies ist ein Vektor, der direkt rechts von der Kameraansicht zeigt. Zuletzt machen wir ein anderes Vektor-Kreuzprodukt, um den Vektor der Kamera zu erzeugen.
Um die Pfanne zu beenden, wir bewegen m_target entlang der nach oben und rechts Vektoren.
Eine Frage, die Sie sich möglicherweise stellen, lautet: Warum immer zwischen kartesisch und sphärisch konvertieren? (Sie müssen auch konvertieren, um die View-Matrix zu erstellen.)
Gute Frage. Auch ich hatte diese Frage und versuchte ausschließlich kartesisch zu sprechen. Sie haben Probleme mit Rotationen. Da Gleitkommaoperationen nicht exakt sind, häufen sich bei mehreren Umdrehungen Fehler an, die der Kamera langsam entsprachen und ungewollt abrollen.
Also blieb ich am Ende bei sphärischen Koordinaten. Um den zusätzlichen Berechnungen entgegenzuwirken, habe ich die Ansichtsmatrix zwischengespeichert und erst berechnet, wenn sich die Kamera bewegt.
Der letzte Schritt ist die Verwendung dieser Kamera-Klasse. Rufen Sie einfach die entsprechende Member-Funktion in den MouseDown / Up / Scroll-Funktionen Ihrer App auf:
Die m_camera * -Faktorvariablen sind lediglich Skalierungsfaktoren, die ändern, wie schnell sich Ihre Kamera dreht / schwenkt / rollt
Der Code, den ich oben habe, ist eine vereinfachte Pseudocode-Version des Kamerasystems, das ich für ein Nebenprojekt erstellt habe: camera.h und camera.cpp . Die Kamera versucht das Maya-Kamerasystem zu imitieren. Der Code ist kostenlos und Open Source. Sie können ihn also auch in Ihrem eigenen Projekt verwenden.
quelle
Für den Fall, dass Sie einen Blick auf eine fertige Lösung werfen möchten. Ich habe einen Port von THREE.JS TrackBall-Steuerelementen in C ++ und C #.
quelle