Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Mai 22, 2024 03:14

Foren-Übersicht » Programmierung » Mathematik-Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Sa Jul 12, 2008 20:38 
Offline
DGL Member

Registriert: Do Jun 22, 2006 19:13
Beiträge: 52
Wohnort: Lübeck
Hallo zusammen,

ich such verzweifelt nach dem richtigen Weg eine 4x4 Matrix zu errechnen die die Transformation und die die Projektion in sich trägt.

Mit Hilfe dieser Matrix soll dann mit Angabe der Höhe und der Breite eines Bildes ein Vector 2-Dimensional auf dem Bild dargestellt werden.

Nun fragt ihr euch bestimmt, warum will der denn das so machen. Aus dem einfachen Grund:

Diese 4x4 Matrix dient als Schnittstelle zwischen 2 Applikationen, die eine erstellt ein Bild inclusive der 4x4 Matrix und die andere verwendet diese dann um einjen Vector 2Dimensional darstellen zu können.

Mit diesen beiden Applikationen funktioniert das auch super. (für die erstellende Applikation existiert leider kein Sourcecode)

Nun soll es eine weitere Applikation geben, die eine unbestimmte Anzahl von Vectoren mit der Kamera so betrachtet wie es der Benutzer gerne hätte. Nach dem Ausrichten der Camera soll nun diese 4x4 Matrix erzeugt werden.

Ich habe schon so viele Variationen ausprobiert und bekomme es einfach nicht hin. (zumindet nicht über diesen Weg. Mit Verwendung von glProject klappt das alles super aber das ist ja leider nicht gefordert).

Im Anhang befindet sich ein Dokument, in dem erklärt wird, wie diese 4x4 Matrix erstellt wird.

Einer meiner Ansätze ist dieser hier um die 4x4 Matrix zu bestimmen:


Code:
  1.  
  2. function CrossProduct(aVector1, aVector2: TGLVector): TGLVector;
  3. begin
  4.     Result.X := ((aVector1.Y * aVector2.Z) - (aVector1.Z * aVector2.Y));
  5.     Result.Y := ((aVector1.Z * aVector2.X) - (aVector1.X * aVector2.Z));
  6.     Result.Z := ((aVector1.X * aVector2.Y) - (aVector1.Y * aVector2.X));
  7. end;
  8.  
  9. function NegativeVector(aVector: TGLVector): TGLVector;
  10. begin
  11.   Result.X := aVector.X * (-1);
  12.   Result.Y := aVector.Y * (-1);
  13.   Result.Z := aVector.Z * (-1);
  14. end;
  15.  
  16. function ScalarProduct(aVector1, aVector2: TGLVector): GLDouble;
  17. begin
  18.   Result := (aVector1.X * aVector2.X + aVector1.Y * aVector2.Y +
  19.     aVector1.Z * aVector2.Z);
  20. end;
  21.  
  22. function Multiply(aMatrix1, aMatrix2: TMatrix): TMatrix;
  23. var
  24.   TempMatrix: TMatrix;
  25. begin
  26.   glPushMatrix;
  27.     glLoadMatrixd(@aMatrix1);
  28.     glMultMatrixd(@aMatrix2);
  29.     glGetDoublev(GL_MODELVIEW_MATRIX, @TempMatrix);
  30.   glPopMatrix;
  31.   Result := TempMatrix;
  32. end;
  33.  
  34. procedure GetMatrix;
  35. var
  36.   PVec: TGLVector;
  37.   UVec: TGLVector;
  38.   VVec: TGLVector;
  39.   WVec: TGLVector;
  40.   P: TMatrix;
  41.   T: TMatrix;
  42. begin
  43.   UVec := CrossProduct(FCamera.ViewDirection, FCamera.UpVector);
  44.   WVec := NegativeVector(FCamera.ViewDirection);
  45.   VVec := CrossProduct(WVec, UVec);
  46.   PVec := FCamera.Position;
  47.  
  48.   T[0, 0] := UVec.X;
  49.   T[0, 1] := VVec.X;
  50.   T[0, 2] := WVec.X;
  51.   T[0, 3] := 0;
  52.   T[1, 0] := UVec.Y;
  53.   T[1, 1] := VVec.Y;
  54.   T[1, 2] := WVec.Y;
  55.   T[1, 3] := 0;
  56.   T[2, 0] := UVec.Z;
  57.   T[2, 1] := VVec.Z;
  58.   T[2, 2] := WVec.Z;
  59.   T[2, 3] := 0;
  60.   T[3, 0] := ScalarProduct(NegativeVector(UVec), PVec);
  61.   T[3, 1] := ScalarProduct(NegativeVector(VVec), PVec);
  62.   T[3, 2] := ScalarProduct(NegativeVector(WVec), PVec);
  63.   T[3, 3] := 1;
  64.  
  65.   P[0, 0] := 2 / (FOrthoRechts - FOrthoLinks);
  66.   P[0, 1] := 0;
  67.   P[0, 2] := 0;
  68.   P[0, 3] := 0;
  69.   P[1, 0] := 0;
  70.   P[1, 1] := 2 / (FOrthoOben - FOrthoUnten);
  71.   P[1, 2] := 0;
  72.   P[1, 3] := 0;
  73.   P[2, 0] := 0;
  74.   P[2, 1] := 0;
  75.   P[2, 2] := (2 / (10000 - 1)) * (-1);
  76.   P[2, 3] := 1;
  77.   P[3, 0] := ((FOrthoRechts + FOrthoLinks) / (FOrthoRechts - FOrthoLinks)) * (-1);
  78.   P[3, 1] := ((FOrthoOben + FOrthoUnten) / (FOrthoOben - FOrthoUnten)) * (-1);
  79.   P[3, 2] := ((10000 + 1) / (10000 - 1));
  80.   P[3, 3] := 1;
  81.  
  82.   T := Multiply(P, T);
  83. end;
  84.  


Kann mir jemand helfen ?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 12, 2008 21:02 
Offline
DGL Member

Registriert: Do Jun 22, 2006 19:13
Beiträge: 52
Wohnort: Lübeck
Sorry, der Anhang ist zu groß.
Hab ihn nun auf einer anderen Webseite untergebracht.

http://www.mkcoolsoft.de/4x4Matrix.PDF


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 13, 2008 00:07 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo,
Die Transformationsmatrix aus dem PDF-File kann ich nicht beurteilen, denn ich rechne normalerweise nicht so. Wenn Du Das überprüfen willst, kannst Du das doch ganz einfach, wenn Du eine kleine OpenGL-Anwendung mit geprüften Testdaten erstellst und Dir die Model-Matrix per glGet rausziehst und mit Deiner eigenen Berechnung vergleichst. Dann siehst Du, ob Deine Berechnung stimmt.

Was die Projektionsmatrix betrifft: beim flüchtigen Drüberschauen kam es mir so vor, als hättest Du die Einträge (3,2) und (2,3) vertauscht. ich habe es mit der Matrix in unserem Wiki verglichen, von der ich ganz genau weiss, dass sie stimmt: http://wiki.delphigl.com/index.php/glFrustum. Aber die Wiki-Matrix stimmt auch mit der Matrix überein, die in Deinem PDF-File angegeben ist. Grundsätzlich kann man mit der obigen Methode hier ganz genauso vorgehen.

Ich empfehle Dir auch sehr die Geometry.pas: da kannst Du jedenfalls mal Berechnungsfehler ausschließen.

Wie Du die Matrizen multiplizierst, hat mich sehr gewundert, denn wenn Du schon OpenGL verwendest, um die Matrizenmultiplikation durchzuführen, dann könntest Du doch eigentlich auch zu allem anderen glRotate/glTranslate benutzen. Und vielleicht sollte ich Dich noch daran erinnern, dass Du zwar ProjektionsMatrix und ModelViewMatrix multiplizieren und das Produkt im ModelView-Modus laden kannst, aber trotzdem nicht vergessen darfst, beim endgültigen Rendern vorher die Projection Matrix mit LoadIdentity zu initialisieren; denn OpenGl hat auf jeden Fall etwas in der Projection Matrix gespeichert, und wenn Du dort keine Einheitsmatrix geladen hast, steht möglicherweise Müll drin (oder, noch schlimmer, lauter Nullen), und dann landet auf dem Bildschirm auch Müll (oder, noch schlimmer: gar nichts).

Außerdem wüßte ich gern, was das für eine Quelle ist, die Du da hochgeladen hast?
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 17, 2008 15:24 
Offline
DGL Member

Registriert: Do Jun 22, 2006 19:13
Beiträge: 52
Wohnort: Lübeck
Hallo Traude,

ich habe ein wenig Hoffnung, dass du es schaffst ein wenig Licht ins Dunkle zu bringen.
Ich habe mal ein Projekt zusammengestellt, das als Demo dienen soll, um mein Problem besser darstellen zu können.

Ich benutze die Camera-Klasse aus dem DGL-Tutorial.

Die Routinen "PointToJpegCoords" und "MultiplyVectorMatrix" werden dazu verwendet, um den 2D-Punkt aus der 4x4Matrix (die vorgegeben wird) zu ermitteln. (Das funktioniert auch immer sehr gut).

Nun möchte ich mir die Matrix aber selber erstellen. Dieses versuche ich in der Methode "VectorTo2D" in der Demo.pas.
Ich denke, dass ich mich an die Formeln gehalten habe, die sich in dem zuvor hochgeladenen PDF befinden.

Das Problem ist folgendes:
Wenn ich die Camera verschiebe oder rotiere, befindet sich der ermittelte 2D-Punkt immer in der Mitte des Bildes.
Das zoomen funktioniert aber.

Ich habe auch deinen Rat befolgt und habe die Rechen-Routinen aus der Geometry.pas verwendet.

Ich wäre dir/euch sehr sehr dankbar, wenn du/ihr mal einen Blick auf die Sache werfen könntest.

Hier der Link für das Demo-Projekt


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 17, 2008 17:17 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Ich habe es runtergeladen und sehe es mir heute abend an.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 18, 2008 13:08 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Ich habe es mir angeschaut. Ich möchte vorausschicken, dass ich das Problem nicht dingfest gemacht habe. Was ich herausgefunden habe, ist folgendes:

1. Du setzt einen festen Punkt (100,100) fest, der die linke ober Ecke eines Quadrats sein soll, das man per Tastatur in seiner Lage verändern kann.

2. Dann erzeugst Du aus den Kameradaten eine Modelviewmatrix, gemäß den Angaben aus dem Buch.

3. Weiters erzeugst Du eine Ortho-Projektionsmatrix.

4. Modelviewmatrix und Projektionsmatrix werden mulzipliziert: eine gemeinsame Matrix;

5. Der obige feste Punkt wird nun mit dieser Matrix multipliziert.

6. Dann wird der Punkt noch transformert, um ihn in den Texturraum zu bringen (/0,5+0,5) und anschließend mit einer vorgegebenen Breite und Höhe multipliziert. Das heißt, eigentlich transformierst Du den Punkt hin und wieder zurück.

Passieren tut dabei Folgendes: beim erstenmal stimmt die Berechnung, und der rote Punkt sitzt am Ende brav auf dem linken oberen Eck des Quadrats. Sobald man eine Cursortaste auch nur anrührt (und damit die Kamera verändert), kommen für den Punkt Koordinaten heraus, die so klein sind, dass sie von der Berechnung (/0,5+0,5) nur mehr das 0,5 behalten, und wenn Du ihn auf die vorgegebene Breite skalierst, sitzt er auf 0,5 der Breite und 0,5 der Höhe und das ist eben die Mitte des Bildes. Der Punkt wird irgendwo "erwürgt".

Um jetzt zu beurteilen, wo das genau stattfindet, weiß ich zuwenig über Dein Programm.

Ich vermute, dass die Kamera der Missetäter ist. Aber das musst Du Dir selber anschauen, denn dann müsste ich mich viel mehr damit beschäftigen. Da ich davon ausgehe, dass Du mir kein Gehalt zahlen willst :wink: , muss ich daher jetzt passen.
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 18, 2008 15:48 
Offline
DGL Member

Registriert: Do Jun 22, 2006 19:13
Beiträge: 52
Wohnort: Lübeck
Vielen vielen Dank für Deine schnelle Antwort.

Ich denke, ich werden mal ein paar Schritte zurück gehen und auf das "Camera-Objekt" vorerst verzichten.
Mal schauen, ob deine Vermutung stimmt.

Komisch ist nur, wenn man den 2D-Punkt mit Hilfe von "glProject" ermittelt ist alles OK. In Anbetracht dieser Tatsache hatte ich angenommen, dass ich in der Berechnung der beiden Matritzen einen oder mehere Fehler gemacht habe.

Nun denn, schauenwir mal was dabei raus kommt. Ich werde meine Erkenntnis dann in diesem Post Kund tun.

Aber trotzdem vielen Dank nochmal!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 18, 2008 19:37 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Ich habe noch einmal drübergelesen, weil mir eingefallen ist, dass man ja die wirkliche Kameramatrix - die Du ja hast - mit der "künstlichen" Modelviewmatrix vergleichen könnte. Dabei habe ich die Methode TCamera.Apply entdeckt. In dieser Methode wird die ModelView-Matrix geladen, aber anschließend wird noch ein glTranslate durchgeführt. Das bedeutet, Deine Kameramatrix ist nicht mit der ModelViewmatrix identisch. Sie sollte es aber sein.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Foren-Übersicht » Programmierung » Mathematik-Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]