Habe schon öffters hier eine Antwort auf meine Fragen gefunden, hoffe das klappt auch dieses mal .
Ich habe vor kurzem hier ein Topic eröffnet gehabt, wobei ich auf die Rotation eingegangen bin. Ich habe ein Cube und den wollte ich rotiren. Mithilfe von rotatef(angle,x,y,z) habe ich es hinbekommen.
Nach dem ich mein Würfel beliebig rotiert habe, möchte ich diesen Würfel im Obj-Format abspeichern, so wie er auch aus der Obj-Datei geladen wurde. Müsste jedoch feststellen, dass die Punkte, die ich aus der Datei geladen habe,nach der rotation unverändert geblieben sind. Wie kriege ich jetzt raus welcher Punkt jetzt wohin gehört. Wenn ich ja ein Punkt bei x=5 habe, und um die Y-Achse mit 90° rotiere, wandert der Punkt ja auf der Z achse bei 5. Wie kriege ich die Matrix heraus mit der ich alle meine Punkte irgendwie und ganz einfach berechnen ( wenn es geht ) kann? Weis da jemand eine Antwort?
Registriert: Di Okt 13, 2009 17:25 Beiträge: 365
Programmiersprache: C++
Hi! Mit glRotatef usw. änderst du ja nicht die Punkte deines Würfels selbst, sondern nur die ModelView-Matrix, mit der deine Grafikkarte die Vertices transformiert. Diese Matrix kannst du mit glGetFloatv und GL_MODELVIEW_MATRIX als ersten Parameter auslesen (nachdem du sie mit glRotatef angepasst hast).
Danach kann es noch sein, dass bei der Matrix Zeilen und Spalten vertauscht sind (kommt darauf an, was du für ein Matrixformat verwendest). Siehe hierzu Matrix Transposition.
Gruß mrtrain
Zuletzt geändert von mrtrain am Mi Aug 31, 2011 18:45, insgesamt 1-mal geändert.
Danke für die Antwort. Ich war einige Zeit krank, bin jedoch wieder da und kann mich endlich damit weiter beschäftigen . Was ist wenn ich das Objekt erst Rotiert, dann Skaliert, dann wider Rortiert und dann verschoben habe? Wenn ich dir Matrix auslese? Kann ich meine Vertices so berechnen, dass es auch genau die gleiche Position, Rotation und Scalierung ergibt?
Registriert: Di Okt 13, 2009 17:25 Beiträge: 365
Programmiersprache: C++
Also grundsätzlich ist es so, dass man immer erst skaliert, dann rotiert und danach verschiebt (transliert). Sonst ist das Ergebnis nicht so, wie man es wahrscheinlich haben wollte. Wenn du die verschiedenen Transformationen aber in beliebiger Reihenfolge ändern können möchtest, würde ich Skalierung, Rotation und Translation getrennt voneinander in Vektoren speichern. Also 1 Verschiebungsvektor, 1 Skalierungsvektor und 1 Vektor, der die X-Richtung des Objektes anzeigt und einen, der die Y-Richtung angibt. Den Z-Vektor kannst du mit dem Kreuzprodukt berechnen.
Aus diesen Vektoren kannst du dir dann eine Skalierungsmatrix, eine Rotationsmatrix und eine Translationsmatrix bauen, die du miteinander multiplizierst, sodass du am Ende eine Matrix hast, die alle in sich vereint. Mag sein, dass das ein wenig umständlich ist, aber ich wüsste jetzt keinen direkteren Weg.
Zuletzt geändert von mrtrain am Mi Aug 31, 2011 18:45, insgesamt 1-mal geändert.
Wenn ich dir Matrix auslese? Kann ich meine Vertices so berechnen, dass es auch genau die gleiche Position, Rotation und Scalierung ergibt?
Die Grafikkarte macht nichts anderes als die Vertices mit der Matrix zu multiplizieren. Das kannst du auch selbst machen. Über glGetFloatv erhälst du eine 4x4 Matrix, die Zahlen sind spaltenweise von oben nach unten angeordnet. Um nun einen Punkt (x,y,z) zu transformieren, multipliziere den Spaltenvektor (x,y,z,1) von rechts mit dieser Matrix. Die Matrixmultiplikation ist recht simpel: Du bildest immer das Dotprodukt (auch Skalarprodukt) einer Zeile der Matrix mit dem Vektor:
Matrix kannst du mit glGetFloatv und GL_MODELVIEW_MATRIX als ersten Parameter auslesen
Ich arbeite mit OpenGL ES 1.0 das heist ich habe GL10 objekt. Das Objekt wird in onDraw von GlSurfaceView erzeugt. In diesem Objekt steckt keine Funktion die glGetFloatv heist. Ich kann nicht auf die Matrix zugreifen. Hast vielleicht anderes VOrschlag ich kann echt nichts finden
glGetBooleanv, glGetFixedv und glGetFloatv gibt es erst ab OpenGL ES 1.1.
Du kannst dir die Rotationsmatrix aber auch einfach selbst berechnen. Da du mit Java zu arbeiten scheinst, schau dir dazu mal mein Ultimate Conquest bzw. das darunter liegende WebGLToolkit (WGT) an. Das ist zwar für GoogleWebToolkit (GWT) (*), aber letztlich doch auch Java. Worauf ich hinaus will: WGT hat eine kleine Mathebibliothek (Package com.delphigl.wgt.math) mit Klassen für Vektoren und Matrizen die du für deine Zwecke benutzen kannst. Beispielsweise kannst du mit Matrix44d.rotationAxis() genau die gleiche Matrix erzeugen wie mit glRotatef(). Mit matrix.transformCoord(vektor) kannst du dann deine Punkte transformieren.
(*) GWT nimmt sich Java 1.5 Quellcode und übersetzt das zu JavaScript damit das ohne Plugin im Browser läuft. Sofern du alle "native" Methoden raus wirfst ist das also normales Java.
Was ist in diesem Falle "w'" Ich brauche ja nur x,y,z Koordinaten. Was kann ich mit "w'" anfangen?
Die Frage hatte ich schon vorauseilend in Kurzfassung beantwortet:
Coolcat hat geschrieben:
Normalerweise enthält die Modelview-Matrix keine Projektion, daher sollte immer w' = 1 sein. Wenn w nicht 1 ist, musst du nochmal durch w teilen.
Gut das war wirklich etwas knapp, hier mal die ausführliche Erklärung: Matrizen sind sogenannte lineare Abbildungen. Eine Eigenschaft dieser ist, dass z.B. der Nullpunkt immer auf den Nullpunkt abgebildet wird. Würde man also im dreidimensionalen Raum bleiben, also einer 3x3 Matrix, würde (0,0,0) immer auf (0,0,0) abgebildet. Für eine Projektion ist zudem eine Division notwendig. (Eine Projektion ist letztlich nur Strahlensatz, man teilt durch die Entfernung.) Eine solche Division lässt sich mit linearen Abbildungen im 3D-Raum ebenfalls nicht erreichen. Man will aber diese Matrizen benutzen, weil die sich eben so schön mit einander multiplizieren lassen, man kann also alle Transformationen (Rotation, Verschiebung, Skalierung, Projektion...) in einer Matrix zusammenfassen.
Wenn in der Mathematik irgendwas nicht möglich oder umständlich scheint, ist es häufig eine gute Idee einfach mal die Anzahl der Dimensionen zu erhöhen. Aus diesem Grund bläst man hier einfach mal den 3D-Raum zu einem 4D-Raum auf und nennt das ganze "Homogeneous Coordinates". Man verwendet also einen 4D-Vektor und eine 4x4-Matrix. Solange keine Projektion durchgeführt wird ist w einfach immer 1. Das führt dazu das immer genau die Translation (Verschiebung) aufaddiert wird. Eine Division (für Projektion) ist mit einer 4x4 Matrix immer noch nicht möglich. Aber auch hier gibt es einen Trick: Man missbraucht die w-Koordinate als Nenner. Statt also zu dividieren wird einfach mit w multipliziert. Vorteil: Man kann die Division aufschieben und weiterhin bequem Matrizen multiplizieren um Transformationen zu kombinieren. Nach Anwendung der gesamten Matrix die alle Transformationen enthält braucht man dann nur nochmal einmal durch w teilen: x/w, y/w, z/w
=> Da aber die Modelview-Matrix normalerweise keine Projektion enthält ist w einfach immer 1. Entsprechend brauchst du w auch gar nicht erst berechnen.
Vielen vielen Dank ich bin endlich fertig mit der Aufgabe , hätte mir jemand gleich gesagt, dass es sich um Homogene Koordinaten handelt, wäre es bischen schneller gegangen , aber jetzt habe ich es.
Ich bedanke mich für die Lösung und die Hilfe die ich hier bekommen habe. Echt netter Forum.
Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.