Objekt auf Kreisbahn bewegen

Dörti.Hermi

Erfahrenes Mitglied
Hallo zusammen!

Folgenes: Ich habs jetzt schon 2 Stunden probiert, aber bin noch immer nicht draufgekommen wie's funktioniert. Und zwar will ich ein Objekt (in meinem Fall ein zufällig generiertes Dreieck) nach dem Tastendruck [k] von der aktuellen Position beim Tastendruck auf einer Kreisbahn bewegen lassen. Drehrichtung ist egal. Ich weiß, dass ich da irgendwas mit sin und cos machen muss, aber irgendwie bewegt sich das Objekt auf einer Geraden.

Hier mal mein Code (Auszug):

Code:
#include <iostream>
#include <GL/glut.h>
#include <time.h>
#include <math.h>

float coords[3][2], rgb[3];
const int MILLISEC_PRO_FRAME = 20;
static float dx, dy;
static bool animation_laeuft = true;
static bool circle = false;

int i,j;

static void timer_func (int value)
{
	if(circle)
	{
		dx = 3*cos(0.01);
		dy = 3*sin(0.01);
	}

    for(j=0; j<3; j++)
	{
		coords[j][0] += dx;
		coords[j][1] += dy;
	}
    glutPostRedisplay ();	
}

static void display_func (void)
{
	if (animation_laeuft)		
		glutTimerFunc (MILLISEC_PRO_FRAME, timer_func, 0);

	glClear(GL_COLOR_BUFFER_BIT);
	glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 
	glBegin (GL_POLYGON);
	glColor3f(rgb[0],rgb[1],rgb[2]);
	for(i=0; i<3; i++)
	{
		glVertex3f (coords[i][0], coords[i][1],0);
	}
	glEnd ();
	glutSwapBuffers( );
}

static void keyboard_func (unsigned char key, int x, int y)
{
    switch (key)
    {
        case ' ':
            animation_laeuft = !animation_laeuft;
            glutPostRedisplay ();
            break;

        case '+':
			dx *= 1.2;
			dy *= 1.2;
			break;

		case '-':
			dx /= 1.2;
			dy /= 1.2;
			break;

		case 'k':
			circle = !circle;
			glutPostRedisplay;
			break;

		case 'Q':
        case 'q':
            exit (0);
			break;
    }
}

Es geht um die Berechnung in der "timer_func". Die Zahlenwerte sind hierbei nur beliebig gewält, weil ich nicht wusste, welche ich brauche.

Kann mir jemand weiterhelfen?

Lg Andi
 
Hm...
du köntest doch was mit dem Satz des Thales machen:
Code:
///Koordinaten beuiehen sich auf den Mittelpunkt des Kreises.
r=Radius
c=Zähler
kx, ky=koordinaten des Dreiecks
////////
kx = 15
ky = 0
r= 10
for(c=0; c+=1; kx==r)
{
kx = (c*c+r*r)^1/2//die wurzel aus c^2+r^2
//Runden wäre ganz gut!
r -= 1
ky = 15 - kx 
//Dreieck zeichnen und vlt ein sleep()
}
//dass wäre dann das erste Viertel.
Du bräuchtest dann ja noch Weiter 4 For schleifen, aber di kanst du ja bestimmt selber anpassen :P
Skini
 
Danke für deine schnelle Antwort, aber ich da da überhaupt gar nix ^^

Des Satz des Thales versteh ich auch irgendwie nicht...

Gibts da noch eine andere Lösung?
 
Hallo, ich hoffe das Thema ist noch aktuell.

Wenn du etwas drehen möchtest, musst du erstmal festlegen, um welchen Punkt.
Zum Beispiel um den Schwerpunkt des Dreiecks:
Code:
float xs = (x[0]+x[1]+x[2])/3.0;
float ys = (y[0]+y[1]+y[2])/3.0;
Für die Drehung kann ich empfehlen, die Dreiecks-Eckpunkte in Polarkoordinarten umzuwandeln, den Winkel um ein Delta zu erhöhen und wieder in kartesiche zurückzuwandeln.
Code:
#include <cmath>
...
float r[3], phi[3];

for (int i = 0; i < 3; i++) {
  // zunächst mal den Radius berechnen nach dem guten alten Pythagoras
  r[i] = sqrt((x[i]-xs)*(x[i]-xs) + (y[i]-ys)*(y[i]-ys));   // Radius für Eckpunkt i

  // dann den Winkel in Radiant mit Arcus-Kosinus
  phi[i] = acos((x[i]-xs)/r[i]);    // Achtung: Es wird angenommen, r[i] ist ungleich 0 !

  // Die acos-Funktion liefert nur Winkel bis max. 180 Grad
  // Anhand y[i] können "noch wärmere Winkel" bis 360 Grad bestimmt werden.:)
  if ((y[i]-ys) < 0) phi[i] = 2.0*3.1415927 - phi[i];

  // so weit, so gut. Nun kommt die Drehung.
  phi[i] += delta_phi;

  // und wieder zurückwandeln
  x[i] = xs + r[i] * cos(phi[i]);
  y[i] = ys + r[i] * sin(phi[i]);
}
Der Sonderfall r[i] == 0.0 müsste noch behandelt werden. Ich hoffe, oben stehender Code ist fehlerfrei, habe ihn aus dem Gedächtnis heraus gechrieben und nicht getestet.
 
Zuletzt bearbeitet:
Zurück