Rotation quirks, etc... need help kinda quick

Well, I’m working a homework for my OpenGL programming class, and I’m having some trouble. I’m trying to make an amusement park ride of sort, where there’s a central hub and support arms that rotate around the hub, and move up and down over time (you know the ones, for kids, with the little seats on them… whatever).

Anyway, the problem is that when I try to place the supports around the hub, that doesn’t work quite right. And when I try to angle them up and down, it doesn’t work correctly… so basically, nothing works right in the support arm department.

Here’s the piece of code in question, and for those really looking to help, here’s all of the code… http://www.doublearon.com/opengl/hw2

if (counter >= 360)
	counter = 0;
counter++;

// Rotate entire coordinate system
glPushMatrix();
	glRotatef(counter,0,1,0);
	
	// Build central hub
	glPushMatrix();
		glRotatef(90,1,0,0);
		glColor3fv(&hub_color[0]);
		glutSolidTorus(hub_inner_radius, hub_outer_radius, 20, 20);
	glPopMatrix();

	// Build support arms around and hub and rotate them
	for(int i=0; i< num_cars; i++)
	{
		glPushMatrix();
			glTranslatef(0, 0, -hub_radius);
			glRotatef(-support_ang[i], 1, 0, 0);
			glTranslatef(0, 0, hub_radius);
										
			glTranslatef(sin(i*support_arc)*support_radius, 0, cos(i*support_arc)*support_radius);
			glColor3fv(&support_color[0]);
			gluCylinder(supports, hub_radius * 0.1, hub_radius * 0.1, 2 * hub_radius, 20, 20);
		glPopMatrix();

		move_system();
	}

glPopMatrix();

Thanks a lot everyone. I really hope you can help. :slight_smile:

exactly what is not working correctly, what happens when you run that code?

Well, when I run the code using 1 support, I get the support to rotate around the hub and angle up, but it also seems to translate in the Y-axis at the same time, which makes no sense to me. That, and when I add a 2nd support, things go all to heck. They never seem to get spaced evenly around the hub, and when they rotate, they never seem to do the same thing.

First I like to work from the center out and maybe you are looking at the solution the hard way.

Instead of rotating the world, let’s just rotate the ride. Note example code…

// build ride
glPushMatrix()
glTranslatef(…) // movie it
glRotatef(axis, 0,0,1); //rotate it’s center
draw_center_piece();
// build a arms
for(a_b = 0, a_b < 4, a_b++) // 4 gives us four arms.
{
glPushMatrix()
glRotate((360/4) * a_b,0,0,1) // draws each
arm at 90’s apart.
draw_arm()
//Draw ride buckets
for(r_b=0; r_b < 4, r_b++)
{
glPushMatrix()
glRotatef((360/4) * r_b, 0,0,1) // draws each bucket at 90’s apart.
Draw_buckets();
glPopMatrix();
}
}
glPopMatrix();

Note I am sure there maybe an error… but I hope it gives you an idea…
Later I will try put down the excact code.

Originally posted by Doublearon:
[b]Well, I’m working a homework for my OpenGL programming class, and I’m having some trouble. I’m trying to make an amusement park ride of sort, where there’s a central hub and support arms that rotate around the hub, and move up and down over time (you know the ones, for kids, with the little seats on them… whatever).

Anyway, the problem is that when I try to place the supports around the hub, that doesn’t work quite right. And when I try to angle them up and down, it doesn’t work correctly… so basically, nothing works right in the support arm department.

Here’s the piece of code in question, and for those really looking to help, here’s all of the code… http://www.doublearon.com/opengl/hw2

if (counter >= 360)
counter = 0;
counter++;

// Rotate entire coordinate system
glPushMatrix();
glRotatef(counter,0,1,0);

  // Build central hub
  glPushMatrix();
  	glRotatef(90,1,0,0);
  	glColor3fv(&hub_color[0]);
  	glutSolidTorus(hub_inner_radius, hub_outer_radius, 20, 20);
  glPopMatrix();
  // Build support arms around and hub and rotate them
  for(int i=0; i&lt; num_cars; i++)
  {
  	glPushMatrix();
  		glTranslatef(0, 0, -hub_radius);
  		glRotatef(-support_ang[i], 1, 0, 0);
  		glTranslatef(0, 0, hub_radius);
  									
  		glTranslatef(sin(i*support_arc)*support_radius, 0, cos(i*support_arc)*support_radius);
  		glColor3fv(&support_color[0]);
  		gluCylinder(supports, hub_radius * 0.1, hub_radius * 0.1, 2 * hub_radius, 20, 20);
  	glPopMatrix();
  	move_system();
  }

glPopMatrix();

Thanks a lot everyone. I really hope you can help. :-)[/b]

I have throw together a simple example of a amusment ride, per your example code.
Currently is has only a veiw from the top, with a little change by adding a rotate command before the routine will move the view. This was based around another piece of code that I had writen.

Note to do this I do not have to use cos/sin, just the glRotate/gltranslate commands.

// ride.c
// By Eric Stringer 2002
// A openGL example program, displays a wire cube
// with a simulation of a amusment ride.
// Keyboard inputs: [ESC] = quit
// ‘C’ = start/stop cylinder rotation, also tages for movement with arrow keys
// ‘E’ = opens and closes cylinder ends
// ‘L’ = enables/disables lighting
// ‘V’ = toggle ortho/prespective view

#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// define glu objects

GLUquadricObj *Cylinder;
GLUquadricObj *Disk;

GLfloat wire_cube, solid_cube, solid_cone; // store objects current rotation
static GLfloat solid_cube_x = -3.0, solid_cube_y = 0.0;
static GLfloat solid_cone_x = 3.0, solid_cone_y = -1.0;
static int wire_cube_rotate = 1, solid_cube_rotate = 1, solid_cone_rotate = 1; // store state; 0= no rotation, 1 = rotation
static GLfloat move_x = 0 , move_y = 0;
static int object_move = 0;

// lighting
GLfloat LightAmbient= { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightDiffuse= { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightPosition= { 5.0f, 25.0f, 15.0f, 1.0f };
GLfloat mat_specular = { 1.0, 1.0, 1.0, 1.0 };
static int light_state = 1; // light on = 1, light off = 0
static int cylinder_state = 1; // ends on cylinder = 1, hollow cylinder = 0
static int view_state = 1; // Ortho view = 1, Perspective = 0

void Sprint( int x, int y, char *st)
{
int l,i;

l=strlen( st );
glRasterPos2i( x, y);
for( i=0; i < l; i++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]);
}

}

static void TimeEvent(int te)
{
int timent;
int i;

if ( object_move == 1)
{
solid_cube_x = move_x;
solid_cube_y = move_y;
}

if ( object_move == 2)
{
solid_cone_x = move_x;
solid_cone_y = move_y;
}

glutPostRedisplay();
glutTimerFunc( 100, TimeEvent, 1);
}

void init(void)
{

glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
// Lighting is added to scene
glLightfv(GL_LIGHT1 ,GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1 ,GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1 ,GL_POSITION, LightPosition);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);

Cylinder = gluNewQuadric();
gluQuadricDrawStyle( Cylinder, GLU_FILL);
gluQuadricNormals( Cylinder, GLU_SMOOTH);
gluQuadricOrientation( Cylinder, GLU_OUTSIDE);
gluQuadricTexture( Cylinder, GL_TRUE);

Disk = gluNewQuadric();
gluQuadricDrawStyle( Disk, GLU_FILL);
gluQuadricNormals( Disk, GLU_SMOOTH);
gluQuadricOrientation( Disk, GLU_OUTSIDE);
gluQuadricTexture( Disk, GL_TRUE);

}

void display(void)
{
int arms , buckets;

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// easy way to put text on the screen.
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glOrtho(-8.0, 8.0, 8.0, -8.0, -1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Put view state on screen
glColor3f( 1.0, 1.0, 1.0);
if (view_state == 0)
{
Sprint(-3, 4, “Perspective view”);
}else Sprint(-2, 4, “Ortho view”);

// Turn Perspective mode on/off
if (view_state == 0)
{
glMatrixMode (GL_PROJECTION);
glLoadIdentity();

 gluPerspective(60.0, 1, 1.0, 30.0);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 }

if (light_state == 1)
{
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL); // Enable for lighing
}else
{
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL); // Disable for no lighing
}

glPushMatrix(); // Draw center base of ride
glColor3f(1.0, 0.2, 1.0);
glTranslatef( solid_cone_x, solid_cone_y, -20.0);
if (solid_cone_rotate == 1) solid_cone++;
if (solid_cone > 360) solid_cone = 0;
glRotatef(solid_cone, 0.0, 0.0, 1.0);
gluCylinder(Cylinder, 1, 1, 2, 16, 16);
if (cylinder_state == 1)
{
gluDisk(Disk, 0, 1, 16, 2); // Bottom end cap of cylinder
glTranslatef(0.0, 0.0, 2.0);// top end cap of cylinder
gluDisk(Disk, 0, 1, 16, 2);
}
for(arms = 0; arms < 4; arms++)
{
glPushMatrix();// Draw next arm axis.
glColor3f(0.0, 1.0, 1.0); // give it a color
glRotatef( (360/4) * arms, 0.0, 0.0, 1.0);
glTranslatef( 6.0, 0.0, 0.0);
if (solid_cube_rotate == 1) solid_cube++;
if (solid_cube > 360) solid_cube = 0; // check for rotation pass 360, and reset if above.
glRotatef(360 - solid_cube, 0.0, 0.0, 1.0); // rotate on z-axis

  glutSolidCube(2.0);

for(buckets = 0; buckets < 4; buckets++)
   {
  	glPushMatrix(); // draw cube to repersent ride buckets.
		glRotatef( (360/4) * buckets, 0.0, 0.0, 1.0);
  	glTranslatef(3.0, 0.0, 0.0);
      glutSolidCube(1.0);
      glPopMatrix();
   }
  glPopMatrix();
}

glPopMatrix();

glPushMatrix(); // Draw large wire cube
glColor3f(1.0, 1.0, 1.0);
glTranslatef( 0.0, 0.0, -20.0);
glutWireCube(13.0);
glPopMatrix();

glutSwapBuffers();
}

void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
}

void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case ‘S’:
solid_cube_rotate = abs( solid_cube_rotate - 1); // Toggle rotate on off.
object_move = 1;
move_x = solid_cube_x;
move_y = solid_cube_y;
break;
case ‘C’:
solid_cone_rotate = abs( solid_cone_rotate - 1); // Toggle rotate on off.
object_move = 2;
move_x = solid_cone_x;
move_y = solid_cone_y;
break;
case ‘L’:
light_state = abs(light_state - 1);
break;
case ‘E’:
cylinder_state = abs(cylinder_state - 1);
break;
case ‘V’:
view_state = abs(view_state - 1);
break;
case 27:
exit(0); // exit program when [ESC] key presseed
break;
default:
break;
}

}

void Special_keys(unsigned char key, int x, int y)
{
switch (key) {
case GLUT_KEY_DOWN:
move_y++;
break;
case GLUT_KEY_UP:
move_y–;
break;
case GLUT_KEY_RIGHT:
move_x++;
break;
case GLUT_KEY_LEFT:
move_x–;
break;
default:
break;
}

}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (10, 10);
glutCreateWindow (argv[0]);
glutSetWindowTitle(“Wirecube”);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutSpecialFunc(Special_keys);
glutTimerFunc( 10, TimeEvent, 1);
glutMainLoop();
return 0;
}

[This message has been edited by nexusone (edited 10-02-2002).]

Thanks a lot! I really appreciate the guidance.