# 3d in 2d umwandeln?



## grafik (13. Jun 2011)

Ich würde gerne ein 3d spiel erstelen ohne dabei erst noch 3d zu lernen. Deshalb dachte ich mir das ich mir mit einer function der ich 3 var.(3d koords) übergebe und dann 2 var.(2d koords) als rückgabe erhalten geht das irgendwie sichtwinkel kann immer gleichsein?


----------



## Landei (13. Jun 2011)

Ja, wenn die "Blickrichtung" fest entlang einer Koordinatenachse ist, geht das relativ einfach, auch Verschiebungen in Richtung der anderen beiden Achsen ist kein Problem. Kompliziert wird es erst bei Drehungen.

Zuerst das Koordinatensystem. x nach rechts und y nach oben würde sich anbieten (weil das richtungsmäßig deinen 2D-Koordinaten entpricht), und z von dir weg zeigen (damit haben wir ein Linke-Hand-System). Setzen wir das Kameraauge auf (0, 0, -z0) und die Projektionsfläche auf das Rechteck (-x0,-y0,0) bis (x0,y0,0), wobei x0/y0 dem Seitenverhältnis deines 2D-Rechtecks entsprechen muss. Natürlich muss dann auch z0 so gewählt werden, dass ein "vernünftiger" Öffnungswinkel entsteht.

Welche 2D-Koordinaten bekommt nun ein Punkt (x,y,z)?
Es gilt nach dem Strahlensatz x/(z+z0) = xp/z0, also xp = x*z0/(z+z0). xp ist hier die Position auf der Projektionsfläche. Liegt xp außerhalb des Bereichs -x0 bis x0, ist der Punkt nicht sichtbar. Ansonsten kannst du diese Koordinate mit einer affinen Transformation in einen Pixel umrechnen (die Transformation muss -x0 auf den Pixel ganz links und x0 ganz rechts abbilden). Für yp gilt analog y*z0/(z+z0), nur dass hier y0 auf den Pixel ganz oben und -y0 ganz unten abgebildet werden muss.


----------



## grafik (14. Jun 2011)

Landei hat gesagt.:


> Ja, wenn die "Blickrichtung" fest entlang einer Koordinatenachse ist, geht das relativ einfach, auch Verschiebungen in Richtung der anderen beiden Achsen ist kein Problem. Kompliziert wird es erst bei Drehungen.


werden jetzt drehungen erklärt oder hab ich das falsch verstanden?



Landei hat gesagt.:


> Zuerst das Koordinatensystem. x nach rechts und y nach oben würde sich anbieten (weil das richtungsmäßig deinen 2D-Koordinaten entpricht), und z von dir weg zeigen (damit haben wir ein Linke-Hand-System). Setzen wir das Kameraauge auf (0, 0, -z0) und die Projektionsfläche auf das Rechteck (-x0,-y0,0) bis (x0,y0,0), wobei x0/y0 dem Seitenverhältnis deines 2D-Rechtecks entsprechen muss. Natürlich muss dann auch z0 so gewählt werden, dass ein "vernünftiger" Öffnungswinkel entsteht.
> 
> 
> 
> ...


----------



## Landei (14. Jun 2011)

grafik hat gesagt.:


> werden jetzt drehungen erklärt oder hab ich das falsch verstanden?


 Nein, einfachster Fall eines festen Standpunktes, der entlang einer Achse schaut.



> Strahlensatz?



Im Prinzip dasselbe wie die Sätze über ähnliche Dreiecke.

Nochmal ganz einfach: Stell dir vor, auf deinem Monitor wäre mittig ein Koordinaten-Kreuz (x-Achse von -x0 bis x0 und y-Achse von -y0 bis y0) abgebildet. Dein Auge befindet sich mittig im Abstand z0 davor, die z-Achse ragt in den Bildschirm hinein.  Jetzt ist irgendwo vor oder hinter deinem Schirm eine Mücke. Dann verbindest du diese mit deinem Auge und schaust, wo die Verbindungsgerade den Monitor "durchstoßen" würde. Dann hast du erst einmal x und y-Koordinate (keine z-Koordinate mehr), die du nur noch auf die Pixel deiner Komponente umrechnen musst. Für diesen Fall sind obige Formeln.


----------



## muckelzwerg (14. Jun 2011)

Genau das macht die Grafikkarte für Dich. Wenn Du 3D-Daten eingeben und daraus die 2D-Projektion berechnen lassen willst, kommst Du um "3D Lernen" nicht herum. Sowohl für die Berechnung der Projektion, als auch für Berechnungen innerhalb der 3D-Szene.
Um 3D zu umgehen musst Du gleich mit 2D arbeiten, sonst sparst Du doch nichts. Du hast sogar mehr Aufwand, weil Du zusätzlich noch all das machen musst, was eigentlich auf der Grafikkarte liegt.

Was genau willst Du denn machen?


----------



## Landei (14. Jun 2011)

Ich finde es schon gut, wenn man am Anfang mal selbst die Berechnungen durchgeführt hat, anstatt die Grafikkarte "machen zu lassen". Das hilft beim Verständnis von Java3D, OpenGL und so ungemein...


----------



## muckelzwerg (14. Jun 2011)

Seh ich genauso, aber


grafik hat gesagt.:


> Ich würde gerne ein 3d spiel erstelen *ohne* dabei erst noch 3d zu lernen.


das geht nunmal nicht, indem man ausgerechnet den Teil nachprogrammiert, der eigentlich auf GraKa stattfindet. 
Und Grundlagenübungen für das "Verständnis von Java3D" ist ziemlich das Gegenteil von "ohne 3d zu lernen". 

Wenn man 3D nicht lernen will, dann muss man es umgehen. Entweder mit einem ganz extremen high-level-system oder indem man kein 3D macht. Sondern ein 2D-Spiel z.B.
Sonst würde es ja im Umkehrschluss bedeuten, alle anderen lernen "3D" nur zum Spaß, brauchen es aber in Wahrheit gar nicht, um z.B. ein 3D-Spiel zu erschaffen.


----------



## Landei (14. Jun 2011)

Ich glaube wir reden aneinander vorbei. 

So wie ich das verstehe will der TO ein 3D-Spiel schreiben, ohne sich erst in irgendeine 3D-_Technologie _(wie Java3D) einzuarbeiten zu müssen, also das 3D "per Hand" zu berechnen. Und das ist meiner Meinung nach in Ordnung und hilft später zu verstehen, was in einer 3D-Engine so abgeht.


----------



## muckelzwerg (14. Jun 2011)

Ja, das hab ich anders verstanden. Da müssen wir mal abwarten, was er noch dazu schreibt.


----------



## grafik (19. Jun 2011)

Landei hat gesagt.:


> Ich glaube wir reden aneinander vorbei.
> 
> So wie ich das verstehe will der TO ein 3D-Spiel schreiben, ohne sich erst in irgendeine 3D-_Technologie _(wie Java3D) einzuarbeiten zu müssen, also das 3D "per Hand" zu berechnen. Und das ist meiner Meinung nach in Ordnung und hilft später zu verstehen, was in einer 3D-Engine so abgeht.


Ja, genau so hab ich das gemeint. Ich hab jetzt auch schon mal eine Klasse entworfen die 3d koords und die pos des betrachters in 2d koords umwandeld:

```
class zweid
{
  int y;
  int x;
  zweid(int sxx, int syy, int szz, int xxx, int yyy, int zz)
           //Standort
  {
    int sy=syy, sx=sxx, sz=szz;
    int yy=yyy, xx=xxx, z = zz;
    int ey=yy, ex=xx, ez=0;
    int a, b, c;

    a=sz-z;      //umwandeln (x|y|z)
    b=sx-xx;    //(3|2|1)Standtort  
    c=sy-yy;   //(1|2|3)Punkt
                   //pro schritt -z macht x+1 und y=y
                   //also(4|2|0)
                   //z=0 kann man dann weglassen

    b=b/a;
    c=c/a;
    a=1;
    while(z!=0)
    {
      ey=ey+c;
      ex=ex+b;
      --z;
    }

    y=ey;
    x=ex;
  }
}
```


Und eine Klasse die mit dieser class alle 8 Punkte eines Würfels speichert:

```
class wuerfel
{
  int vxor, vxul, vxol, vxur, vyor, vyul, vyol, vyur;  //vxor= v=vorne, x=koord, o=oben, r=rechts
  int hxor, hxul, hxol, hxur, hyor, hyul, hyol, hyur;
  
  public wuerfel(int x, int y, int z, int higth, int length, int tiefe)
//x, y, z koords, heigth höhe, length = länge, tiefe = tiefe
  {
    int xx, yy, zz;
    
    zweid zzz = new zweid(300, 200, -200000, x, y, z);
                                    //Blickwinkel          koords
    vxor=zzz.x;//koords werden gespeichert
    vyor=zzz.y;
    
    xx=x+length;
    yy=y-higth;
    zweid zzz1 = new zweid(300, 200, -200000, xx, yy, z);
    vxul=zzz1.x;
    vyul=zzz1.y;
    
    yy=yy+higth;
    zweid zzz2 = new zweid(300, 200, -200000, xx, yy, z);
    vxol=zzz2.x;
    vyol=zzz2.y;
    
    yy=yy-higth;
    xx=xx-length;
    zweid zzz3 = new zweid(300, 200, -200000, xx, yy, z);
    vxur=zzz3.x;
    vyur=zzz3.y;
    
    
    hxor=vxor-tiefe;
    hxol=vxol-tiefe;
    hxur=vxur-tiefe;
    hxul=vxul-tiefe;

    hyor=vxor-tiefe;
    hyol=vxol-tiefe;
    hyur=vxur-tiefe;
    hyul=vxul-tiefe;
  }
}
```
Leider funktionirt das ganze noch nicht so ganz aus probirt habe ich es hier mit:

```
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import static java.awt.event.KeyEvent.*;

public class spiel extends Frame
{
    public static void main(String[] args)
  {
    spiel f = new spiel();            //fenster
    f.setSize(1000, 700);
    f.setTitle("Rollenspiel");
    f.setVisible(true);
  }
  
  spiel()
  {
    addWindowListener(new window());
  }

  public class window extends WindowAdapter
  {
    public void windowClosing(WindowEvent e)
    {
      System.exit(0);
    }
  }

  public void paint(Graphics g)
  {
    Graphics2D g2d = (Graphics2D) g;

    wuerfel a = new wuerfel(500, 500, 500, 100, 100, 100);
    
    GeneralPath gp = new GeneralPath();
    gp.moveTo(a.vxor, a.vyor);
    gp.lineTo(a.vxol, a.vyol);
    gp.lineTo(a.vxul, a.vyul);
    gp.lineTo(a.vxur, a.vyur);
    gp.lineTo(a.vxor, a.vyor);

    gp.lineTo(a.hxor, a.hyor);
    gp.lineTo(a.hxol, a.hyol);
    gp.lineTo(a.vxol, a.vyol);
    gp.lineTo(a.hxol, a.hyol);
    gp.lineTo(a.hxul, a.hyul);
    gp.lineTo(a.vxul, a.vyul);
    gp.lineTo(a.hxul, a.hyul);
    gp.lineTo(a.hxur, a.hyur);
    gp.lineTo(a.vxur, a.vyur);

    g2d.draw(gp);
  }
}
```
Weiß einer warum das nicht funktionirt?


----------



## muckelzwerg (19. Jun 2011)

Wieso? Da "funktioniert" doch alles.
Probleme gibt es erst dann, wenn Du beschreibst, was passieren soll und was stattdessen tatsächlich passiert.


----------



## twseitex (19. Jun 2011)

Hi,

bitte für diese Antwort mich nicht würgen 

Java SE Desktop Technologies - Java 3D API


Ich habe mich mit meinen Java-Audio-Player für Java SE, also Standard Java, sowas
von rumgequält, um konfigurierbare 2D-Animation wie Rotation eines Bildes in "Echtzeit"
hinzubekommen ..... und dabei die Java-Doc studieren müssen (Java-Literaten ) ).

Es geht nur der 1 Weg: Hartnäckiges Studieren der Bibliothek, dann erst Try and Error.

Drum  der obige Link *fg.

Wer mein erquältes Java-Player (2d-Graphic unter Java-SE) sehen will, besuche mich auf  twseiten.com  (audio, flash and java).

Cu !


----------



## grafik (19. Jun 2011)

muckelzwerg hat gesagt.:


> Wieso? Da "funktioniert" doch alles.
> Probleme gibt es erst dann, wenn Du beschreibst, was passieren soll und was stattdessen tatsächlich passiert.


Stimmt, also eigentlich soll er mir einen würfel in 3d ausgeben(so wie man den im mathe unterricht malt(oder so anlich)).Stadessen malt er mir ein viereck mit einem dreick. Warum macht er dies?


----------



## grafik (19. Jun 2011)

twseitex hat gesagt.:


> Hi,
> 
> bitte für diese Antwort mich nicht würgen
> 
> ...


Wenn ich das richtig verstanden habe willst du mir damit sagen das dass nicht geht, oder ? Meine antwort natürlich geht das(sonst könnte man ja garkein 3d darstellen) man muss nur wissen wie!


----------



## muckelzwerg (19. Jun 2011)

Ok. Wie arbeitet denn Deine Berechnung? Warum nimmst Du nicht die Verfahren, die auf der Grafikkarte das 3D machen, also die üblichen Matrizen?
Du willst doch bestimmt eine perspektivische Projektion?

Hier z.B. kannst Du Dich mal einlesen.
http://wwwcg.in.tum.de/Teaching/WS2004/ProSem/Workouts/hummelj/Folien.pdf
http://wwwcg.in.tum.de/Teaching/WS2004/ProSem/Workouts/hummelj/Ausarbeitung.pdf

Aber wie gesagt, wenn Du Deine eigene 3D-Software-Engine baust, dann hast Du hinterher sowieso mehr drauf, als Du brauchst um z.B. jogl oder java3D zu verwenden. Du musst ja trotzdem alles tun, was Du bei OpenGL tun musst. Und dann kommt noch die ganze Berechnung DAZU, die sonst die Grafikkarte macht. Abkürzen kannst Du da nichts, es fällt ja nichts weg, wenn Du die Software von der Graka in Dein Programm reinziehst. Gefüttert werden muss Deine Software-Engine ja genauso. 
Du siehst ja schon wie viele Zeilen Du für Deinen Würfel geschrieben hast.


----------



## Landei (19. Jun 2011)

Lass dich doch von fremden Code "inspirieren". Das hier ist zwar für ein Applet, sollte aber leichter umzubiegen sein als deinen Versuch zu korrigieren: 3-Dimensional Square Demo - Java - Source Code | DreamInCode.net


----------



## muckelzwerg (19. Jun 2011)

Es gibt auch einige Sachen in Flash für solche kleinen Rotationsdemos usw. Ist vielleicht einen Blick wert.
Das Problem ist nur, dass dort ganz konkret ein einzelner Fall berechnet wird. Damit kann man aber nicht einfach mal so eine einfache Spielwelt projezieren.


----------



## grafik (20. Jun 2011)

So ich glaub mitlerweile nicht mehr daran das das irgendwann klappt daher hab ich mir jetzt die jmonkey engine runtergeladen aber irgendwie klapt das nicht nachdem ich ein neues projekt erstelt habe krieg ich dieses nicht geöfnet .Warum??


----------



## muckelzwerg (20. Jun 2011)

Wenn Du es so schnell aufgibst, dann war das richtig so. Dann hättest Du das Projekt nicht durchgehalten.
Wenn Du die Mathe dahinter verstanden hast, kannst Du die grundlegenden Primitive aber recht problemlos mit einem einfachen Shading an einem Wochenende schreiben.

Für die neuen Probleme solltest Du einen neuen Thread aufmachen.


----------



## Landei (20. Jun 2011)

Ich habe länger nichts mehr mit JME gemacht, kann da also leider nicht helfen. Hast du dir die Installationsanleitung angeschaut? Und dann mit eines der Einsteigertutorials ausprobiert?


----------

