Forum: PC-Programmierung Suche Library für Koordinatentransformation 3D-->2D


von Mathedoofi (Gast)


Lesenswert?

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.

von Mathedoofi (Gast)


Lesenswert?

Achso, parallele Linien sollen parallel bleiben, also nicht auf einen 
weit entfernten Punkt zulaufen.

von benji (Gast)


Lesenswert?

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?

von Michael P. (mipo)


Lesenswert?

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...

von Michael P. (mipo)


Lesenswert?

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...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Mathedoofi (Gast)


Lesenswert?

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...

von Mathedoofi (Gast)


Lesenswert?

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

von Tom K. (ez81)


Lesenswert?

In openCV gibt es projectPoints(), das auf den ersten Blick Dein Problem 
lösen könnte. Handlich ist openCV aber definitiv nicht.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Mathedoofi (Gast)


Lesenswert?

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...

von asdf (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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

von Mathedoofi (Gast)


Lesenswert?

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...

von Mathedoofi (Gast)


Angehängte Dateien:

Lesenswert?

Bild vergessen

von Karl H. (kbuchegg)


Lesenswert?

> 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 :-)

von Karl H. (kbuchegg)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Mathedoofi (Gast)


Lesenswert?

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!

von Mathedoofi (Gast)


Lesenswert?

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...

von Karl H. (kbuchegg)


Lesenswert?

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 :-)

von Mathedoofi (Gast)


Lesenswert?

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?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Mathedoofi (Gast)


Lesenswert?

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! ;-)

von Mathedoofi (Gast)


Angehängte Dateien:

Lesenswert?

Habs jetzt hinbekommen, Danke nochmal für die Hilfe. Echt toll dieser 
Matrixsalat wenn man ihn erstmal verstanden hat! :-)

(Anhang benötigt GTK)

von Mathedoofi (Gast)


Angehängte Dateien:

Lesenswert?

Ups, da fehlt noch die Glade-Datei.

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
Noch kein Account? Hier anmelden.