PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : aus cordinaten 3d bild erechnen?


Lukas Luehr
16.09.2010, 14:34
ich habe jetzt eingie cordinaten pare (je drei cordinaten) das sind die eck kordinaten eines 3d würfels und ich wolte jetzt gerne wissen wie ich diese kordianten nur mit linien darstellen kann das ist alles ich hoffe das das nicht al zu schwer ist

vielen dank schonmal


AGGROStar1991
16.09.2010, 16:20
Es wäre praktisch, wenn du Plattform, Grafiktoolkit usw angibst. Ausserdem weiss ich nicht was du mit linien meinst? aus einem punkt kann man keine lineare funktion machen. Oder meinst du Vektoren? damit wäre dann jeder Punkt eindeutig durch seinen Ortsvektor bestimmt( Vektor vom Nullpunkt zu diesem Punkt)


mfg

Firefall
16.09.2010, 17:19
Ich denke er meint ein Wireframe erzeugen.

Lukas Luehr
17.09.2010, 12:13
ich habe cordinaten : 3,3,3 und 9,6,9 zwischen diesen cordinaten möchte ich eine linie ziehen.
ich möchte nur wissen wie ich 3d cordinaten in bildschirm cordinaten umrechne ich habe davon auch ein buch aber ich weiß nicht genau wo das ist

Xpyder
17.09.2010, 13:17
Nehmen wir einmal an, die Koordinaten wären X, Y und Z - wobei X die waagerechte Koordinate in einem gedachten Koordinatensystem wäre und Y die senkrechte. Z wäre dann die "Tiefe", würde also "nach hinten" - in den Raum hinein gehen.
Außerdem denke Dir die Bildschirmmitte als Koordinaten 0,0 des gedachten Koordinatensystems.
Dann sind die beiden Koordinaten des Zielpunktes (also da, wo sie "im 3D" von vorn aus zu sehen wären) : Xziel = X/Z und Yziel= Y/Z
Meistens wird das alles aber sehr klein werden, sich also nah am Mittelpunkt aufhalten, daher sollte man die "Voxelgröße" eventuell etwas größer wählen, d.h. den gedachten Abstand zwischen zwei Punkten, bzw die "Einheit"... Will sagen: Entweder man macht X und Y sehr groß oder man multipliziert es mit einer Einheit, die den "kleinsten Pixel" angibt.
(Anmerkung: Die Z-Koordinate muß immer positiv und größer als Null sein. Denn Null wäre genau der Bildschirm selbst und negative Z befinden sich "vor" dem Bildschirm - wären daher nicht darstellbar.)

Erklärung zur "kleinsten Pixel Einheit":
Das mit dem "kleinsten Pixel" meine ich so: Nehmen wir an, man spielt ein älteres Ballerspiel, wie z.B. DOOM, wo es noch kein Anti-Aliasing (verwischen der Pixel) bei den Texturen gab. Wenn die Wände ganz nah vor einem standen, waren die Textturpixel große Quadrate. Bei einer Entfernung von 1 hätten sie die größe der besagten Einheit. (Wäre die Einheit also 1, wäre ein Texturpixel, wenn man schon mit der Nase an der Wand stehen würde, so groß wie ein Bildschirmpixel - das würde aber bedeuten, daß man wahnsinnig riesige Texturen bräuchte und meistens steht man nie mit einer Entfernung von nur 1 Pixel an der Wand.)

Will sagen: Eigentlich könnte man also so eine "Einheit" dazurechnen, was dann bedeutet, daß die Formeln für die "3D"-Bildkoordinaten wären:
Xziel=Einheit*X/Z und YZiel=Einheit*Y/Z.
So, und weil man sich ja die Bildmitte als 0,0 vorstellt, muß man ja eigentlich die Hälfte der jeweiligen Auflösung auch noch addieren. (Die schreibt man besser irgendwo vorher in Variablen.)
Nehmen wir mal an, die Auflösung wäre 640x480. Dann würde es bedeuten
Xziel=Einheit*X/Z+320 und YZiel=Einheit*Y/Z+240.
(Achja, man nimmt nur den ganzzahligen Teil für die Punktkoordinaten, weil man ja keine "halben Pixel" darstellen kann.)
Das Ganze macht man auch mit dem zweiten Punkt. Und dann zieht man einfach, wie im 2D, eine Linie vom ersten zum zweiten Punkt.
Und JA! Eigentlich ist das nicht ganz korrekt, denn durch die perspektivische Verzerrung müßte die Linie eigentlich nicht ganz gerade sein (wie im 2D) sondern eine minimale Kurve drin haben. Aber: 1.) Das würde aber nur bei wahnsinnig langen Linien sichtbar werden (ansosten würde sich das im Nachkommabereich wegrechnen) und 2.) Wenn man das wirklich so korrekt wollen haben würde, müßte man alle Punkte der Linie einzeln nach der obengenannten Methode berechnen und darstellen, was ein immenser Rechenaufwand wäre und was deshalb meines Erachtens kaum gemacht wird.
Sollte es noch Fragen geben - vielleicht, weil meine Erklärung zu abstrakt und unverständlich war - oder z.B. nach weiteren Dingen - wie man solche 3D-Objekte dann z.B. im Raum dreht (z.B. sich selbst um sie herum bewegt), kann ich das gern auch noch erklären.
Ich hoffe, ich konnte helfen.

Lukas Luehr
17.09.2010, 13:47
ich habe das jetzt wie volgt gelöst :

ScreemX=Y-(X/2)
ScreemY=Z-(X/2)



ist das auch richtig oder ist das nur so eine art 3d ?

EDIT:
Ich habe grade herausgefunden das das leider nur die isometrische darstellung ist das ist blöd
kan mier jemdand die richtige formel sagen?
meisnst du:
Xziel=Einheit*X/Z oder
Xziel=Einheit*(X/Z)

Xpyder
17.09.2010, 16:36
kan mier jemdand die richtige formel sagen?
meisnst du:
Xziel=Einheit*X/Z oder
Xziel=Einheit*(X/Z)

Es ist eigentlich egal, weil in beiden Fällen dasselbe Ergebnis herauskommt. Also laß lieber die Klammern weg. Ein dummer Compiler könnte sonst langsameren Code erzeugen, der eigentlich nicht sein müßte.
Erklärung: Ich mache lieber die Multiplikationen alle vor den Divisionen. Auf die Art ist die Multiplikation in diesem speziellen Fall integer (ganzzahlig) und nur die Division gebrochenzahlig (Kommazahlen).
Außerdem würde man, da man ja sowieso nur eine Integer-Zahl braucht, nach der Division ohnein auf eine ganze Zahl runden - könnte also gleich eine integer-Division (also ganzzahlige Division ohne Rest) benutzen (die meisten Programmiersprachen bieten sowas an). Und in dem Fall MUß dann die Multiplikation vor der Division ausgeführt werden, um größere Genauigkeit zu kriegen.
Beispiel zu diesem Problem
Gegeben: Einheit=25, X=100, Z=30
Rechnet man Einheit*X und dann DIV Z (DIV als Beispiel für ganzzahlige Division), erhält man: 25*100 DIV 30, also 25000 DIV 30 = 833
Rechnet man dagegen zuerst X DIV Z und dann *Einheit, also 100 DIV 30 (=33) und dann * 25, erhält man 825, was ungenauer ist.

Im Falle mit Fließkomma-Rechnung ergibt sich das Problem in beiden Fällen zwar nicht (obwohl auch da im ersten Fall gar keine Fließkomma-Rechnung nötig wäre), aber Fließkomma-Rechnungen (also mit "Kommazahlen") werden auf dem Rechner langsamer ausgeführt als Integer-Rechnungen. Und da man sowieso am Ende ganzzahlige Ergebnisse haben will, kann man die Fließkomma-Rechnungen vermeiden, indem man zuerst alle Multiplikationen ausführt und dann erst dividiert.

Lukas Luehr
17.09.2010, 17:41
danke ich schreinbe das übrigents mit blitz basick und wil das später mit c++ nach schreiben nun habe ich volgenden code (ausschnitt):

Xmin=0
Ymin=0
Xmax=800
Ymax=600
Hpix=800
Vpix=600
Graphics Xmax,Ymax,0,0

SetBuffer BackBuffer()

AZ_P=8
AZ_L=12
Dim Lines_3D(AZ_L,2)
Dim Punkte_2d(AZ_P,2)
Dim Punkte_3d(AZ_P,3)
Dim Punkte_BS(AZ_P,2)


Cordinaten_X=250
Cordinaten_Y=250

;datensegment
For I=1 To AZ_P
For J =1 To 3
Read Punkte_3d(I,J)
Next
Next
Data 0,0,0,0,5,0,5,5,0,5,0,0
Data 0,0,5,0,5,5,5,5,5,5,0,5


For I=1 To AZ_L
For J =1 To 2
Read Lines_3D(I,J)
Next
Next
Data 1,2,2,3,3,4,4,1,1,5,5,6,6,7,7,8,8,5,6,2,7,3,8,4
;Data 1,3,2,7,4,5,6,8,1,6,4,7
;ende datensegment
Repeat
;--------------------------------------------------------------------

a=0
b=0
g=0
If KeyDown(200) b = 10
If KeyDown(208) b = -10
If KeyDown(203) g = 10
If KeyDown(205) g = -10
If KeyDown(2) a = 10
If KeyDown(3) a = -10
For I = 1 To AZ_P
X=Punkte_3d(I,1)
Y=Punkte_3d(I,2)
Z=Punkte_3d(I,3)
;Drehwinkel: a um die x-Achse, b um die y-Achse und g um die z-Achse
x_n = Cos(b) * Cos(g) * x - Cos(b) * Sin(g) * y + Sin(b) * z
y_n = (Cos(a) * Sin(g) + Sin(a) * Sin(b) * Cos(g)) * x + (Cos(a) * Cos(g) - Sin(a) * Sin(b) * Sin(g)) * y - Sin(a) * Cos(b) * z
z_n = (Sin(a) * Sin(g) - Cos(a) * Sin(b) * Cos(g)) * x + (Sin(a) * Cos(g) + Cos(a) * Sin(b) * Sin(g)) * y + Cos(a) * Cos(b) * z
Punkte_3d(I,1)=x_n
Punkte_3d(I,2)=y_n
Punkte_3d(I,3)=z_n
Next
;--------------------------------------------------------------------
For I=1 To AZ_P
;3d zu 2d
If Punkte_3d(I,3)> 0 Then
Punkte_2d(I,1)=25*Punkte_3d(I,1)/Punkte_3d(I,3)
Punkte_2d(I,2)=25*Punkte_3d(I,2)/Punkte_3d(I,3)
Else
Punkte_2d(I,1)=25*Punkte_3d(I,1)
Punkte_2d(I,2)=25*Punkte_3d(I,2)
EndIf
Next
For I = 1 To AZ_L
Line Punkte_2D(Lines_3D(I,1),1)+Cordinaten_X,Punkte_2D(Lines_3D(I,1),2)+Cordinaten_Y,Punkte_2D(Lines_3D(I,2),1)+Cordinaten_X,Punkte_2D(Lines_3D(I,2),2)+Cordinaten_Y
Next
Flip
Delay 50
Cls
Until KeyDown(1)
End


wen ich das so mache sieht das ganze zwar sehr lsutig aus aber halt nicht so wie es seine solte sieht da jemand einen fehler ich kan mier vorstellendas ich beid er ratation einen fehler gemacht habe aber ich habe da nichts gefunden

amoxys
17.09.2010, 23:59
ich habe davon auch ein buch aber ich weiß nicht genau wo das ist
Mir rutschen die oft unters Bett, oder im Regal nach ganz hinten unten. Und meist sind sie dort, wo man zuallererst nachgesehen hat. Nicht entmutigen lassen. Irgendwo muss es ja sein.

Das Ganze macht man auch mit dem zweiten Punkt. Und dann zieht man einfach, wie im 2D, eine Linie vom ersten zum zweiten Punkt.
Und JA! Eigentlich ist das nicht ganz korrekt, denn durch die perspektivische Verzerrung müßte die Linie eigentlich nicht ganz gerade sein (wie im 2D) sondern eine minimale Kurve drin haben.
Nicht durcheinander bringen. :) Die Endpunkte sind vollkommen ausreichend. Die Funktion mit der die Punktkoordinaten berechnet werden ist ja linear, also würde auch eine gerade Linie entstehen, wenn man alle Punkte einzeln zeichnet. Die perspektivische Verzerrung macht sich u.a. darin bemerkbar, dass eigentlich parallel verlaufende Geraden sich scheinbar annähern. Aber sie sind immer noch gerade.

wen ich das so mache sieht das ganze zwar sehr lsutig aus aber halt nicht so wie es seine solte
Wo liegt denn das Rotationszentrum? Außerdem kannst du doch die Z-Koordinate nicht einfach auf einen konstanten Wert setzen, wenn sie zu klein wird. Da müssen ausgeklügeltere Techniken ran. :rolleyes:

Lukas Luehr
18.09.2010, 11:10
Die z kordiante ist kein konstanter wert bei ener rotation wird er ne erechnet udnes rotiert um den null punkt des objektes (0,0,0).

ich habe das program jetzt umgeschreiben damit die original objekt kordianten nicht verendert werden sonder eine kopie davon erstelt wird.

ein weiteres proble wahr , das die cordinaten integer wahren jetzt habe ich flout draus gemacht.

hier , der queltext:

Xmin=0
Ymin=0
Xmax=800
Ymax=600
Hpix=800
Vpix=600
Graphics Xmax,Ymax,0,0

SetBuffer BackBuffer()
Faktor#=100.000
AZ_P=8
AZ_L=12
Dim Lines_3D(AZ_L,2)
Dim Punkte_2d(AZ_P,2)
Dim Punkte_3d#(AZ_P,3)
Dim Punkte_3d_Original#(AZ_P,3)
Dim Punkte_BS(AZ_P,2)


Cordinaten_X=250
Cordinaten_Y=250

;datensegment
For I=1 To AZ_P
For J =1 To 3
Read Punkte_3d_Original(I,J)
Punkte_3d(I,J)=Punkte_3d_Original(I,J)
Next
Next
Data 0,0,0,0,1.05,0,1.05,1.05,0,1.05,0,0
Data 0,0,1.05,0,1.05,1.05,1.05,1.05,1.05,1.05,0,1.05


For I=1 To AZ_L
For J =1 To 2
Read Lines_3D(I,J)
Next
Next
Data 1,2,2,3,3,4,4,1,1,5,5,6,6,7,7,8,8,5,6,2,7,3,8,4
Data 1,3,2,7,4,5,6,8,1,6,4,7
;ende datensegment
Repeat
;--------------------------------------------------------------------

a=0
b=0
g=0
If KeyDown(200) b = 1
If KeyDown(208) b = -1
If KeyDown(203) g = 1
If KeyDown(205) g = -1
If KeyDown(2) a = 1
If KeyDown(3) a = -1
For I = 1 To AZ_P
Rotate_A=Rotate_A+a
Rotate_B=Rotate_B+b
Rotate_G=Rotate_G+g
X=Punkte_3d_Original(I,1)
Y=Punkte_3d_Original(I,2)
Z=Punkte_3d_Original(I,3)
;Drehwinkel: a um die x-Achse, b um die y-Achse und g um die z-Achse
x_n = Cos(Rotate_B) * Cos(Rotate_G) * x - Cos(Rotate_B) * Sin(g) * y + Sin(Rotate_B) * z
y_n = (Cos(Rotate_A) * Sin(Rotate_G) + Sin(Rotate_A) * Sin(Rotate_B) * Cos(Rotate_G)) * x + (Cos(Rotate_A) * Cos(Rotate_G) - Sin(Rotate_A) * Sin(Rotate_B) * Sin(Rotate_G)) * y - Sin(Rotate_A) * Cos(Rotate_B) * z
z_n = (Sin(Rotate_A) * Sin(Rotate_G) - Cos(Rotate_A) * Sin(Rotate_B) * Cos(Rotate_G)) * x + (Sin(Rotate_A) * Cos(Rotate_G) + Cos(Rotate_A) * Sin(Rotate_B) * Sin(Rotate_G)) * y + Cos(Rotate_A) * Cos(Rotate_B) * z
Punkte_3d(I,1)=x_n
Punkte_3d(I,2)=y_n
Punkte_3d(I,3)=z_n
Next
;--------------------------------------------------------------------
For I=1 To AZ_P
;3d zu 2d
If Punkte_3d(I,3)> 0 Then
Punkte_2d(I,1)=Faktor*Punkte_3d(I,1)/Punkte_3d(I,3)
Punkte_2d(I,2)=Faktor*Punkte_3d(I,2)/Punkte_3d(I,3)
Else
Punkte_2d(I,1)=Faktor*Punkte_3d(I,1)
Punkte_2d(I,2)=Faktor*Punkte_3d(I,2)
EndIf
Next
For I = 1 To AZ_L
Line Punkte_2D(Lines_3D(I,1),1)+Cordinaten_X,Punkte_2D(Lines_3D(I,1),2)+Cordinaten_Y,Punkte_2D(Lines_3D(I,2),1)+Cordinaten_X,Punkte_2D(Lines_3D(I,2),2)+Cordinaten_Y
Next
Flip
Delay 50
Cls
Until KeyDown(1)
End


ich habe das buch wieder gefunden , das hatte mein vater sich genommen.
Und eine frage dei nichts hiermit zu tun hat : ist es überhaut möglich mit

Brainfuck(eine progrmmiersprache) ein nützliches programm zu scheiben ?