Seite 3 von 8

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 03.02.2013 22:29
von Falko
Danke @STARGÅTE :allright:

MfG Falko

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 16.08.2014 13:54
von silbersurfer
Schade Stargate auf PureBasic 5.2 läuft es leider nicht mehr

Code: Alles auswählen

Structure Drawing3D_Object
	StructureUnion
		Type.i
		Cluster.Drawing3D_Cluster ;<<<<<<<<< dieses Element
		Line.Drawing3D_Line
		Triangle.Drawing3D_Triangle
	EndStructureUnion
EndStructure


schmeißt den Fehler"Stucture mit Dymamischen Elementen ist in StructureUnion nicht erlaubt vielecht kannst du das ja beheben ?
Wäre Super denn Drawing3D ist echt gut :allright:

gruss Silbersurfer

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 16.08.2014 14:35
von STARGÅTE
du kannst glaube ich die ganze struktur auskommentieren, die wird in dieser Version die hier online ist eh nicht genutzt.

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 16.08.2014 16:43
von silbersurfer
jo das funzt... cool, Danke Stargate :allright:
Die Lib ist echt stark....

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 19.08.2014 19:16
von silbersurfer
hallo Stargate,

Ich habe da noch mal eine frage bezüglich Rotation Matrix

habe mir, um alles besser zu verstehen eine eigene Rotation Matrix erstellt
Die funtz auch soweit nur das Sie nach einiger Zeit aus dem Ruder Läuft und ich Frage mich warum?
wenn die Rotation für jede Achse allein gemacht werden läuft alles richtig
Bild

Code: Alles auswählen

With *use
		\p11=CosZ*CosY : \p21=-SinZ 		: \p31=-SinY
		\P12=SinZ		: \p22=CosZ*CosX	: \p32=-SinX
		\p13=SinY		: \p23=SinX		  : \p33=CosY*CosX
EndWith
dein Code hier
läuft sauber, nur kann Ich nicht ganz nachvollziehen warum

Code: Alles auswählen

*Use\p11 =  CosY*CosZ               	 : *Use\p12 = -CosY*SinZ            	    : *Use\p13 =  SinY
*Use\p21 =  SinX*SinY*CosZ+CosX*SinZ 	: *Use\p22 = -SinX*SinY*SinZ+CosX*CosZ 	: *Use\p23 = -SinX*CosY
*Use\p31 = -CosX*SinY*CosZ+SinX*SinZ 	: *Use\p32 =  CosX*SinY*SinZ+SinX*CosZ 	: *Use\p33 =  CosX*CosY
meine Frage was übersehe Ich jetzt hier
gruss Silbersurfer

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 19.08.2014 19:31
von STARGÅTE
Die Rotation im 3D-Raum ist eine Hintereinanderausführung von Einzelrotationen um jede der drei Achsen.
Zwar (bzw. vermutlich) stimmen deine Einzelrotationen, aber du hast sie "falsch" multipliziert.
RotationXYZ = RotationZ * RotationY * RotationX
Dabei werden die Matrixeinträge nicht einfach einzeln multipliziert, sondern nach der Vorschrift:
M = A * B -> M[i,j] = Summe[k]( A[i,k] * B[k,j] )

Dabei sei auch erwähnt, dass die Matrixmultiplikation nicht kommutativ ist, also A*B <> B*A ist.
Deswegen gibt es durchaus verschiedene Rotationsmatrizen, jenachdem welche Rotationsachen-Reihenfolge man definiert.
Weiterführende Literatur: Eulersche Winkel

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 19.08.2014 20:01
von silbersurfer
das habe Ich auch soweit verstanden und meine Matrix macht das auch so (denke Ich jetzt mal)
was Ich mit aus dem Ruder laufen meinte, ist das nach einiger Zeit sich die Pixel verschieben...
die Rotation verlaufen erstmal so wie erwartet nur das irgendwann sich die Form verändert (Viereck)
als wäre was ungenau an der Rechnung an sich *grübel

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 19.08.2014 22:49
von alter Mann
Das sich die Objekte, die Du mit der Transformationsmatrix "behandelst" nach einer Weile verzerrt dargestellt werden, ist nicht verwunderlich, da sich durch die ständige Matrixmultiplikation Fehler aufsummieren. Du must also die Transformationsmatrix nach einigen Multiplikationen wieder "orthogonalisieren". Eine "orthogonale" Transformationsmatrix hat eine Determinante von 1. Eine "verzerrte" Transformationsmatrix eine kleiner 1.

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 19.08.2014 22:56
von STARGÅTE
Redest du jetzt von deinem oder meinem Code?
Also die Matrix die jetzt noch im Post von dir steht ist falsch.

Das mit "aus dem Ruder Läuft" kann durchaus ein normales Artefakt der Matrizenrechung sein.
Bei jeder Matrizenmultiplikation entstehen ungenauigkeitden Aufgrund der Floats.
Eine fortlaufende Rotation mit einer Matrix führt zu einer Matrix die nicht mehr Normiert ist.
Das bedeutet anschaulich, das Objekt wird scheinbar "großer".

Aus diesem Grund verwenden 3D-Anwendungen Quaternions.
Dort wird eine Orientierung eines Objekts mit Hilfe von 4 Zahlen dargestellt und nicht mit 9 wie bei der Rotationsmatrix.
Außerdem sind weniger Multiplikationen nötig, sodass weniger Fehler entstehen.

Bei Drawing3D habe ich darauf verzichtet, da ich keine dynamischen Sachen anzeigen lassen wollte, da die Engine dafür eh zu langsam ist, sondern nur statische.

Ansonsten kannst du ja mal dein Code posten oder als PN zukommen lassen, vllt ist es auch was anderes.

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Verfasst: 21.08.2014 11:17
von silbersurfer
Hm da Ich leider kein Mathe Profi bin, und Mir immer alles hart in meinen Schädel hämmern muß
bin Ich mit meiner Wissensaufnahme hier wohl am Ende, mein Problem ist sicher nicht das Verstäntnis, sondern eher
die Schreibweise von Mathematik wo Ich immer wieder auf dem Schlauch stehe "Leider seuftz"

Stargate schrieb
Also die Matrix die jetzt noch im Post von dir steht ist falsch.
ja aber was genau mache Ich da Falsch ?
Mir ist auch aufgefallen das es nur zu fehlern kommt wenn Ich X und Y Achse Rotiere X-Z oder Y-Z ergeben in meinen Augen keine fehler
zumindest Rotieren Sie wie Ich mir das gedacht hatte

alter Mann Schrieb
Transformationsmatrix nach einigen Multiplikationen wieder "orthogonalisieren"
da Habe Ich das ganze Web durchsucht und auch viel gefunden nur leider wieder alles in der Mathesprache wo bei mir dann der Kopf Raucht
mir fehlt da immer der bezug wie man etwas in Progammiersprachen umsetzt

So Hier jetzt mal ein kleiner code wie Ich das meine Hoffe das er nicht alt so schlimm ist

Code: Alles auswählen

EnableExplicit

Structure Vector
	x.f
	y.f
	z.f
EndStructure

Structure surface
	xp.f : yp.f :image.i
	scale.f
	List vertex.Vector()
EndStructure

Structure Matrix3D
	p11.f : p21.f : p31.f
	p12.f : p22.f : p32.f
	p13.f : p23.f : p33.f
EndStructure

OpenWindow(0,0,0,800,600,"Test Grafik ausgaben !",#PB_Window_SystemMenu |#PB_Window_ScreenCentered )
ImageGadget(0,0,0,800,600,0)
Define image=CreateImage(#PB_Any,800,600)

Define testm.Matrix3D,sur1.surface
sur1\scale=100 :sur1\xp=400 : sur1\yp=300

Procedure addvertex(*use.surface,x.f,y.f,z.f)
	AddElement(*use\vertex())
	*use\vertex()\x=x* *use\scale
	*use\vertex()\y=y* *use\scale
	*use\vertex()\z=z* *use\scale
EndProcedure

Procedure.i Draw_Rotate3D(*Use.Vector, *Source.Matrix3D)
	Protected Buffer.Vector 
	CopyMemory(*Use, @Buffer, SizeOf(Vector))
	*Use\Z = Buffer\z**Source\p33 + Buffer\Y**Source\p32 + Buffer\x**Source\p31
	*Use\Y = Buffer\z**Source\p23 + Buffer\Y**Source\p22 + Buffer\x**Source\p21
	*Use\X = Buffer\z**Source\p13 + Buffer\Y**Source\p12 + Buffer\x**Source\p11	
	ProcedureReturn *Use
EndProcedure

Procedure.i Rotation(*use.Matrix3D,x.f,y.f,z.f)
	Protected CosZ.f = Cos(Z), CosY.f = Cos(Y), CosX.f = Cos(X)
	Protected SinZ.f = Sin(Z), SinY.f = Sin(Y), SinX.f = Sin(X)	
; 	*Use\p11 =  CosY*CosZ              			  	: *Use\p12 = -CosY*SinZ            			    : *Use\p13 =  SinY
; 	*Use\p21 =  SinX*SinY*CosZ+CosX*SinZ 	: *Use\p22 = -SinX*SinY*SinZ+CosX*CosZ 	: *Use\p23 = -SinX*CosY
; 	*Use\p31 = -CosX*SinY*CosZ+SinX*SinZ 	: *Use\p32 =  CosX*SinY*SinZ+SinX*CosZ 	: *Use\p33 =  CosX*CosY
	With *use
		\p11=CosZ*CosY	: \p21=-SinZ				: \p31=-SinY
		\P12=SinZ				: \p22=CosZ*CosX	: \p32=-SinX
		\p13=SinY			: \p23=SinX				: \p33=CosY*CosX
	EndWith	
	ProcedureReturn *use
EndProcedure

Procedure draw(*this.surface)
	Shared testm
	Protected bx.f,by.f,x.f,y.f,z.f
	Box(0,0,800,600,$000000)
	bx=*this\vertex()\x : by=*this\vertex()\y
	ForEach *this\vertex()		
		x=*this\vertex()\x : y=*this\vertex()\y
		LineXY(*this\xp+bx,*this\yp+by,*this\xp+x,*this\yp+y)
		bx=x : by=y
		Draw_Rotate3D(*this\vertex(), testm)
	Next 
EndProcedure




addvertex(sur1,-1,1,0)
addvertex(sur1,1,1,0)
addvertex(sur1,1,-1,0)
addvertex(sur1,-1,-1,0)

Rotation(testm,0.01,0.0,0.002)


Repeat 
	If StartDrawing(ImageOutput(image))		
		draw(sur1)
		StopDrawing()	
	EndIf 
	SetGadgetState(0,ImageID(image))
Until WindowEvent()=#PB_Event_CloseWindow