Zentralprojektion
Übersicht

funkmaster5000Betreff: Zentralprojektion |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo Community!
Ich versuche mich mal wieder an der Zentralprojektion. Die Formel? Einfach! Das Handling? Kompliziert! Da ich mich bislang auch nicht an die 3D Programmierung mit Blitz3D gemacht habe, verstehe ich die Zusammenhänge zwischen x,y,z und dem Blickpunkt des "Betrachters" nicht. Vielleicht gehe ich es auch falsch an. So wie ich es derzeit habe, gebe ich die Punkte meiner Straße in 3D an und daraus werden dann 2D x- und y-Koordinaten. Als Übung wollte ich so eine Pseudo-3D Straße programmieren a la: So weit so gut. Hier mal mein Code: Code: [AUSKLAPPEN] Graphics 320,200,32,2 SetBuffer BackBuffer() Type point3d ;hält die Informationen meines 3D-Punktes Field x Field y Field z End Type Type camera ;ist der Betrachter Field x Field y Field z End Type Const screen_width = 320 ;die Auflösung x Const screen_height = 200 ;die Auflösung y cam.camera = New camera ;neuen Betrachter erzeugen cam\x = 0 cam\y = 0 cam\z = -(screen_width / 2) For i = 100 To 1 Step -1 ;funktioniert, aber warum? Wenn ich z <> 1 eingebe, sind die Ergebnisse komisch p.point3d = New point3d p\x = -i p\y = i p\z = 1 Next While Not KeyHit(1) Cls For p.point3d = Each point3d x = (cam\x * p\z - p\x * cam\z) / (p\z - cam\z) + screen_width / 2 y = (cam\y * p\z - p\y * cam\z) / (p\z - cam\z) + screen_height / 2 Plot (x, y) ;Zeichne die Straße Next Flip Wend Welche Werte haben welchen Einfluss? Und warum? Warum muss ich mein z nicht verringern/erhöhen, wenn ich in die Tiefe gehe? Es funktioniert mit 1. Wenn ich die Straße jetzt auf den Betrachter zuscrollen lassen will, muss ich y und x verringern? Ich habe verschiedene Tutorials angeschaut, aber die waren alle nicht für BlitzBasic und das einzige (naja, war immerhin qbasic) ist nicht mehr verfügbar (siehe http://www.extentofthejam.com/pseudo/). Brauche ich den Betrachter überhaupt? Muss es überhaupt 3D sein, geht es nicht einfach mit einem Offset-Wert? Fragen über Fragen ![]() Danke im Voraus! |
||
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe mich zwar noch nie mit Zentralprojektion beschäftigt, aber ich glaube deine Formel geht davon aus, dass sich die Kamera hinter der Projektionsfläche befindet, was dazu führt, dass Bewegungen der Kamera im Z nur eine Art Skalierung bewirken würde.
Wenn du, wie du beschrieben hast, bewegungen in die Tiefe durch veränderung der Z-Koordinate der Kamera haben möchtest, musst du die Kamera vor die Projektionsfläche setzen und die Formel dementsprechend anpassen. Hier mal ein Beispiel wie ich das in BMax lösen würde (in BB umschreiben sollte kein Problem darstellen): Ich würde 3 Punkte als Fläche (Polygon) zusammenfügen und dann die ganze Fläche als 2D Projezieren. Bewegung der Kamera nach der Reihenfolge: W, S, A, D = Hoch, Runter, Links, Rechts Q und E = Zurück, Vor BlitzMax: [AUSKLAPPEN] SuperStrict Gruß Trust |
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
funkmaster5000 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Danke schonmal! Ich schreibe mir den Code heute abend um und dann sehen wir weiter ![]() |
||
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
Man könnte die Umrechnung auch ganz simpel mit Dreiecksberechnung und Winkelfunktionen machen.
Und hier mal ein kleines Testprogramm um zu veranschaulichen, wie das mit dem Blickpunkt funktioniert. Vielleicht wird dir dann einiges klarer ![]() BlickpunktTest.rar 52kb Verschiebe die Kamera mit W,A,S,D Gruß Trust |
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
- Zuletzt bearbeitet von Trust am So, März 17, 2013 18:07, insgesamt einmal bearbeitet
funkmaster5000 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Aha, deswegen kann die Kamera logischerweise auch nicht bei 0,0,0 liegen. Und je größer y, desto höher befinde ich mich über dem 3D Objekt. Dementsprechend muss y für jeden 3D Punkt gleich bleiben (es sei denn, ich wollte einen Hügel darstellen), x bedeutet eine Verschiebung nach links/rechts und z nach vorne/hinten.
Folgende Formel hab ich auch gefunden: Code: [AUSKLAPPEN] x = FOV * X / (Z + ZCENTER) + XCENTER y = FOV * Y / (Z + ZCENTER) + YCENTER Für mein Beispiel sind folgende Werte perfekt: Code: [AUSKLAPPEN] CONST XCENTER = 160 'Mitte des BildschirmsX (Auflösung = 320*200 px) CONST YCENTER = 100 'Mitte des BildschirmsY CONST ZCENTER = 256 'Warum? CONST FOV = ZCENTER 'Warum? CONST YCoord = 100 'So schließt die "Rennstrecke" mit dem unteren Bildschirmrand ab Ich verstehe die Wahl von FOV und ZCENTER nicht (habe ich aus einem anderen Tutorial). 256 wurde auch in anderen Tutorien als perfekt angesehen und das trifft auch zu, ich weiß nur nicht, warum? Außerdem muss FOV ZCENTER entsprechen, sonst klappts nicht. Fungiert das wie ein "Zoomfaktor"? |
||
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
FOV wird denke ich mal die "Brennweite" sein (Field Of View ??).
Schau dir dazu einfach mal mein BlickpunktTest-Programm an. Die Verschiebung der Kamera zur 2D-Projektionsfläche ist im Prinzip nix anderes als die Brennweite oder den Zoomfaktor zu verstellen. Und ZCENTER ist der Fluchtpunkt in der Tiefe. Auf der YCENTER-Höhe befindet sich dein "Horizont". Code: [AUSKLAPPEN] x = FOV * X / (Z + ZCENTER) + XCENTER
Code: [AUSKLAPPEN] FOV * X
Der Punkt wird im X, X mal zur Brennweite verschoben. Code: [AUSKLAPPEN] / (Z + ZCENTER)
Wieviel dieser Punkt tatsächlich im X verschoben wird, ist abhängig davon, wie weit der Abstand dieses Punktes in der Tiefe, zum Fluchtpunkt ist. Der Teiler Z+ZCENTER wird immer kleiner umso "näher" das 3D objekt der Kamera kommt, folglich wird die Verschiebung im X immer größer. Code: [AUSKLAPPEN] + XCENTER
Stellt sicher das von der Sceenmitte aus gerechnet wird Das selbe für Y. Dadurch entsteht diese Verschiebung, bzw. dieser Tiefeneindruck. Code: [AUSKLAPPEN] .
/ \ / \ / \ / \ Code: [AUSKLAPPEN] FOV = ZCENTER = 256
Warum das Optimal ist kann ich auch nicht sagen, dafür müsste ich vielleicht den ganzen Code sehen. Gruß Trust |
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
- Zuletzt bearbeitet von Trust am So, März 17, 2013 17:14, insgesamt 3-mal bearbeitet
funkmaster5000 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das ist im Prinzip der ganze Code! Erzeugt werden die Linien derzeit noch über Pixel, aber künftig möchte ich ein Type erstellen, der 2 Punkte enthält, die dann einfach über eine Linie verbunden werden.
Für eine Strecke liegt dann eine vorberechnete Datei mit den entsprechenden Koordinaten vor. Zumindest ist das die Idee. Ich errechne einmal die ganzen X-Werte für eine Gerade,Links-/Rechtskurve. Passieren dann 2 Punkte das Sichtfeld (zbewegung<= 0) wird ein Ereignis ausgelöst, das den kommenden Streckenabschnitt bestimmt. Die 2 Punkte übernehmen dann wieder ihr ursprüngliches z, erhalten aber je nach Ereignis das passende x. So verwerte ich die selben Types ständig wieder. So stelle ichs mir derzeit zumindest vor. Angewendet sieht der Code so aus: Code: [AUSKLAPPEN] CONST XCENTER = 160
CONST YCENTER = 100 CONST ZCENTER = 256 CONST FOV = 256 CONST YCoord = 100 FOR XCoord = -160 TO 160 FOR ZCoord = 1 TO 800 x = FOV * XCoord / (ZCoord + ZCENTER) + XCENTER y = FOV * YCoord / (ZCoord + ZCENTER) + YCENTER Plot x,y NEXT NEXT Daraus entsteht genau das Bild, das du mir als Ascii aufgezeichnet hast. Hast du vielleicht eine Idee, wie ich den Skalierungsfaktror eines Sprites aus dem z herausbekomme? Ich würde es prozentual machen. z = 800 = 0%, z = 1 = 100% |
||
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
ZCENTER ist der Startpunkt nicht der Endpunkt in der Tiefe.
Und FOV ist der Brennwert/Zoom. Warum FOV = ZCENTER? Ist FOV kleiner als ZCENTER also vor dem Fokuspunkt, reicht die Strasse nicht bis zum Bildschirmrand, weil du einen Bereich siehst, der noch vor dem Anfang der Strasse liegt. Ist FOV größer als ZCENTER, siehst du nicht die Strasse von Anfang an, sondern nur Teile vom Ende. Und dazu zerrt es das Bild. Nimm einfach mal das hier und spiele mit FOV und ZCENTER rum. BlitzBasic: [AUSKLAPPEN] Const XCENTER = 320 Zitat: Hast du vielleicht eine Idee, wie ich den Skalierungsfaktror eines Sprites aus dem z herausbekomme? Ich würde es prozentual machen. z = 800 = 0%, z = 1 = 100%
Ja genau, ist einfacher 3-Satz. Nur das 800 nah an der Kamera ist und 1 weit weg, da ZCENTER der Startpunkt im Z ist. Also: z = 1 = 0% und z = 800 = 100% Code: [AUSKLAPPEN] Also wenn 800 = 100% dann:
Spriteskalierung in % = (ZCoord/800) * 100 Gruß Trust |
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
funkmaster5000 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Erstmal Danke, dass du mir so nett hilfst! Interessiert dich das Thema? Ich finds ziemlich spannend ![]() So wurde es ja früher wirklich gemacht, als es noch kein "echtes" 3D gab. Schon ne super Leistung! Aber ich habe (natürlich) noch eine Frage: Trust hat Folgendes geschrieben: Nur das 800 nah an der Kamera ist und 1 weit weg, da ZCENTER der Startpunkt im Z ist. Also: z = 1 = 0% und z = 800 = 100% Bist du dir sicher? Bild 1: For ZCoord = 1 to 40 Bild 2: For ZCoord = 1 to 800 Je größer mein z, desto weiter reicht die Strecke! |
||
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ja, finde es ziemlich interessant! ![]() Wie man früher aus wenig Leistung viel rausgeholt hat. Deshalb hat es mir auch die Iso-Perspektive so angetan ![]() ZCENTER ist der um 256 verschobene Koordinatenursprung. Genauso wie XCENTER der um 160 verschobene Koordinatenursprung und YCENTER der um 100 verschobene Koordinatenursprung ist. Da es Z in 2D nicht gibt wird versucht es in X und Y auszudrücken. Umso weiter weg ein Objekt vom Z-Ursprung ist desto größer wird Y. Umso näher ein Objekt am Z Ursprung ist desto kleiner wird Y. Das "imaginäre" Z in 2D fängt wie du sagst bei der "Kamera" bzw. der 2D-Projektionfläche an. Also wird auch vom unteren Bildschirmrand angefangen zu zeichnen ( Y ist groß, da Punkt weit weg vom Koordinatenursprung) Zitat: Nur das 800 nah an der Kamera ist und 1 weit weg, da ZCENTER der Startpunkt im Z ist. Also: z = 1 = 0% und z = 800 = 100% Da habe ich mich aber wirklich vertan. Habe das oben geschriebene mit Z und Y verwechselt. Sorry ![]() Die Formel wäre dann nätürlich wenn z = 1 = 100% und z = 800 = 0% Code: [AUSKLAPPEN] Skalierung in % = 100 - (ZCoord/800) * 100
Gruß Trust |
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group