3D Grafik Formeln

Developer_X

Top Contributor
Hi, ich habe schon sehr lange danach gegoogled, aber bin um ehrlich zu sein nie zu einem wirklichen Ergebniss gekommen.
Ich denke ihr könnt mir hier weiterhelfen.
Ihr habt sicher alle schon den MathematikStoff durch, ich bin erst in der achten.

Also:
Ich will die Formel für folgendes :

Ich habe selbst eine Klasse Vector3D geschrieben,
es gibt die variablen x,y und z.

Nun möchte ich gerne wissen, wie ich ausrechnen kann, wo x und y sind, auf einer 2Dimensionalen Oberfläche, d.h. im Grunde genommen folgendes muss in der Fomel drin sein:

Point_x, Point_y, Point_z, und User_x, User_y, User_z.

Technisch gesehen kann man auf einer 2Dimensionalen Oberfläche wie unser aller Bildschirm es ist, keine 3Dimensionalen Objekte anzeigen, aber man kann mithilfe von Formeln herausfinden, wo die 3DKoordinaten auf der 2Dimensionalen Oberfläche sind.

Kann mir einer helfen?

Danke schon mal im Voraus Developer_X.
 

javimka

Top Contributor
Weisst du, was eine Matrixmultiplikation ist? Damit steht und fällt eine solche Projektion!

Du hast also eine Anzahl Vektoren im 3D Raum und eine Kamera und willst wissen, wo deine Punkte im Bild der Kamera zu liegen kommen oder?
 

Marco13

Top Contributor
3D projection - Wikipedia, the free encyclopedia

(
1c89722619b756d05adb4ea38ee6f62b.png
:D)
 

Developer_X

Top Contributor
danke, aber kannst du mir das vielleicht auch genauer erklären, das von Wikipedia reicht mir nicht, außerdem warum brauche ich ne Formel um Z auszurechnen?!

Ich wollte lediglich eine Formel, welche die 2DKoordinate auf einer Oberfläche eines 3DVektors umwandelt.

Kannst du mir so eine geben?
 

Developer_X

Top Contributor
nein leider nicht, ich habe mich auch schon mal an meinen Mathe Lehrer gewendet, der will mir das noch nicht erklären, aber ich denke ich weiß das nicht, ich kenn das nur von Vektoren.

Wäre nett von euch wenn ihr mir das auch noch erklären könntet.

Sry, aber ich hab leider nicht den Stoff des Studiums drauf.
 

Developer_X

Top Contributor
ok ich habs mir mal angeguckt was eine Matrix ist, nach Wikipedia ist das aus meiner Sicht wie ein
2Dimensionales Array.

Eine Matrix ist also eine Tabellenförmige anordnungen von Objekte, zum Beispiel Mathematische Zahlen, mit denen man jeder zeit arbeiten kann, genau wie ein 2dimensionales Array.

Addieren, Subtrahieren, Multiplizieren, Dividieren, Radizieren und Potenzieren sind aber ganz komplizierte angelegenheiten, so wie ich das sehen konnte.

Aber was eine Matrix ist, habe ich gelernt, danke dass ihr mich das schon gelehrt habt.

Desweiteren habe ich folgende Vorstellung bekommen, was matrixen multiplikation sein könnte:

a b e f
c d * g h

==
a * e + b * g +c * f +d *h ???

Ist eigentlich gar nicht so schwer.
 

javimka

Top Contributor
Ganz so einfach sind Matrizen schon nicht. Wichtig für dich ist vor allem die Matrix-Vektor Multiplikation:

Code:
[a,b] * [x] = [ax+by]
[c,d]   [y]   [cx+dy]

Der Trick ist es, eine Matrix zu erstellen, die du mit jedem deiner Vektoren multiplizieren kannst und jeweils gerade den gesuchten 2D-Punkt erhälst. Um diese Matrix zu konstruieren, brauchst du Kugelkoordinaten. Kennst du die bereits?
 

Developer_X

Top Contributor
Nach Wikipedia:
In räumlichen Polarkoordinaten wird ein Punkt durch seinen Abstand vom Ursprung und durch zwei Winkel angegeben. Wenn der Abstand vom Ursprung konstant ist (auf einer Sphäre = Kugeloberfläche), benötigt man nur die zwei Winkel, um einen Punkt eindeutig zu bezeichnen, und spricht dann von sphärischen Koordinaten. Der Begriff Kugelkoordinaten kann als Oberbegriff für diese beiden Fälle angesehen werden.

Für Polarkoordinaten in der Ebene (ein Abstand, ein Winkel) und Zylinderkoordinaten (zwei Abstände, ein Winkel) siehe den Artikel Polarkoordinaten.


Ich hab leider net kapiert was die damit meinen, von Wikipedia.
Das mit den Matrixen ging ja noch, aber das hier.
Kugelkoordinaten.PNG


Dieses Bild gibt mir nicht gerade mehr aufschluss.
Da brauch ich wirklich hilfe
 

javimka

Top Contributor
Weisst du, solche Dinge sollte dir wirklich ein Lehrer beibringen, über das Forum ist das schon sehr aufwendig.

Wenn du unbedingt eine Matrix-Aufgabe willst :)
A = [1,0 ; 0,1], v = [4 ; 7]
Berechne A*v

A = [4,-3 ; 1,2], v = [2 ; 3]
Berechne A*v

A = [1,-1,1 ; 0,1,-1 ; 0,0,1], v = [1 ; 2 ; 3]
Berechne A*v

Übrigens Sind zweischen ; jeweils die Zeilen der Matrix, [a,b ; c,d] bedeutet also
Code:
[a , b]
[c , d]
 

Developer_X

Top Contributor
A = [1,0 ; 0,1], v = [4 ; 7]
Code:
1*4 + 0*7 + 0*4 + 1*7

A = [4,-3 ; 1,2], v = [2 ; 3]
Code:
4 * 2 + -3*3 + 1*2 + 2*3

A = [1,-1,1 ; 0,1,-1 ; 0,0,1], v = [1 ; 2 ; 3]
Code:
1 * 1 + -1* 2 + 1*3 
+ 0 * 1 +  1*2 + -1*3 +0*1 + 0*2 + 0*3

Richtig?

Und danke dass du mir so viel beibringst.
 

javimka

Top Contributor
Ist noch nicht ganz richtig. Du hast bei den ersten beiden Aufgabe zwar jeweils die richtigen Zahlen miteinander multipliziert, was für das erste Mal schon mal ganz vortrefflich ist, aber als Resultat kriegst du nicht eine Zahl, sondern wieder ein Vektor.
Matrix * Vektor = Vektor.

Der resultierende Vektor hat ja 2 oder 3 Elemente. Das erste Element kommt zustande, indem zu die erste Zeile der Matrix mit dem Vektor multiplizierst, also jeweils zwei Zaheln zusammenmultiplizierst und aufsummierst.
Das zweite Element kriegst du, wenn du die zweite Zeile der Matrix, wiederum mit dem Vektor multiplizierst und wieder aufsummierst.
Code:
[[COLOR="Red"]a[/COLOR],[COLOR="SeaGreen"]b[/COLOR] ; c,d] * [[COLOR="Red"]x[/COLOR] ; [COLOR="SeaGreen"]y[/COLOR]] = [[COLOR="Red"]a*x[/COLOR]+[COLOR="SeaGreen"]b*y[/COLOR] ; c*x+d*y]

Zahlenbeispiel:
[1,2 ; 3,4] * [5;6] = [1*5+2*6 ; 3*5+4*6] = [17;39]
 

Developer_X

Top Contributor
ach so!
also das hier?

A = [1,0 ; 0,1], v = [4 ; 7]
Code:
1*4 + 0*7 
0*4 + 1*7
[U]Vector2f(4|7)[/U]

A = [4,-3 ; 1,2], v = [2 ; 3]
Code:
4 * 2 + -3*3 
1*2 + 2*3
[U]Vector2f(-1|8)[/U]

A = [1,-1,1 ; 0,1,-1 ; 0,0,1], v = [1 ; 2 ; 3]
Code:
1 * 1 + -1* 2 + 1*3 
0 * 1 +  1*2 + -1*3
0*1 + 0*2 + 0*3

[U]Vector 3f(2|-1|0)[/U]

Richtig?

Ich habe mit f die elemente gemeint
 

javimka

Top Contributor
Ich hoffe, du kennst Polarkoordinaten.
In 2D hast du zum einen kartesische Koordinaten, als x- und y- Koordinaten. Ein Punkt in der Ebene kann aber auch anders dargestellt werden, nämlich mittels eines Winkels und dem Abstand zum Nullpunkt. Der Punkt ( pi/4, 5 ) ist also der Punkt, der im Winkel pi/4 zur x-Achse steht (gegen den Uhrzeigersinn) und den Abstand 5 zum Nullpunkt hat. Winkel werden natürlich in Radian gemessen.
Die Kugelkoordinaten sind die 3D Erweiterung der Polarkoordinaten. Es gibt einen Zusätzlichen Wert für die Koordinaten eines Punktes, nämlich den Winkel zwischen der z-Achse und der Verbingun des Punktes und dem Nullpunkt.
 

Developer_X

Top Contributor
Also, ich habs mir mal durchgelesen, mir ist jetzt klar geworden, was Kugelkoordinaten sind,
schauen wir uns dazu doch mal das Bild an:
Kugelkoordinaten.PNG


Es ist im grunde genommen wie das normale 3D-Koordinaten System, nur dass der ganze Raum gezerrt ist.
Meine Erklärung:
Also im Bild sind folgende Daten zu sehen:
Φ
r
θ

R erstmal zu bestimmen um eine "Platte zu bekommen".
Dann kann man sich noch auf dieser Platte nach hinten bewegen mit Φ
und von oben nach unten, natürlich auf dem kreisbogen, mit θ.

Das heißt im Grunde genommen:
x r
y θ
z Φ

hab ich das so richtig verstanden?
 

Marco13

Top Contributor
Nur mal so als Einschub: Was die Kugekoordinaten jetzt mit der 3D-Projektion zu tun haben sollen, leuchtet mir nicht ganz ein ... ???:L
 

Developer_X

Top Contributor
Ich hoffe, du kennst Polarkoordinaten.
In 2D hast du zum einen kartesische Koordinaten, als x- und y- Koordinaten. Ein Punkt in der Ebene kann aber auch anders dargestellt werden, nämlich mittels eines Winkels und dem Abstand zum Nullpunkt. Der Punkt ( pi/4, 5 ) ist also der Punkt, der im Winkel pi/4 zur x-Achse steht (gegen den Uhrzeigersinn) und den Abstand 5 zum Nullpunkt hat. Winkel werden natürlich in Radian gemessen.
Die Kugelkoordinaten sind die 3D Erweiterung der Polarkoordinaten. Es gibt einen Zusätzlichen Wert für die Koordinaten eines Punktes, nämlich den Winkel zwischen der z-Achse und der Verbingun des Punktes und dem Nullpunkt.

Polar Koordinaten kenne ich nicht, aber habs jetzt bei wikipedia nachgelesen, und hat mir die augen noch weiter geöffnet.

Im "PolarKoordinatenSystem" kann man den Punkt mit dem Radius angeben, und dem Abstand zum Mittelpunkt des Kreises angeben, is klar, und dieses andere, das Kugelkoordinatensystem, ist ja eigentlich nur noch mal, mit nem zweiten winkel, und dem abstand.
 

javimka

Top Contributor
Nein, die Umrechnung ist komplizierter.

Für einen Punkt p ist
r der Abstand von p zum Nullpunkt, wobei r>=0 gilt
Φ Der Winkel zwischen dem "Schatten" von p auf der x-y-Ebene und der x-Achse, wobei 0<=Φ<2*pi gilt
θ Der Winkel zwischen det z-Achse und p, wobei 0<=θ<pi gilt
 

javimka

Top Contributor
Du musst wissen, wie du die Projektionsmatrix zusammenstellen kannst. Dazu brauchst du die Kugelkoordinaten deiner Kamera. Wie du die berechnen kannst, steht auf Wikipedia.
Das schwierigste ist, mit den Werten, diese Matrix zu basteln. Wie das geht steht auch auf Wikipedia, aber ist meiner Meinung nach schlecht erklärt.
 

javimka

Top Contributor
Nein, das geht leider nicht, da müsste ich ja ein ganzes Buch schreiben. Vielleicht gehst du mal in die Bibliothek oder möglicherweise, ist das einfach noch ein bisschen zu mathematisch für dich.
 

Marco13

Top Contributor
*räusper* ... was soll das mit den Polarkoordinaten? Ich dengele jetzt seit >10 Jahren mit Computergrafik rum, und kenne auch die Namen "Foley, van Dam, Feiner & Hughes", aber Polarkoordinaten kann ich da jetzt nicht einordnen... ???:L (Man könnte die verwenden um die Kameraposition zu beschreiben, aber das wäre ja ein Krampf im Vergleich zu dem, was z.B. ein gluLookAt macht...)
 

javimka

Top Contributor
was macht gluLookAt denn?

Ich kenne es so, dass man die Polarkoordinaten der Kamera verwendet, um mit ein paar sin/cos die Projektionsmatrix zu erstellen. Er will ja die 2D Koordinaten auf dem Bidlschirm berechnen.

Ich arbeite allerdings nicht seit 10 Jahren mit Computergrafik ;)
 
G

Guest2

Gast
Moin,

DevX, das was Du machen willst ist eigentlich "nur" eine Projektion von 3D Koordinaten auf 2D Koordinaten.

Grundsätzlich brauchst Du:

v = Deinen Punkt im 3D Raum (x, y, z)
Das sind Deine Eingangsdaten. In OpenGL nennt man die Objektkoordinaten. Um einfacher Rechnen zu können, erweitert man v zu v = (x, y, z, w) wobei w bei einem Punkt immer 1 ist (also (x, y, z, 1)). (Das nennt man homogene Koordinaten)

MV = Deine ModelViewMatrix
Beschreibt wie einzelne Objekte zum Koordinatenursprung (0,0,0) stehen. Wenn MV die Einheitsmatrix ist (in der Matrix auf der Diagonalen 1 sonnst 0), ist das so als ob Du in dem Punkt (0,0,0) stehst und in Richtung -z blickst. MV bildet die Objektkoordinaten auf die Augkoordinaten ab. Das heißt, wenn Du z.B. mit Deiner Kamera 5 Einheiten weiter links stehst, wird genau das in MV festgehalten. Technisch gesehen ist MV eine 4x4 Matrix.

P = Deine Projektionsmatrix
Beschreibt wie Deine Kamera die 3D Koordinaten auf 2D Koordinaten abbilden soll. Wenn Du Dir einen normalen Fotoapparat ansiehst, kennst Du ja den Zoom. Daran siehst Du, das es keinen festen Weg von 3D auf 2D gibt, sondern das P von weitern Faktoren abhängt (z.B. dem Zoom). Genau brauchst Du die Fenstergröße (= das Papierformat), den Blickwinkel (= den Zoom), und den minimalen / maximalen Abstand den ein Objekt zur Kamera haben darf = zNear / zFar) . Technisch gesehen ist auch P eine 4x4 Matrix.

v' = Deine 2D Koordinaten (x', y', z', w')
x' und y' sind das Ergebnis und das was Du wissen willst (fast), w' brauchst Du aber noch zum rechnen.


Insgesamt gilt nun: v' = (x', y', z', w') = P * MV * v

Fast das was Du willst, denn v' muss noch durch die w' Komponente in v' geteilt (normalisiert werden). Dann hast Du Koordinaten im Einheitswürfel, das heiß sie sind zwar schon auf 2D Abgebildet, aber x', y', z' liegen alle noch zwischen -1 und +1 ("Normalized Device Coordinates"). Da Du ja Fensterkoordinaten willst, musst Du diese noch entsprechend verschieben und aufziehen. (z.B. x'' = (x' + 1) / 2 * Fensterbreite).

Also insgesamt:

x'' = (x' / w' + 1) / 2 * Fensterbreite
y'' = (y' / w' + 1) / 2 * Fensterhöhe


Der Einfachheit halber nehmen wir jetzt an Du stehst mit Deiner Kamera in (0,0,0) und Blickst nach -z, dann wird MV zur Einheitsmatrix (ist dann wie * 1 und kann wegfallen), dann gilt:

v' = (x', y', z', w') = P * v

und (immer noch):

x'' = (x' / w' + 1) / 2 * Fensterbreite
y'' = (y' / w' + 1) / 2 * Fensterhöhe

Außer dem P müsstest Du jetzt erstmal alles kennen bzw. berechnen können.

Und das P muss man jetzt erstmal einfach wissen (also unten kopieren)(man kann es auch herleiten, aber nicht mehr heute ;) )

In Java sieht das dann so aus (oder soll ich es mal in Brainfuck versuchen? :D) :

Java:
public class Projection {

    public static float[] gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {

        final float[] projectionMatrix = new float[15];

        final float f = (float) (1.0 / Math.tan(Math.toRadians(fovy / 2.0)));

        projectionMatrix[0] = f / aspect;
        projectionMatrix[5] = f;
        projectionMatrix[10] = (zFar + zNear) / (zNear - zFar);
        projectionMatrix[14] = (2 * zFar * zNear) / (zNear - zFar);
        projectionMatrix[11] = -1;

        return projectionMatrix;

    }


    public static float[] project(final float[] projectionMatrix, final float x, final float y, final float z) {

        // Clip Coordinates
        final float clipCoordinateX = x * projectionMatrix[0];
        final float clipCoordinateY = y * projectionMatrix[5];
        final float clipCoordinateZ = z * projectionMatrix[10] + projectionMatrix[14];
        final float clipCoordinateW = z * projectionMatrix[11];

        // Normalized Device Coordinates
        return new float[] { clipCoordinateX / clipCoordinateW, clipCoordinateY / clipCoordinateW, clipCoordinateZ / clipCoordinateW };

    }


    public static int[] clipAndTranslateDivide(final float[] normalizedDeviceCoordinates, final float width, final float height) {

        // clip z
        if (!(normalizedDeviceCoordinates[2] >= -1 && normalizedDeviceCoordinates[2] <= +1))
            return null;

        // clip x
        final int x = Math.round((normalizedDeviceCoordinates[0] + 1) / 2 * width);
        if (!(x >= 0 && x <= width))
            return null;

        // clip y
        final int y = Math.round((normalizedDeviceCoordinates[1] + 1) / 2 * width);
        if (!(y >= 0 && y <= width))
            return null;

        return new int[] { x, y };

    }


    public static void main(final String[] args) {

        // Viewport parameters
        final float width = 500;
        final float height = 500;
        final float fovy = 90f;
        final float zNear = 1f;
        final float zFar = 100f;

        // Eye Coordinates
        final float x = -1.0f;
        final float y = 0.5f;
        final float z = -1.0f;

        final float[] projectionMatrix = gluPerspective(fovy, width / height, zNear, zFar);
        final float[] normalizedDeviceCoordinates = project(projectionMatrix, x, y, z);
        final int[] windowCoordinates = clipAndTranslateDivide(normalizedDeviceCoordinates, width, height);

        System.out.println("Point(" + x + ", " + y + ", " + z + ") is at " + Arrays.toString(windowCoordinates));

    }
}


Ergibt:

Code:
Point(-1.0, 0.5, -1.0) is at [0, 375]

Also genau da wo man ihn erwaten würde.

(Kann trotzdem sein das da irgendwo noch ein Dreher drinne steckt, aber ist mir jetzt spät genug ;) )

P.S.: Mir ist durchaus bewusst das Du das nicht auf Anhieb verstehen wirst (kannst), aber einfach nicht aufgeben, dann wird es schon irgendwann klarer werden (zumindest ein wenig ;) )


@Marco (bzgl. den Polarkoordinaten): Danke, wollte eben schon den Foley, van Dam raus graben, weil ich dachte ich hätte was verdrängt ;)

Gruß,
Fancy
 

Developer_X

Top Contributor
Danke für diese Erklräung, ich werd mir das mal mehrmals durchlesen, und ich muss dir sagen danke, da ich gerne nicht nur JOGl oder JAVA3D verwenden möchte,
ich möchte mal selbst dieses ganze selbst machen, oder wenigstens wissen wie man das macht.

Danke euch allen.

DX
 

Marco13

Top Contributor
Um das nochmal explizit zu erwähnen: In Amazon.com: Computer Graphics: Principles and Practice in C (2nd Edition) (9780201848403): James D. Foley, Andries van Dam, Steven K. Feiner, John F. Hughes: Books steht das alles drin. Das ist die "Bibel" der Grafikprogrammierung, aber ebenso wie die Bibel würde ich auch bei diesem Buch kaum jemandem empfehlen, es zu lesen. Lange Ausführungen über PHIGS und CRTs (was? ???:L ) sind nicht mehr zeitgemäß. Einiges ändert sich aber nie: Speziell die mathematischen Grundlagen* von Projektionen und anderen Transformationen sind dort ausführlich erklärt. Nicht einfach. Nicht immer so verständlich, wie man sie mit einem gewissen didaktischen Wohlwollen vielleicht machen könnte. Aber ausführlich.

*Grundlagen heißt hier: Das, was auf dem Stoff der 12.-13. Klasse aufbaut...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Feste Blöcke mit Grafik Spiele- und Multimedia-Programmierung 9
Anfänger2011 Wichtig: Grafik und Sprites erstellen Spiele- und Multimedia-Programmierung 1
T grafik in bereiche einteilen (dartboard) Spiele- und Multimedia-Programmierung 14
T LWJGL Grafik meines Projektes läuft nicht korrekt auf meinem iMac Spiele- und Multimedia-Programmierung 19
S Wolken Bild/Grafik vom Programm erstellen lassen Spiele- und Multimedia-Programmierung 11
Luk10 Tipps für bessere Animationen / Grafik Engine Spiele- und Multimedia-Programmierung 2
M Einen Hobby Game - / Grafik Designer zu finden (Screenshot vom Spiel) Spiele- und Multimedia-Programmierung 7
D einfache 2D Grafik in JAVA. absoluter Anfänger Spiele- und Multimedia-Programmierung 5
R 2D Grafik JOGL Spiele- und Multimedia-Programmierung 18
S Grafik erstellen für Java Spiel Spiele- und Multimedia-Programmierung 8
Developer_X Java3D Grafik Boni Spiele- und Multimedia-Programmierung 8
H Grafik verschwindet durch Größenveränderung von GridBag Spiele- und Multimedia-Programmierung 5
N Felder auf Grafik Spiele- und Multimedia-Programmierung 2
R Grafik-Engine? MemoryImageSource? Spiele- und Multimedia-Programmierung 10
E Tester mit Intels Onboard-Grafik (o.ä.) gesucht! Spiele- und Multimedia-Programmierung 28
N Grafik als Hintergrund eines Rechtecks verwenden? Spiele- und Multimedia-Programmierung 4
G Entscheidungshilfe: Grafik-API Spiele- und Multimedia-Programmierung 5
T Spiel mit schöner Grafik, bitte testen Spiele- und Multimedia-Programmierung 10
V Wie bewege ich eine eingefügte Grafik (img) ? Spiele- und Multimedia-Programmierung 2
S Wie kann ich das Zeichnen der Grafik feiner machen? Spiele- und Multimedia-Programmierung 9

Ähnliche Java Themen

Neue Themen


Oben