Registriert: Mi Mär 09, 2005 15:54 Beiträge: 372 Wohnort: München
Programmiersprache: Delphi, C#, FPC
Ich versuche gerade, eine Spiegelung per Stencil-Puffer zu realisieren. Bisher klappt alles ganz gut, nur das ich eine einschränkung habe, die mir nicht so ganz gefällt:
Ich skaliere die Spiegelfläche mit Hilfe von glScale(1, -1, 1) um eine Spiegelung am Boden zu erziehlen. Doch ich möchte jetzt nicht nur waagerecht spiegeln, sondern auch z.B. an einer um 45° gedrehten und 70° geneigten Oberfläche (nur so als Beispiel).
Von der Oberfläche (ist jetzt mal einfach ein Viereck), kenne ich alle 4 Punke und somit auch den Normalenvektor.
Wenn ich jetzt die Spiegelungsroutine richtig verstanden habe, müsste ich jetzt die komplette Welt per glScale(x, y, z) skalieren, um ein korrektes Spiegelbild zu bekommen. Doch wie komme ich auf x, y und z? Den Normalenvektor einfach zu invertieren reicht ja nicht (sonst würde das glScale(1, -1, 1) nicht funzen, da der nVektor (0, 1, 0) ist)
Ich denke, das ist gar nicht so einfach. Du solltest ja bedenken, dass man die ebene um so ca. unendlich verschiedene Achsen neigen kann. Das heißt, da musst du dir noch etwas genaueres zb eine Neigungsachse einfallen lassen, sonst wird das kaum was werden. Wenn du diese Achse hast, sollte sich der Rest über das Skalaprodukt errechnen lassen:
cos y = Vektor1 Skala Vektor 2 / (Laenge(Vektor1) * Laenge(Vektor2);
Also ich würde das so angehen: Spiegelmatrizen sind immer dieser 3x3 Matrix ähnlich:
Code:
-100
010
001
Du musst nur das Koordinatensystem finden, in dem die Matrix so aussieht. Das geht aber leicht. Es muss sich um ein Orthonormalsystem handeln und einen Basisvektor kennst du bereits - nämlich deine Normale. Fehlen noch zwei weitere Vektoren, die du fast beliebig wählen kannst, sie müssen nur Orthonormal sein. Nimm dazu deinen Normalenvektor her. Suche dir die Komponente des Vektors heraus, die den kleinsten Betrag aufweist. Setze diese Komponente auf 1. Bilde das Kreuzprodukt aus Normalenvektor und dem eben bestimmten Vektor. Wir nennen diesen einmal b2. Normiere b2 (so skalieren, daß er Länge 1 besitzt). Jetzt bilde das Kreuzprodukt aus n und b2, nenne diesen Vektor b3. Dieser ist bereits normiert und du hast eine Basis aufgespannt, in der die Gewünschte Spiegelung genau wie oben aussieht. Damit kennen wir aber auch schon eine Rotationsmatrix, die unser Koordinatensystem wieder ins globale Koordinatensystem zurückdreht: Man schreibt dazu einfach n, b1, b2 nebeneinander und tue so als wäre es eine Matrix K. Die Einträge sehen dann so aus:
Code:
n[1] b2[1] b3[1]
n[2] b2[2] b3[2]
n[3] b2[3] b3[3]
Transponieren wir diese Matrix K, erhalten wir die inverse Matrix K^-1 (Eigenschaft von Rotationsmatrizen.). Sieht so aus:
Code:
n[1] n[2] n[3]
b2[1] b2[2] b2[3]
b3[1] b3[2] b3[3]
Diese Matrix dreht also unser globales Koordinatensystem ins Koordinatensystem unserer Drehmatrix. Jetzt müssen wir also nur noch die Matrizen zusammenmultiplizieren:
Code:
KSK^-1
Diese Indexschlacht beim zusammenmultiplizieren überlasse ich Dir. Im Matrixartikel im Wiki steht im Bedarfsfall wie das geht - falls Du es nicht wissen solltest (ansonsten ist das Wissen, das man sich für Grafik ganz schnell aneigenen sollte).
Soweit so gut. Wahrscheinlich willst Du die Sache jetzt noch als OpenGl Matrix haben. Gibts aber ganz einfach: Man schreibt an die enstandene Matrix rechts unten noch eine 1 hin und füllt nach oben und links jeweils von der 1 ausgehend mit Nullen auf. Schon hat man aus einer 3x3 Matrix eine passende 4x4 OpenGl Matrix gemacht.
Also zwei Dinge die ich gesehen habe:
1. Du suchst nicht die Betragsmäßig kleinste Komponente, sondern die absolut kleinste. Das ganze mit Betrag zu machen hätte schon seinen sinn.
2. Du musst die 3 angegebenen Matrizen miteinander multiplizieren - mach das am besten auf einem Blatt Papier. Diese Matrix muss dann mit MultMatrix weitergereicht werden. Bislang rechnest du nur mit K^-1. Diese beschreibt aber nur eine Drehung. Du musst stattdessen K*S*(K^-1) verwenden, dann sollte die Sache schon besser klappen.
Mitglieder in diesem Forum: Google [Bot] und 18 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.