# gutes Tutorial zu 3d->2d Projektion?



## hdi (10. Apr 2009)

Hi,

ich hatte vor einiger Zeit schon mal einen Versuch gestartet, ein wenig mit 3d rumzuspielen. Ich meine nicht Java3D. Mir wurde auch geholfen mit meinem Bsp damals (wollte nur einen Würfel darstellen), aber ich möchte es mal wirklich verstehen. Ich habe jetzt gut 1 Stunde gegooglet, mit allen Begriffen die mir irgendwie eingefallen sind. Alle "Tutorials" die ich finde sind 1-2 Din-A 4 Seiten kurz und erklären gar nicht genau, wofür die Variablen in ihren Codes eigentlich stehen. Da steht dann "screen_x", was soll das nun sein? Desktop-Auflösung? Frame-Grösse? So geht das mit allem... Und wenn ichs versuch nachzumachen bleibt mein Fenster immer leer und mein Objekt liegt irgendwo wahrscheinlich bei -2349324,12334... 

Gibt es denn dafür keine guten Erklärungen? Die etwas ausführlicher sind? Das sind doch eigentlich nur n halbes dutzend Formeln, die man stur anwenden muss, um aus 3 Punkten 2 Punkte zu machen. Kann doch nich so schwer sein, entweder ich bin total doof oder die Leute im Inet kriegen's nich hin jmd. das gut zu erklären.

Wäre sehr dankbar für gute Links


----------



## 0x7F800000 (10. Apr 2009)

hdi hat gesagt.:


> Ich meine nicht Java3D.


Gut, und was meinst du stattdessen? Die codeunbehaftete Lineare Algebra oder wie? ???:L


----------



## hdi (10. Apr 2009)

Ich meine die Prozedur, einen 3d-punkt mittels mathematischer formeln in einen 2d-punkt umzuwandeln. Also quasi "per Hand". Das kann eig. nich so wild sein, es sind wie gesagt so 4-6 Formeln die man einfach auf einen 3d-punkt anwenden muss, abhängig von Screen-size und Blickwinkel usw.

Nennt sich eben einfach Projektion auf eine Ebene. Aber leider wird das nirgendwo etwas ausführlicher erklärt. Ich kriegs einfach nicht hin...
Das Ding ist, ich möchte jetzt nicht unbedingt Java3D lernen. Man muss die paar Formeln nur mal verstehen dann kriegt man damit auch recht simpel 3d-Spiele hin (im Sinne von wirklich nur 3d-Perspektive, also nix mit 3d-engine, Shader, usw.)


----------



## Marco13 (10. Apr 2009)

Hm. Teilweise sehe ich da Widersprüche... erstmal ein Widerspruch, der keiner ist:
_Also quasi "per Hand"._ --> _Das Ding ist, ich möchte jetzt nicht unbedingt Java3D lernen._

Die Zielsetzung bei der Verwendung von Java3D ist eben KOMPLETT unabhängig von dem ist, was ich (auch anhand deines Würfel-Threads von damals) jetzt als Intention vermute. Man verwendet Java3D ja gerade WEIL man sagen will: "Hier is 'ne Kamera - zeichne die Linien richtig". Was du im Moment vorhast klingt eher nach: "Zeichne die Linien so, dass es aussieht, als hätte man eine Kamera"... Das geht eben mehr in die Mathematischen Tiefen.

Was aber wirklich widersprüchllich klingt ist
_aber ich möchte es mal wirklich verstehen._
<- vs ->
_Das sind doch eigentlich nur n halbes dutzend Formeln, die man stur anwenden muss_

"Wirklich verstehen" und "stur anwenden" hat halt nicht viel miteinander zu tun. Ich hatte ja schon im letzten Thread angedeutet, dass ich mich auch schon lange nichtmehr mit sowas beschäftigt habe. Vor ein paar Jahren mal "oberflächlich" in einer Vorlesung (weil es heutzutage eben nicht mehr wirklich relevant ist). DAVOR hatte ich mir das ganze schonmal in Computer Graphics: Principles and Practice in C (Addison-Wesley Systems Programming Series): James D. Foley, Andries VanDam, Steven K. Feiner: Amazon.de: Englische Bücher angesehen (die "Bibel" der Grafikprogrammierung - aber IMHO für die meisten nur sehr eingeschränkt empfehlenswert (Bibel, eben  )). Da war ich noch weit davon weg, das überhaupt verstehen zu können (sinngemäß: "... aha...und was genau ist eine 'Matrix'?"), aber dort ist das ganze bis ins Detail mit Formeln, Herleitungen und Begründungen und kleinen mehr oder weniger anschaulichen Bildchen erklärt. In der Google-Buchsuche kann man da schonmal einen Blick reinwerfen...: Computer graphics: principles and ... - Google Buchsuche - worauf ich rauswill: Das ganze kann bei ausführlicher und allgemeiner Beschreibung auch schnell "erschlagen". Als Alternative kann man auch einfach die Matrix von Appendix F - OpenGL Programming Guide (unten) abtippen, und akzeptieren: "Jo, die macht die Projektion", und rotiert die dann Munter weiter wie eine Kamera. 

Welches Tutorial hast du denn bisher verwendet?


----------



## 0x7F800000 (10. Apr 2009)

Öhm... Also, wenn dich die etwas mathematischere Seite interessiert, und du Bleistiftskizzen akzeptierst, könnte ich das hier auch so skizzieren :autsch:


----------



## Spacerat (10. Apr 2009)

hdi hat gesagt.:


> Alle "Tutorials" die ich finde sind 1-2 Din-A 4 Seiten kurz...


Warum sollten die Erklärungen denn länger sein? Die sind doch eigentlich recht simple Formeln...
z.B. hier


----------



## hdi (10. Apr 2009)

Danke Spacerat, da wird schon mal mehr gesagt als in den anderen die ich mir gestern angesehen hab.

Allerdings stimmt irgendwas noch nicht. Ich habe die Formeln, wie sie dort stehen, angewandt, aber bekomme komische Werte.
Ich glaube es liegt daran dass ich das mit dem Winkel nicht ganz verstanden habe, bzw f und g.

Hier mal meine Werte:


```
public static int pwidth = 500;
	public static int pheight = 500;
	public static int degrees = 45;
	public static double f = pwidth / Math.tan(Math.toDegrees(degrees));
	public static double g = pheight / Math.tan(Math.toDegrees(degrees));
```

Auf einem 500x500 Panel also erstelle ich einen Würfel (Kantelänge 50), in 100px Tiefe, in der Mitte des Panels, dessen 3d-Punkte wie folgt gemappt werden:


```
public Point to2d() {
		double x2d, y2d;
		x2d = (x * f) / z + 0.5 * pwidth;
		y2d = (y * g) / z + 0.5 * pheight;
		return new Point((int) x2d, (int) y2d);
	}
```

Als Ergebnis bekomme ich allerdings folgendes:


```
Mapping [225,225,100] -> [-575,-575]
Mapping [275,225,100] -> [-759,-575]
Mapping [225,275,100] -> [-575,-759]
Mapping [275,275,100] -> [-759,-759]
Mapping [225,225,150] -> [-300,-300]
Mapping [275,225,150] -> [-423,-300]
Mapping [225,275,150] -> [-300,-423]
Mapping [275,275,150] -> [-423,-423]
Mapping [225,225,100] -> [-575,-575]
Mapping [225,275,100] -> [-575,-759]
Mapping [275,225,100] -> [-759,-575]
Mapping [275,275,100] -> [-759,-759]
Mapping [225,225,150] -> [-300,-300]
Mapping [225,275,150] -> [-300,-423]
Mapping [275,225,150] -> [-423,-300]
Mapping [275,275,150] -> [-423,-423]
Mapping [225,225,100] -> [-575,-575]
Mapping [225,225,150] -> [-300,-300]
Mapping [225,275,100] -> [-575,-759]
Mapping [225,275,150] -> [-300,-423]
Mapping [275,225,100] -> [-759,-575]
Mapping [275,225,150] -> [-423,-300]
Mapping [275,275,100] -> [-759,-759]
Mapping [275,275,150] -> [-423,-423]
```

Anscheinend stelle ich mich mit diesem Thema sehr dumm an?! Auch in diesem Tutorial scheine ich ja nicht zu begreifen was dieses f und g genau sein soll, bzw das 'a', also das mit dem Winkel. Ich war mir jetzt auch nicht so sicher, da wird was von Screen Resolutio geredet. Aber damit meinen die ja eben die Grösse vom Panel, in dem ich male oder? (Und nicht etwa die Desktop-Auflösung??)

Dank dir


----------



## 0x7F800000 (10. Apr 2009)

hdi hat gesagt.:


> Anscheinend stelle ich mich mit diesem Thema sehr dumm an?!




```
Math.toDegrees(degrees)
```
Mein Motto "Grad muss sterben" dürfte mittlerweile einigen bekannt sein, denke ich mal... :noe:


----------



## hdi (10. Apr 2009)

Ich verstehe dich leider nicht. 
Wenn ich das toDegrees() weglasse kommen auch seltsame Werte heraus. Ich gebe ja zu, ich habe auf dem Gymnasium in Mathe nicht aufgepasst. Bin hier echt aufgeschmissen...


----------



## Illuvatar (10. Apr 2009)

Schau dir nochmal

```
toDegrees(degrees)
```
ganz genau an, und überleg mal, was da vielleicht unsinnig dran sein könnte. Mal ganz abgesehen von jeglicher Mathematik (die btw bei 3d-Sachen durchaus ziemlich weiterhilft...)


----------



## 0x7F800000 (10. Apr 2009)

Ja, eben deswegen... Wenn du den Halben FOV-Winkel auf PI/4 setzen willst, dann schreib da doch eben direkt hin:

```
double halfFOV=Math.PI/4;
double tan=Math.tan(halfFOV);
```
oder noch besser direkt:

```
double tan=1;
```
oder sowas... Mit diesen komishcen gradmaß-winkeln schießen sich die Leute dauernd in den Fuß, aber können's trotzdem nicht lassen...

Was du mit deg=45  Math.toDeg(deg) ausgerechnet hast entspricht... 45*180/PI=2578.310078~820.70158 PI
Das entspricht also mehr als 400 umdrehungen, um am ende stoppt das glücksrad bei 0.7 PI , was für den halben FOV totaler blödsinn ist, weil es größer als PI/2 ist.

Ich würde sogar vorschlagen, du lässt alle winkeln weg, und drehst direkt an diesem tangens herum.

Dieser tangens gibt das verhältnis zwischen der breite des sichbaren bereiches und der sichtweite, also
tan=FarClippingPlaneWidth/FarClippingPlaneDistance
wenn dieses Verhältnis sehr klein wird (0.01, 0.001 usw...) Dann siehst du nur einen extrem schmalen Strahl (Etwa für Scharfschützengewehre in egoshootern gut)
Wenn du da werte um 1 einsetzt, kriegst du sichtfeld von insgesammt PI/2=90° (das was du wohl vorhattest). Wenn du da größere werte einsetzst, wird das sichtfeld breiter. Ich würde mit werten zwischen 1 und 2 experimentieren, und höhere werte für riesen-geschwindigkeiten bei rennspielen und warp-effekte nutzen...


----------



## Spacerat (10. Apr 2009)

Illuvatar hat gesagt.:


> Schau dir nochmal
> 
> ```
> toDegrees(degrees)
> ...


... oder versuchs mal mit [highlight=java]Math.toRadians(degrees);[/highlight]


----------



## Illuvatar (10. Apr 2009)

Spacerat hat gesagt.:


> ... oder versuchs mal mit [highlight=java]Math.toRadians(degrees);[/highlight]



Darauf wollte ich mit meinem Zaunpfahl hinweisen, genau


----------



## eliot (14. Apr 2009)

Schau mal hier:

Grundkurs Computergrafik mit Java. Die Grundlagen verstehen und einfach umsetzen mit Java 3D: Amazon.de: Frank Klawonn: Bücher

Ist von Frank Klawonn, bei ihm habe ihc meine omputergrafik Vorlesung genossen.
Das Buch leitet alles mathmatisch her, und zeiugt dann die Umsetzung in Java
(deckt gesetzte Standards in 2d und 3d ab). Sehr zu empfehlen!

regards
eliot


----------

