3D - Rotation

Anfängerfragen zum Programmieren mit PureBasic.
Andreas_S
Beiträge: 787
Registriert: 14.04.2007 16:48
Wohnort: Wien Umgebung
Kontaktdaten:

Beitrag von Andreas_S »

ok fertig



Zum allgemeinen:
x, y, z ... sind Punkte die den Abstand vom Ursprung angeben

a ... alfa
b ... beta
c ... gama


Code: Alles auswählen

X - Rotation:
	x' = x
	y' = cos(a) * y - sin(a) * z
	z' = sin(a) * y + cos(a) * z

Y - Rotation:
	x' = cos(b) * x - sin(b) * z
	y' = y
	z' = sin(b) * x + cos(b) * z

Z - Rotation:
	x' = cos(c) * x - sin(c) * y
	y' = sin(c) * x + cos(c) * y
	z' = z

Um dies allgemeinen Gleichungen in Matrizen umzuformen nimmt man jeweils die Faktoren der entsprechenden x, y, z Koordinaten:

Code: Alles auswählen

X - Rotation:
		x				--> x ... 1, y ... 0     , z ... 0
		cos(a) * y - sin(a) * z		--> x ... 0, y ... cos(a), z ... -sin(a)
		sin(a) * y + cos(a) * z		--> x ... 0, y ... sin(a), z ... cos(a)

	Y - Rotation:
		cos(b) * x - sin(b) * z		--> x ... cos(b), y ... 0, z ... -sin(b)
		y				--> x ... 0     , y ... 1, z ... 0
		sin(b) * x + cos(b) * z		--> x ... sin(b), y ... 0, z ... cos(b)

	Z - Rotation:
		cos(c) * x - sin(c) * y		--> x ... cos(c), y ... -sin(c), z ... 0
		sin(c) * x + cos(c) * y		--> x ... sin(c), y ... cos(c) , z ... 0
		z				--> x ... 0     , y ... 0      , z ... 1

Das entspricht dann volgenden Matrizen:

Code: Alles auswählen

X - Rotation:

		    ┌                         ┐
		    |  1   0        0         |
		    |                         |
		A = |  0   cos(a)   -sin(a)   |
		    |                         |
		    |  0   sin(a)   cos(a)    |
		    └                         ┘

	Y - Rotation:

		    ┌                         ┐
		    |  cos(b)   0   -sin(b)   |
		    |                         |
		B = |  0        1   0         |
		    |                         |
		    |  sin(b)   0   cos(b)    |
		    └                         ┘

	Z - Rotation:

		    ┌                         ┐
		    |  cos(c)   -sin(c)   0   |
		    |                         |
		C = |  sin(c)   cos(c)    0   |
		    |                         |
		    |  0        0         1   |
		    └                         ┘

(Man könnte hier eigendlich noch

Code: Alles auswählen

   ┌   ┐
   | x |
   |   |
 * | y |
   |   |
   | z |
   └   ┘
anführen aber das hab ich mir gespart weil es nicht notwendig ist)



Um aus diesen Matrizen eine zu machen rechnen wir einfach A * B * C

-> ps. achtung es dürfen bei Matrizen nie die Factoren vertauscht werden weil hier das Kommuntativgesetzt (oder wie das heißt) nicht gilt!


Code: Alles auswählen

            ┌                                                                                                                 ┐
            |   cos(b) * cos(c)                              -cos(b) * sin(c)                               -sin(b)           |
            |                                                                                                                 |
A * B * C = |  -sin(x) * sin(y) * cos(z) + cos(x) * sin(z)    sin(x) * sin(y) * sin(z) + cos(x) * cos(z)    -sin(a) * cos(b)  |
            |                                                                                                                 |
            |   cos(x) * sin(y) * cos(z) + sin(x) * sin(z)   -cos(x) * sin(y) * sin(z) + sin(x) * cos(z)     cos(a) * cos(b)  |
            └                                                                                                                 ┘


Das "Ergebnis" wird jetzt wieder

Code: Alles auswählen

   ┌   ┐
   | x |
   |   |
 * | y |
   |   |
   | z |
   └   ┘
und man bekommt volgendes herraus...


Code: Alles auswählen

x' =	x * (  cos(y) * cos(z) ) + 
	y * ( -cos(y) * sin(z) ) + 
	z * ( -sin(y) )

y' =	x * ( -sin(x) * sin(y) * cos(z) + cos(x) * sin(z) ) + 
	y * (  sin(x) * sin(y) * sin(z) + cos(x) * cos(z) ) + 
	z * ( -sin(x) * cos(y) );

z' =	x * (  cos(x) * sin(y) * cos(z) + sin(x) * sin(z) ) + 
	y * ( -cos(x) * sin(y) * sin(z) + sin(x) * cos(z) ) + 
	z * (  cos(x) * cos(y) )


Also wenns noch Fragen gibt, vil. kann ich sie beantworten...

Man glaubt garnicht wie schwer es ist Matrizen zu posten...

Andreas
Zuletzt geändert von Andreas_S am 29.08.2008 20:16, insgesamt 2-mal geändert.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Nice hat sich auf jedenfall gelohnt das viele Posten ,-)

Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Das ist ein gutes Beispiel für Rotationsmatrizen. Man sieht auch sehr schön,
wie einheitlich sie für die einzelnen Achsen aufgebaut sind.

Wenn man sich mit Matrizen schon ein bisschen auskennt und ein gutes
räumliches oder sogar mehrdimensionales Vorstellungsvermögen hat, kann
man sich auch mal diesen Wikipedia-Artikel über Rotationsmatrizen durchlesen.
Dort wird unter anderem erklärt, wie man Drehmatrizen für n-dimensionale
Räume erstellt.
Außerdem gibt es dort eine Matrix, mit der man einen Punkt um eine
beliebige Achse in Form eines Vektors in R³ drehen kann.
Andreas_S
Beiträge: 787
Registriert: 14.04.2007 16:48
Wohnort: Wien Umgebung
Kontaktdaten:

Beitrag von Andreas_S »

@NicTheQuick

Geniale Seite!

Zwei Frage Dazu:

Wie kommt man auf die zwei Matrizen im R2 Raum? :

Drehung eines Punktes:
Bild

Drehung eines Koordinatensystems:
Bild

Und kann man mit der Drehung des Koordinatensystems eine Art Camera-Effekt erzielen?

Danke im voraus,
Andreas
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

Ich schnall das nicht ganz. :freak:

Also ich hab des nicht ganz durchschaut, aber wenn ich nun (OpenGL 8) ) die 3D Koordinaten eines Punktes habe, und die Drehungswinkel, wie verwende ich dann die oben niedergeschriebenen Gleichungen? :freak: Klar, man könnte ja glRotatef_(W.f, X.f, Y.f, Z.f) nutzen, aber das ist irgendwie nicht "richtig".
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Andreas_S
Beiträge: 787
Registriert: 14.04.2007 16:48
Wohnort: Wien Umgebung
Kontaktdaten:

Beitrag von Andreas_S »

Erster Post...

Code: Alles auswählen

// X + Y + Z Rotation
   result.x = rotatePoint.x + (cos(rotateAngle.y) * cos(rotateAngle.z) * d.x - sin(rotateAngle.z) * d.y - sin(rotateAngle.y) * d.z);
   result.y = rotatePoint.y + (sin(rotateAngle.z) * d.x + cos(rotateAngle.z) * cos(rotateAngle.x) * d.y - sin(rotateAngle.x) * d.z);
   result.z = rotatePoint.z + (sin(rotateAngle.y) * d.x + cos(rotateAngle.y) * cos(rotateAngle.x) * d.z + sin(rotateAngle.x) * d.y);
Die Variablen sollten sich von selbst erklären...

Valls du nicht OOP lesen kannst:
result, rotatePoint, rotateAngle .... sind 3D Vektoren
also eine Struktur mit 3 Variablen (x|y|z).

Falls du die Variablen nicht verstehst:
d ... der Vektor um den der angeführte Vektor 'rotatePoint' gedreht werden soll.
rotatePoint ... rotations Mittelpunkt (Vektor)
result ... der neue Vektor mit der neuen Position (Vektor)
rotateAngle ... rotations winkel (Vektor)

Ich befürchte aber das OGL vil. die winkel anders rum hat... dann müsste der Vektor mit -1 multipliziert werden... (-x|-y|-z)
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

OOP ist mir schon bekannt. :)

Habs jetzt nicht gebacken gekriegt, muss ich nochmal mehr mit rumprobieren...
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Antworten