Hallo, ich will mit dem PC dreidimensionale Objekte zeichen, mein Programm will aber 2D-Koordinaten. Also suche ich eine handliche Library die mir das umrechnet. Ich meine das etwa so: Ich: Punkt (x,y,z)=(3,4,5); Kamera (x,y,z)=(0,0,0) schaut in diese und diese Richtung Programm: Punkt an Position (x,y)=(4.7, 2.9) zeichnen. Eigentlich wollte ich das selber schreiben aber ich steig trotz Leistungskurs vor zig Jahren nicht durch die Mathematik. :-( Gefunden habe ich http://www.base32.de/3dengine.html aber da fehlt irgendwie ein Beispiel wie der ganze Kram zu verwenden ist.
Achso, parallele Linien sollen parallel bleiben, also nicht auf einen weit entfernten Punkt zulaufen.
Mathedoofi schrieb: > Gefunden habe ich http://www.base32.de/3dengine.html aber da fehlt > irgendwie ein Beispiel wie der ganze Kram zu verwenden ist. In der Datei "3d.c" ist doch ein Beispiel drin. Da muss man sich halt ein bisschen durchhangeln. Aber da die Lib ja für nen mc ist, weiß ich nicht, ob das das ist, was du suchst. In welcher Programmiersprache hättest du es denn gerne?
Wie komplex soll es denn werden? Einfache Zentralperspektive is simpel: X = (a*px)/pz Y = (a*pz)/pz "a" ist der Abstand des Betrachters zum (virtuellen) Bildschirm px,py,pz die 3D Koordinate und X,Y die entsprechende 2D Bildschirm-Koordinate. Allerdings musst Du Dich selbst um verdeckte Linien/Flächen etc kümmern. Für eine Bewegung/Kippen der Kamera muss man dabei die Objekte manipulieren. Aber für einfache Sachen taugt's. Ansonsten bleibt die Frage, auf welchem System und wass die Anforderungen sind. Bitmapping gewünscht? I.d.R sollte man OpenGL oder directX nehmen...
Mathedoofi schrieb: > Achso, parallele Linien sollen parallel bleiben, also nicht auf einen > weit entfernten Punkt zulaufen. ? dann gibt es aber keine Perspektive/Tiefeneffekt. Lass die 3 Koordinate einfach weg...
Das ist lediglich eine Matrixmultiplikation, den Overkill einer "Bibliothek" braucht's dazu nicht: Gegeben ist ein Punkt P, der in die Ebene zu projizieren ist, die durch zwei Vektoren X und Y aufgespannt wird. Zusammen mit einem dritten Vektor Z, der Blickrichtung, wird der ganze Raum aufgespannt, in dem P liegt. Da es sich um eine Parallelprojektion handeln soll, liegt o.E. der Koordinatenursprung in der Ebene. Bezeichnet nun k = (x, y, z) den Koordinatenvektor von P bezüglich dieser Basis B = { X, Y, Z }, dann ist P offenbar:
und der gesuchte Koordinatenvektor k
Die z-Koordinate ist der Abstand (in Einheiten von |Z|) zur Ebene und interessiert nicht. Die beiden Koordinaten x und y sind die gesuchten 2D-Koordinaten. Die Matrix B^-1 ist eine 3×3 Matrix; da z nicht benötigt wird, kann man einfach die dritte Zeile entfernen und erhält damit eine Projektion R³ -> R² Das Ergebnis hängt davon ab, wie die Vektoren X und Y in die Ebene gelegt werden; dies ist nicht eindeutig.
benji schrieb: > In der Datei "3d.c" ist doch ein Beispiel drin. Oh, hab ich glatt übersehen. So wirklich verstanden habe ich die Library trotzdem nicht. ( > Aber da die Lib ja für nen mc ist, weiß ich > nicht, ob das das ist, was du suchst. Das könnte man ja umschreiben. > In welcher Programmiersprache hättest du es denn gerne? Im Idealfall C, aber da bin ich flexibel solange die verwendete Sprache einigermaßen verständlich ist... ) Michael Potthoff schrieb: > Wie komplex soll es denn werden? So einfach wie möglich... Michael Potthoff schrieb: > Mathedoofi schrieb: >> Achso, parallele Linien sollen parallel bleiben, also nicht auf einen >> weit entfernten Punkt zulaufen. > > ? dann gibt es aber keine Perspektive/Tiefeneffekt. Lass die 3 > Koordinate einfach weg... Verstehe ich gerade nich... Wenn ich einen Würfel mit parallelen Kanten zeichne und von oben schräg drauf gucke habe ich doch meine Perspektive?!? Johann L. schrieb: > Das ist lediglich eine Matrixmultiplikation, den Overkill einer > "Bibliothek" braucht's dazu nicht: > [...] Ah, das ist Mathe in verträglichen Dosen, nicht dieses Fachchinesisch wie bei Wikipedia... Die Transformation lässt sich also durch eine Matrixmultiplikation darstellen, das wirkliche Problem ist dann ja wohl das Finden der Transformationsmatrix(?) B bzw B^-1 richtig? Was ich nicht verstehe: Wenn ich 2 bzw 3 Vektoren nehme um meine "Leinwand" darzustellen bekomme ich doch unendlich viele davon, muss da nicht noch irgendwo ein Punkt dazu der auf dieser Leinwand liegt (Koordinatenursprung)? Ich ärgere mich übrigens gerade ziemlich das ich meine Formelsammlung verbummelt hab...
OK, ich habe mich wohl geirrt. Ich suche eine Projektion die wie ein Foto aussieht, also anscheinend NICHT die Parallelprojektion. Aktuell wühle ich mich durch http://en.wikipedia.org/wiki/3D_projection#Perspective_projection
In openCV gibt es projectPoints(), das auf den ersten Blick Dein Problem lösen könnte. Handlich ist openCV aber definitiv nicht.
Da es für den PC ist: Such dir ein OpenGL Tutorial. Gibts wie Sand am Meer. Dann hast du mit der Mathe dahinter erst mal nichts zu tun, obwohl es hilft wenn man sie versteht. Komplexe Sachverhalte lassen sich nun mal nicht mit Küchenutensilien erklären, so dass man sie in allen Details versteht.
Tom K. schrieb: > In openCV gibt es projectPoints(), das auf den ersten Blick Dein Problem > lösen könnte. Handlich ist openCV aber definitiv nicht. Puh, ne, das ist wirklich nicht handlich. Danke trotzdem! Karl Heinz Buchegger schrieb: > Da es für den PC ist: > > Such dir ein OpenGL Tutorial. Gibts wie Sand am Meer. Dann hast du mit > der Mathe dahinter erst mal nichts zu tun, obwohl es hilft wenn man sie > versteht. Komplexe Sachverhalte lassen sich nun mal nicht mit > Küchenutensilien erklären, so dass man sie in allen Details versteht. Unterschätze meine Küche nicht! :-) Ne, ernsthaft, ich brauche eigentlich nur einen Satz Formeln (X,Y)=f(x,y,z und Kameraposition), verstehen muss ich die garnicht wenn genau beschrieben ist was was ist. Ich wühle mich gerade durch diverse Tutorials und Uniskripte, mal sehen was da raus kommt...
Karl Heinz Buchegger schrieb: > Such dir ein OpenGL Tutorial genau das! http://wiki.delphigl.com/index.php/Hauptseite Mathedoofi schrieb: > verstehen muss ich die garnicht würde aber ungemein helfen.
Mathedoofi schrieb: > Unterschätze meine Küche nicht! :-) Ne, ernsthaft, ich brauche > eigentlich nur einen Satz Formeln (X,Y)=f(x,y,z und Kameraposition), > verstehen muss ich die garnicht wenn genau beschrieben ist was was ist. Willkommen bei Vektoralgebra und Matrizenrechnen. Im Prinzip ist es ganz einfach :-) (Ne, im Ernst. Auf den ersten Blick sieht das alles reichlich kompliziert aus. Hat man den Trick aber erst mal raus, ist es wirklich ziemlich einfach) http://cs.fit.edu/~wds/classes/cse5255/thesis/transformation/transformation.html
asdf schrieb: > http://wiki.delphigl.com/index.php/Hauptseite Danke! > Mathedoofi schrieb: >> verstehen muss ich die garnicht > würde aber ungemein helfen. Wohl war. Mathe ist schon etwas sehr Merkwürdiges... Karl Heinz Buchegger schrieb: > (Ne, im Ernst. Auf den ersten Blick sieht das alles reichlich > kompliziert aus. Hat man den Trick aber erst mal raus, ist es wirklich > ziemlich einfach) Wenn man es kann ist es immer einfach. :-) Ich schreib jetzt mal das "Kochrezept" ab was ich mir erarbeitet habe und hoffe auf Kommentare "richtig/falsch, weil". Ich benutze meine eigenen Wörter, bitte nicht zuuu pingelig sein... Grundlage ist dieses Skript http://www.mttcs.org:8008/Skripte/Ext/Pra/Material/vorlesung3.pdf So ganz klar ist mir die Sache noch nicht aber ich bin ihr ein Stückchen näher (hoffe ich...). Also: a. Eine Ebene ist definiert durch 2 Vektoren mit einem gemeinsamen Ursprung. b. Es gibt das universelle dreidimensionale Weltkoordinatensystem in dem die Objekte positioniert werden und das dreidimensionale Kamerasystem. Die Projektion erfolgt auf eine Ebene = "Leinwand" die parallel zur Ebene Vektor(OX) und Vektor(OY) ist. Der Abstand zwischen beiden Ebenen beträgt d. c. Im Beispiel sind die Ebenen wie im Anhang zu sehen ausgerichtet. Kochbuch: 1. Operationen festlegen die aus dem Weltkoordinatensystem das Kamerakoordinatensystem machen. im Beispiel: 1 - Rotation entlang OX 180° 2 - Rotation entlang OZ 90° 2. Matrixen für diese Operationen rausfinden (s. Skript) und in umgekehrter Reihenfolge multiplizieren, anschließend "Kehrwert" ausrechnen. Rx = [ 1 0 0 0 ] [ 0 -1 0 0 ] [ 0 0 -1 0 ] [ 0 0 0 1 ] Rz = [ 0 -1 0 0 ] [ 1 0 0 0 ] [ 0 0 1 0 ] [ 0 0 0 1 ] M = (RzRx)^-1 = [ 0 1 0 0 ] [ 1 0 0 0 ] [ 0 0 -1 0 ] [ 0 0 0 1 ] 3. Jeden Punkt in homogene Koordinaten umwandeln und mit M multiplizieren um vom Weltksystem ins Kameraksystem zu kommen. Sei P(5,3,2) (im Weltkoordinatensystem), in homogen [ 5 ] [ 3 ] [ 2 ] [ 1 ] P' = MP = [ 3 ] [ 5 ] [ -2 ] [ 1 ] DIE GROSSE FRAGE: STIMMT DAS BIS HIER? Mit dem letzten Punkt habe ich noch so meine Probleme: 4. Auf die Leinwand projezieren: Mit Projektionsmatrix für perspektivische Projektion multiplizieren (s. Skript) um 2D-Koordinaten zu erhalten. Sei E die Projektionsmatrix. Sei Abstand d = 1. E = [ 1 0 0 0 ] [ 0 1 0 0 ] [ 0 0 1 0 ] [ 0 0 1/d 0 ] entspricht also E = [ 1 0 0 0 ] [ 0 1 0 0 ] [ 0 0 1 0 ] [ 0 0 1 0 ] P'E = [ 3 ] [ 5 ] [ -2 ] [ -2 ] in "normalen Koordinaten" umrechnen = durch -2 teilen und man erhält die 2D-Koordinaten im Kameraksystem (x,y)=(-1.5, -2.5) und die Entfernung zur Leinwand=1. Das kommt mir aber komisch vor, ich hätte auf positive Koordinaten getippt?!? Wenn ich d negatif mache passt es besser. -->Problem! Soweit also meine Erkenntnisse...
> 1. Operationen festlegen die aus dem Weltkoordinatensystem das > Kamerakoordinatensystem machen. > im Beispiel: 1 - Rotation entlang OX 180° > 2 - Rotation entlang OZ 90° > > 2. Matrixen für diese Operationen rausfinden (s. Skript) und in > umgekehrter Reihenfolge multiplizieren, anschließend "Kehrwert" > ausrechnen. Im Prinzip, denke ich, soweit richtig, wenn auch noch sehr unvollständig. Allerdings ist gibt es eine einfachere Sichtweise: Ich projeziere immer entlang der Z-Achse (oder Y, je nachdem welche SIchtweise man bevorzugt). D.h. meine Kamera sitzt immer im Ursprung und schaut immer von dort aus in Richtung der Achse. Und dann verschiebe und drehe ich einfach das Universum solange, bis ich genau meinen Beobachter im Koordinatenursprung habe und die Richtung in die er schaut genau in diese festgelegte Achse zeigt. (Und seine Up-Richtung mit der globalen Up-Richtung identisch ist). Im Endeffkt kommt nach all den Manipulationen hinten nach dieselbe Matrix raus, aber die Sichtweise ist einfacher, weil ich mich nicht mit beliebig orientierten Bildebenen im Raum rum schlagen muss :-)
Schau dir mal dieses Buch an A trip down the graphics pipeline Jim Blinn By Google gibts davon die Online-Version. Ab Seite 21 "Nested Transformations and Blobby Man" ist ein Artikel, der für dich interessant ist. http://books.google.at/books?id=KBDS6GAwSwAC&pg=PA30&lpg=PA30&dq=blinn+blobby+man&source=bl&ots=PPs5JwL_yq&sig=J3t6AxrZobayeAyijMkvf9GwiAc&hl=de&sa=X&ei=cBdeT_fCKIKBOsPi3ZMN&ved=0CB8Q6AEwAA#v=onepage&q=blinn%20blobby%20man&f=false
Karl Heinz Buchegger schrieb: > Schau dir mal dieses Buch an > > A trip down the graphics pipeline > Jim Blinn > > By Google gibts davon die Online-Version. > Ab Seite 21 "Nested Transformations and Blobby Man" > ist ein Artikel, der für dich interessant ist. Ach Shit. die für dich interessanten Seiten 24 und 25 fehlen in der Vorschau.
Karl Heinz Buchegger schrieb: > Im Prinzip, denke ich, soweit richtig, wenn auch noch sehr > unvollständig. Ich will ja kein Buch schreiben, wenn es für meine Zwecke reicht ist gut. Das ganze ist eh nur eine rein private Spielerei. > Allerdings ist gibt es eine einfachere Sichtweise: > [...] > Im Endeffkt kommt nach all den Manipulationen hinten nach dieselbe > Matrix raus, aber die Sichtweise ist einfacher, weil ich mich nicht mit > beliebig orientierten Bildebenen im Raum rum schlagen muss :-) Ich bleib jetzt bei meiner Methode, bin froh das einigermaßen verstanden zu haben. Kannst du noch was zur eigentlichen Projektion und dem Vorzeichenfehler (Punkt 4) sagen? Karl Heinz Buchegger schrieb: > Ach Shit. die für dich interessanten Seiten 24 und 25 fehlen in der > Vorschau. Pech gehabt, Danke trotzdem!
Mathedoofi schrieb: > Ich bleib jetzt bei meiner Methode, bin froh das einigermaßen verstanden > zu haben. Ich find die Sichtweise "Kamera bewegen" irgendwie deutlich logischer...
Mathedoofi schrieb: > Mathedoofi schrieb: >> Ich bleib jetzt bei meiner Methode, bin froh das einigermaßen verstanden >> zu haben. > Ich find die Sichtweise "Kamera bewegen" irgendwie deutlich logischer... Nicht, wenn du die allgemeine Mathe dahinter entwickeln musst. Das macht man in der Grafik bzw. in Copmutational Geometry oft: Man löst ein Problem nicht im allgemeinen Fall, weil das formelmässig zu aufwändig wird. Die Schnittpunkte einer beliebig orientierten Geraden durch einen beliebig orientierten Zylinder zu berechnen ist formelmässig kompliziert. Ist der Zylinder aber im Koodinatenursprung und in einer Normallage (zb er steht senkrecht), dann vereinfachen sich die Formeln. Was macht man daher: Man transformiert das Problem aus seiner allgemeinen Lage im Raum in diese Normallage, berechnet dort die Lösung und transformiert das Ergebnis wieder zurück. Genauso auch hier: Habe ich meine Kamera im Koordinatenursprung und schaut sie immer entlang der Z-Achse, dann ist die Berechnung des perspektivischen Bildes trivial :-)
Du meinst also es ist sinnvoller die Kamera im Ursprung zu lassen und die Objekte so zu manipulieren dass sie davor auftauchen? Was ist mit der eigentlichen Projektion, passt meine Rechnung von oben?
Auch für diesen Fall ist es einfach: A bezeichne die Position des Auges und P ein in die Ebene E zu projizierender Punkt; die Projektion sei mit P' bezeichnet. Offenbar lieht P' auf der durch A und P gegebenen Geraden:
mit einem noch zu bestimmenden Parameter λ. Die Ebene E ist gegeben durch einen Punkt Q sowie einer Normalen n, d.h. es gilt
In der Praxis wird man n und Q aus der Blickrichtung ableiten und dem Abstand, den die Projektionsebene E vom Auge haben soll. Einsetzen von P' in die letzte Gleichung liefert
Damit ist P' bestimmt. Was zu tun bleibt, ist die Koordinaten von P' bezüglich zweier die Ebene E aufspannenden Vektoren X und Y zu finden. siehe oben. Nix hochtrabendes also; Anschauung nud die Basics reichen vollkommen aus.
Johann L. schrieb: > Auch für diesen Fall ist es einfach: Danke! So gut wie du müsste man Mathe können. Also ich versuche es mal: (Wie oben vorgeschlagen lasse ich die Kamera an einer Stelle stehen und bewege stattdessen die Objekte) > A bezeichne die Position des Auges auf der y-Achse (rechtshändiges System) bei -5: A(0;-5;0) > und P P(x;y;z) > ein in die Ebene E das ist die Ebene x0z > zu > projizierender Punkt; die Projektion sei mit P' bezeichnet. > > Offenbar lieht P' auf der durch A und P gegebenen Geraden: >
> mit einem noch zu bestimmenden Parameter λ. > > Die Ebene E ist gegeben durch einen Punkt Q Q(0;0;0) > sowie einer Normalen n, Vektor n(0;1;0) > d.h. > es gilt >
> In der Praxis wird man n und Q aus der Blickrichtung ableiten und dem > Abstand, den die Projektionsebene E vom Auge haben soll. > > Einsetzen von P' in die letzte Gleichung liefert >
1 | ( (0;0;0) - (0;-5;0) ) * Vektor(0;1;0) (0;5;0)*(0;1;0) 5 |
2 | lambda = ------------------------------------- = ----------------- = --- |
3 | ( (x;y;z) - (0;-5;0) ) * Vektor(0;1;0) (x;y+5;z)*(0;1;0) y+5 |
> Damit ist P' bestimmt. Was zu tun bleibt, ist die Koordinaten von P' > bezüglich zweier die Ebene E aufspannenden Vektoren X und Y zu finden. Die Einheitsvektoren 0x und 0z passen, von daher: P'(X;Y;Z) X=5x/(y+5) Y=0 Z=5z/(y+5) Passt das so? Ich würde sagen es sieht gut aus. Danke für die Mathenachhilfe! ;-)
Habs jetzt hinbekommen, Danke nochmal für die Hilfe. Echt toll dieser Matrixsalat wenn man ihn erstmal verstanden hat! :-) (Anhang benötigt GTK)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.