Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 07:15

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Rotieren
BeitragVerfasst: Mi Jun 30, 2010 16:12 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
Moin,

ich versuche die ganze Zeit schon meine Objekte um einen vorgegebenen Vertex entsprechend zu drehen. Kurz: ich habe eine Ansammlung von Objekten welche die Infos Position & Rotation beinhalten, so werden diese dann auch gerendert. Nun möchte ich jedoch mehrere Objekte auswählen können und diese entsprechend des Mittelpunktes der Auswahl rotieren. D.h ich muss dann entsprechend die Positionen & Rotationen der Objekte ändern. Den Mittelpunkt aller Objekte hab ich schon berechnet. Es habert jedoch beim Rotieren... Hab schon mit VectorRotate rumgespielt, jedoch hab ichs nicht hinbekommen...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Mi Jun 30, 2010 17:04 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 20, 2005 13:18
Beiträge: 1054
Wohnort: Dresden
Programmiersprache: C, C++, Pascal, OPL
Möchtest du die Objekte nach dem Rotieren um den Mittelpunkt relativ zu dieser Rotation dann wieder Rotieren? Das ist einfach, du musst nur die Reihenfolge beachten.

Sagen wir mal, du hast 10 Objekte und willst die Objekt 3 bis 7 um den Mittelpunkt dieser 5 Punkte rotieren.

Dann zeichnest du 1 bis 2 und 8 bis 10 wie gehabt, aber bei 3 bis 7 "bewegst" du dich erst an die Mittelpunktposition mit glTranslate, DANN rotierst du um die Rotation, die alle haben sollen. Alles Dinge, die du nun machst sind relativ zu den schon getätigten Operationen.
Du kannst nun also glTranlate aufrufen, wobei du die Positionen der Objekte relativ zu ihrem Mittelpunkt nehmen solltest, und dann am Ende wieder wie gehabt rotieren. In Pseudocode sieht das folgerndermaßen aus:
Code:
//Objekte malen, die "normal" positioniert werden:
for nr in [1,2,8,9,10] do
begin
  glLoadIdentity;
  glTranslatef(object[nr].x,object[nr].y,object[nr].z);
  glRotatef(object[nr].angle,object[nr].vx,object[nr].vy,object[nr].vz);
  object[nr].zeichne;
end;

//Objekte malen, die vorher rotiert werden um den Mittelpunkt:
glLoadIdentity;
glTranslatef(m.x,m.y,m.z); //m ist der Mittelpunkt
glRotatef(rot.angle,rot.vx,rot.vy,rot.vz); //Die Rotation, die du haben wolltest
for nr in [3..7] do
begin
  glPushMatrix;
  glTranslatef(object[nr].x-m.x,object[nr].y-m.y,object[nr].z-m.z);
  glRotatef(object[nr].angle,object[nr].vx,object[nr].vy,object[nr].vz);
  object[nr].zeichne;
  glPopMatrix;
end;


Ich weiß nciht 100% ob das das ist, was du willst, aber am Anfang ist es immer gut sich glTranslate, glRotate usw. als "Greifarm" vorzustellen, der in der Szene umhergreift und Objekte setzt.

LG Ziz

_________________
Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut.
Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’.
Und du schaust mich an und fragst ob ich das kann.
Und ich denk, ich werd' mich ändern irgendwann.

_________________Farin Urlaub - Bewegungslos


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Mi Jun 30, 2010 17:24 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
Nein, die Renderprocedure muss bleiben wie sie ist. Ist muss die Positionen so berechnen. Stell dir das so vor, wie ein Tool zum Einrichten einer Szene. Die Renderprocedure guckt nur die Position & Rotation des Objektes an und führt diese einmalig aus. Ich kann natürlich jedes Objekt einzeln positionieren, jedoch ist das ganz schön nervig. Jedes simple 3D Programm kann mehrere Objekte selektieren und diese dann entsprechend zum Relativen Mittelpunkt rotieren.

Irgendwie müsste das auch aus einer Mischung Sinus/Cosinus (x = xM * r * sin(phi) y= yM * r * cos(phi)) funktionieren. Doch das hab ich auch noch nicht hinbekommen...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Do Jul 01, 2010 07:54 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
eigentlich müsste das doch so funktionieren oder nich:

Basis ist das hier x = XM + R + cos(winkel) | y = YM + R + sin(winkel)

Code:
procedure TMainForm.RotateSelectedX(Angle: Single);
var
  r: Single;
  I: Integer;
begin
setSelCenter;
 //Radius von Relativ
for I := 0 to SelList.Count - 1 do
  begin
   //Relativen Radius von SelectionCenter
   r:= sqrt(Power( SelList[i].position[1] - SelCenter[1],2) +
            Power( SelList[i].position[2] - SelCenter[2],2));
   StatusBar.Panels[1].Text:= FloatToStr(R);
   SelList[i].Position[1] := (selCenter[1] + r) * Cosinus(Angle);
   SelList[i].Position[2] := (selCenter[2] + r) * Sinus(Angle);
  end;
end;


aber wie objekte machen alles, aber drehen sich nicht um den mittelpunkt


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 09:19 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
mh, kann mir noch keiner helfen? Müsste doch irgendwie über Rotationsmatrix funktionieren oder?!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 09:39 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
mh, kann mir noch keiner helfen?

Versuche so genau wie möglich zu formulieren was du wissen möchtest. Ich bin mir nämlich nicht so ganz sicher.

Zitat:
Müsste doch irgendwie über Rotationsmatrix funktionieren oder?!

Mit Matrizen kannst du jede beliebige affine Transformation darstellen.

1. Verschiebe die Objekte so das der Punkt um den du drehen willst, nennen wir ihn (x,y,z) bei (0,0,0) liegt.
2. Rotiere mit der Rotationsmatrix
3. Verschiebe den Mittelpunkt so das (0,0,0) wieder bei (x,y,z) liegt.

Am Ende sieht das dann so aus:
Zitat:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(....);
glRotatef(....);
glTranslatef(....);

rendern(); // deine normale Render-Methode

glPopMatrix();

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 12:55 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
ok ich versuchs nochmal:
Ich habe eine Liste mit Objekten. Alle Objekte haben folgende Infos: Position (xPos, yPos, zPos), Rotation (xRot, yRot, zRot)
Diese Objekte werden dann in der Renderprocdure nacheinander mit glTranslate an die Richtige Position gesetzt und entsprechend Rotiert. Bis dahin alles i.o.
Nun hab ich gewisse möglichkeiten meine Objekte zu plazieren, d.h. die Postion & Rotationswerte zu ändern. Dazu kann ich jedes Objekt einzeln auswählen und die Werte einstellen. Nun möchte ich jedoch auch mehrere Objekte auswählen und verschieben bzw. rotieren. Verschieben stellt hier ja kein Problem da.
Wenn ich nun mehrere Objekte Rotieren will, reicht es ja nicht aus das ich einfach nur Rotation des Objektes ändere, denn dann drehen sich alle Objekte nur entsprechend um sich selbst. Denkbar besser (wie in jedem 3D-Programm wie c4d, 3dmax,etc) wäre es, wenn sich alle Objekte um den Mittelpunkt der ausgewählten Objekte drehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 13:20 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ok, ich halte fest:
Du willst die Berechnung "von Hand" durchführen und die entsprechenden Werte für Position (xPos, yPos, zPos) und Rotation (xRot, yRot, zRot) aktualisieren. Der Benutzer kann dann im Anschluss eine andere Operation wählen und die Werte werden wieder aktualisiert usw.

Also ein kleines Problem ist die von dir gewählte Darstellung der Rotation durch drei Winkel. Die ist nämlich nicht eindeutig und daher kompliziert zu handhaben. Zu allem Überfluss gibt es dann auch noch mehrere Varianten wie du deine drei Winkel dann letztlich anwendest. Die einfachste wäre so etwas wie:
Code:
glRotatef(xRot, 1,0,0);
glRotatef(yRot, 0,1,0);
glRotatef(zRot, 0,0,1);

Aber das ist nur eine von vielen Möglichkeiten. Was benutzt du hier?

Würdest du intern mit Matrizen oder Quaternionen arbeiten wäre die Sache wesentlich einfacher. Der Nachteil ist das du dem Nutzer nicht mehr einfach drei Winkel präsentieren kannst wie es die meisten 3D-Editoren tun.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 13:40 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
glRotatef(xRot, 1,0,0);
glRotatef(yRot, 0,1,0);
glRotatef(zRot, 0,0,1);

genauso siehts aus..
ist das wirklich so kompliziert? Eigentlich ist doch nur die Positionierung der einzelnen Objekte wichtig oder? Die Rotation, muss ich doch dann einfach mit der geänderten Rotation addieren oder? Denn ob ich ein Objekt nun um seine eigene Achse oder von einer entfernten Achse drehe, der winkel bleibt gleich...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 14:38 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Die Rotation, muss ich doch dann einfach mit der geänderten Rotation addieren oder?

Ähm...*smash head on keyboard to continue*......natürlich....habe wieder viel zu kompliziert gedacht.

Ich hab mal gerade Maxima angeworfen und das ausgerechnet:
Code:
/* Translationsmatrix um Punkt (x,y,z) nach (0,0,0) zu verschieben. */
T: matrix(
 [1,0,0,-x],
 [0,1,0,-y],
 [0,0,1,-z],
 [0,0,0,1]
);
/* Rotationsmatrix X-Achse um Winkel a */
A: matrix(
 [1,0,0,0],
 [0,cos(a),-sin(a),0],
 [0,sin(a),cos(a),0],
 [0,0,0,1]
);
/* Rotationsmatrix Y-Achse um Winkel b */
B: matrix(
 [cos(b),0,sin(b),0],
 [0,1,0,0],
 [-sin(b),0,cos(b),0],
 [0,0,0,1]
);
/* Rotationsmatrix Z-Achse um Winkel c */
C: matrix(
 [cos(c),-sin(c),0,0],
 [sin(c),cos(c),0,0],
 [0,0,1,0],
 [0,0,0,1]
);
/* Translationsmatrix um Punkt (0,0,0) nach (x,y,z) zu verschieben. */
S: matrix(
 [1,0,0,x],
 [0,1,0,y],
 [0,0,1,z],
 [0,0,0,1]
);

/* alles mit einander multipliziert */
M: S.C.B.A.T;

/* ergibt: */
M: matrix([cos(b)*cos(c),sin(a)*sin(b)*cos(c)-cos(a)*sin(c),sin(a)*sin(c)+cos(a)*sin(b)*cos(c),cos(c)*(sin(b)*(-cos(a)*z-sin(a)*y)-cos(b)*x)-sin(c)*(sin(a)*z-cos(a)*y)+x],[cos(b)*sin(c),sin(a)*sin(b)*sin(c)+cos(a)*cos(c),cos(a)*sin(b)*sin(c)-sin(a)*cos(c),sin(c)*(sin(b)*(-cos(a)*z-sin(a)*y)-cos(b)*x)+cos(c)*(sin(a)*z-cos(a)*y)+y],[-sin(b),sin(a)*cos(b),cos(a)*cos(b),cos(b)*(-cos(a)*z-sin(a)*y)+z+sin(b)*x],[0,0,0,1]);


Also das ergibt dann, wenn du es ausschreiben willst das hier:
Code:
xPosNeu := (sin(a)*sin(c)+cos(a)*sin(b)*cos(c))*zPos+(sin(a)*sin(b)*cos(c)-cos(a)*sin(c))*yPos+cos(b)*cos(c)*xPos+cos(c)*(sin(b)*(-cos(a)*z-sin(a)*y)-cos(b)*x)-sin(c)*(sin(a)*z-cos(a)*y)+x;
yPosNeu := (cos(a)*sin(b)*sin(c)-sin(a)*cos(c))*zPos+(sin(a)*sin(b)*sin(c)+cos(a)*cos(c))*yPos+cos(b)*sin(c)*xPos+sin(c)*(sin(b)*(-cos(a)*z-sin(a)*y)-cos(b)*x)+cos(c)*(sin(a)*z-cos(a)*y)+y;
zPosNeu := cos(a)*cos(b)*zPos+sin(a)*cos(b)*yPos-sin(b)*xPos+cos(b)*(-cos(a)*z-sin(a)*y)+z+sin(b)*x;


Offensichtlich ist die Matrix/Vektorschreibweise schöner, da schreibst du dann nämlich einfach nur
Code:
vNeu := (S*C*B*A*T) * v;

und die Sache ist gegessen ;) Eine Mathelib für sowas lohnt sich.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 14:59 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Nachtrag: Hier noch die wxMaxima-Datei für die Nachwelt.


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 15:51 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
haut noch nich so ganz hin.. habs so implementiert:
Code:
procedure TMainForm.RotateSelectedY(Angle: Single);
var
  xPosNeu, yPosNeu, zPosNeu: Single;
  a, b, c, x, y, z: Single;
  xPos, yPos, zPos: Single;
  I: Integer;
begin
 SetselCenter;
 for I := 0 to SelList.Count - 1 do
  begin
   //Position nach dem Selektieren des Objektes
   xPos := SelList[i].RelativePosition[0];
   yPos := SelList[i].RelativePosition[1];
   zPos := SelList[i].RelativePosition[2];

   x:= SelCenter[0];
   y:= SelCenter[1];
   z:= SelCenter[2];

   a:= 0;
   b:=angle;
   c:=0;


      xPosNeu := (sinus(a)*sinus(c)+cosinus(a)*sinus(b)*cosinus(c))*zPos+(sinus(a)*sinus(b)*cosinus(c)-cos(a)*sinus(c))*yPos+cosinus(b)*cosinus(c)*xPos+cosinus(c)*(sinus(b)*(-cos(a)*z-sin(a)*y)-cos(b)*x)-sin(c)*(sinus(a)*z-cos(a)*y)+x;
      yPosNeu := (cosinus(a)*sinus(b)*sinus(c)-sin(a)*cosinus(c))*zPos+(sinus(a)*sinus(b)*sinus(c)+cosinus(a)*cosinus(c))*yPos+cosinus(b)*sinus(c)*xPos+sinus(c)*(sinus(b)*(-cos(a)*z-sin(a)*y)-cos(b)*x)+cosinus(c)*(sinus(a)*z-cos(a)*y)+y;
      zPosNeu := cosinus(a)*cosinus(b)*zPos+sinus(a)*cosinus(b)*yPos-sin(b)*xPos+cosinus(b)*(-cos(a)*z-sin(a)*y)+z+sinus(b)*x;
   SelList[i].Position[0] := xPosNeu;
   SelList[i].Position[1] := yPosNeu;
   SelList[i].Position[2] := zPosNeu;
   SelList[i].Rotation[0] := SelList[i].RelativeRotation[0] + round(a);
   SelList[i].Rotation[1] := SelList[i].RelativeRotation[1] + round(b);
   SelList[i].Rotation[2] := SelList[i].RelativeRotation[2] + round(c);
  end;
end;


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 16:11 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
halt! Funktioniert. Lag an Sinus() <> sin().
Mercie für deine Mühe.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Rotieren
BeitragVerfasst: Fr Jul 02, 2010 16:19 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Du hast ja da im Moment noch Winkel auf Null. Wenn es noch Probleme gibt: Es wäre möglich das noch irgendwo die Drehrichtung nicht stimmt. In dem Fall einfach das Vorzeichen des jeweiligen Winkels ändern.

Noch ein Tipp: Nicht ständig immer wieder den Sinus/Cosinus ausrechnen, sondern nur einmal:
Code:
sa := sin(a); ca := cos(a);
sb := sin(b); cb := cos(b);
sc := sin(c); cc := cos(c);

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]