# frage zu glrotated



## Campino (2. Aug 2005)

hi, 

dreht openGL bei dem Befehl glrotated() um einen Punkt oder um einen Vector? 

Als Beispiel nehme ich mal 0/0/1. Wenn die Funktion um einen Punkt dreht, würde das Ergebnis sich ändern, wenn man sich weiter vom Punkt entfernt (der Punkt hat ja eine feste Position). Wenn die Drehung um einen Vector erfolgt, würde das Ergebnis durch die Entfernung vom Punkt (der dann ja nicht vorhanden ist) nicht beeinflusst (der Vector gibt schließlich nur an, dass es sich um eine senkrechte Achse handelt, um die gedreht wird). 

Danke schonmal, 

campino


----------



## Beni (2. Aug 2005)

Drehen tut man immer um eine _Achse_, und eine Achse ist eine Gerade. Eine Gerade ist aber fest im Raum (so wie ein Punkt), und es kommt sehr wohl darauf an, wieweit man von der Achse entfernt ist. (Dreh dich mal um dich selbst (um die "Körperachse", die geht durch den Kopf und in dem Mittelpunkt der Füsse vorbei), deine Arme bewegen sich weiter, als z.B. deine Nase...)


----------



## Campino (3. Aug 2005)

mhh..

also, weshalb ich eigentlich fragte:

Ich zeichne ein Prisma, bestehend aus QuadFaces und TriangleFaces. Dieses Prisma wird standardmäßig so gezeichnet, dass man von oben darauf guckt. Ich will es mit glRotated so drehen, dass man auf eine der dreieckigen Seiten sieht. Ich erstelle also mit glPushMatrix eine neue Matrix, drehe mit glRotated, erstelle mein Prisma und rufe glPopmatrix auf, um wieder zur alten Matrix zurückzukehren. Dabei dreht dass Prisma sich nicht nur, sondern es verschiebt sich auch ganz weit im Raum, fast als würde es sich auf einer Kreisbahn um den Nullpunkt befinden. Wie kriege ich das Prisma dazu, auf seiner Position zu bleiben. Als Achse gebe ich einen Eckpunkt des Prisma an, der Winkel ist 50°. 

Kann ich das Prisma z.B. mit glTranslated wieder an seine Position schieben? Wenn ja: wie müssen die Parameter aussehen?

Danke schonmal, 
campino


----------



## stev.glasow (3. Aug 2005)

mit glTranslated verschiebt man den Nullpunkt und dieser ist dann auch der Ausgangspunkt für die Drehung. Zeichnest du deine Körper auch um den Nullpunkt?


----------



## Soulfly (3. Aug 2005)

Das mit Achse ist mir bei dir auch nicht geheuer.

glRotated(rot,xachse,yachse,zachse);

Das mit dem Punkt von dem Prisma wird wahrscheinlich einen komischen effekt haben.
Versuche doch erstmal um eine Achse zu drehen. 
Y-achse z.B.

glRotated(rot,0.0,1.0,0.0);


----------



## Beni (3. Aug 2005)

Die Achse um die man rotiert geht immer durch den Nullpunkt. Wenn  die Achse durch einen anderen Punkt gehen soll, muss man erst mit "glTranslate" diesen Punkt an die Stelle 0/0/0 bringen. (also "glTranslate( -x, -y, -z )" aufrufen).



> fast als würde es sich auf einer Kreisbahn um den Nullpunkt befinden


Nur fast, die Kreisbahn geht um den nächsten Punkt auf der Achse :wink:

[Edit]
Vielleicht hilft ein Bildchen.






Die roten Kreise sind die Bahnen, auf denen sich die Punkte des Tetraeders bewegen. Die Bahnebenen sind jeweils normal (senkrecht) zur Achse, und der Mittelpunkt der Bahnen auf der Achse.
Die Achse (die Richtung ist durch x/y/z gegeben) geht immer durch den Nullpunkt.


----------



## Campino (3. Aug 2005)

Beni hat gesagt.:
			
		

> Die Achse um die man rotiert geht immer durch den Nullpunkt. Wenn  die Achse durch einen anderen Punkt gehen soll, muss man erst mit "glTranslate" diesen Punkt an die Stelle 0/0/0 bringen. (also "glTranslate( -x, -y, -z )" aufrufen).
> 
> 
> 
> ...


ahhh...okay, danke...

EDIT: doch noch Problem:


```
gl.glPushMatrix();
		gl.glTranslated(-vx, -vy, -vz);
		gl.glRotated(50, 0, 0, 0);
		//gl.glTranslated(vx, vy, vz);
                //Code für das Prisma
gl.glPopMatrix();
```

also: so entsteht das Prisma am Nullpunkt (allerdings richtig gedreht). Ich wollte es also, mit dem Zweiten translate zurückschieben, allerdings verschwindet es dabei ganz (bzw. rutscht unter andere Objekte, etwa 50(?) nach links). Was mache ich falsch?


----------



## Beni (3. Aug 2005)

Also, das wieso kann ich dir mal erklären: Du schiebst zuerst in die Richtung x. Dann rotierst du, und dann willst du in die Richtung -x schieben. Aber weil du rotiert hast, schiebst du in "-rotiert( x )"...

Du kannst die Matrix die die Rotation beschreibt selbst berechnen, hier ist sie.
Wenn ich mich nicht verrechnet habe: rufe zuerst glRotate auf, berechne die Matrix M (einfach abtippen was in der Doku steht), berechne p' = M*p (Vektor-Matrix-Multiplikation), wobei p der Punkt ist, um den du rotieren willst, und rufe dann glTranslate mit p-p' auf.
(Der Punkt p soll an derselben Position bleiben, und "p = M*p + p -p' " (M*p=Rotation, p-p'=Translation)
Vielleicht musst du da ein bisschen ausprobieren, eine einfachere Lösung hab ich nicht auf Lager.


----------



## Soulfly (3. Aug 2005)

Du musst diese reihenfolge haben

push()
gltranslate(..)
glrotate(..)
Prisma zeichen
pop()


----------



## Campino (4. Aug 2005)

Soulfly: 
nichts anderes hab ich oben in meinem Code, oder?

Beni:
1) ich habs versucht, nur die Vector-Matrix-Multiplikation macht Probleme. Ich habe die Schleife aus deinem Link in Java umgesetzt, wenn ich die Variablen richtig zugeordnet habe (Y=p', X=p, C=M) müsste das wie unten aussehen, oder? 

Allerdings tritt in Zeile 34 eine ArrayIndexOutOfBoundsException auf, weil der Vector 3 und die Matrix 4 Felder hat, wie löse ich dieses Problem?

2) habe ich die Matrix richtig umgesetzt? Müssen die leeren Zeilen in der Docu wirklich in leere Zeilen im Array, so wie ich das gemacht hab, umgesetzt werden?

So, jetzt der Code:

```
gl.glPushMatrix();
		gl.glRotated(this.getAngle(), 0, 0, 0);
		
		double c = Math.cos(this.getAngle());
		double s = Math.sin(this.getAngle());

		double[][] md=new double[6][4]; //<-Die Matrix
		md[0][0]= x*x*(1-c)+c;
		md[0][1]=x*y*(1-c)-z*s;  
		md[0][2]=x*z*(1-c)+y*s;	 
		md[0][3]=0;
		//leere Zeile 1
		 md[2][0]=y*x*(1-c)+z*s;
		 md[2][1]=y*y*(1-c)+c;
		 md[2][2]=y*z*(1-c)-x*s;	 
		 md[2][3]=0;
		 
		 md[3][0]=x*z*(1-c)-y*s;	
		 md[3][1]=y*z*(1-c)+x*s;  
		 md[3][2]=z*z*(1-c)+c;	 
		 md[3][3]=0;  
		 //leere Zeile 4
		 md[5][0]=0;
		 md[5][1]=0;		 
		 md[5][2]=0;	 
		 md[5][3]=1;
		 
		 double p[]={x, y, z};
		 double[] ps={0d, 0d, 0d};
		 
		 for(int i=0;i<md.length;i++){ //eigentlich i=1
           for(int j=0;i<md[i].length;j++){ //eigentlich j=1
             ps[i] = ps[i] + md[i][j]*p[j];
           }
		 }
		 
		 gl.glTranslated((p[0]-ps[0]), (p[1]-ps[1]), (p[2]-ps[1]));
//Prisma zeichnen
gl.glPopMatrix();
```


----------



## stev.glasow (4. Aug 2005)

Campino hat gesagt.:
			
		

> Soulfly:
> nichts anderes hab ich oben in meinem Code, oder?


Na doch, glrotate ist das erste was du nach dem pushmatrix machst.

das glTranslate muss vor das glrotate, glTranslate  verschiebt den nullpunkt und glrotate dreht um diesen
[edit]



> gl.glRotated(this.getAngle(), 0, 0, 0);


Wieso sind denn x,y, z gleich 0?


----------



## Campino (4. Aug 2005)

stevg hat gesagt.:
			
		

> Campino hat gesagt.:
> 
> 
> 
> ...



Stimmmt, so geht's...


Soufly: tschuldigung...
Beni: hat sich erledigt 

all: 
:applaus:  

[schild=6 fontcolor=000000 shadowcolor=C0C0C0 shieldshadow=1]Danke[/schild]


----------



## Soulfly (5. Aug 2005)

Angenommen!


----------

