-/* $Id: geartrain.c,v 1.6 2000/04/06 02:22:59 brianp Exp $ */
+/* $Id: geartrain.c,v 1.7 2000/11/30 01:44:24 gareth Exp $ */
/*
* GearTrain Simulator * Version: 1.00
TDA background;
-struct AXLE
+struct AXLE
{
char name[20];
GLint id;
};
-struct GEAR
+struct GEAR
{
char name[20];
char type[7];
};
-struct BELT
+struct BELT
{
char name[20];
GLint id;
char Buf1[256], Buf2[256], Buf3[256], Buf4[256], Buf5[256];
+static GLint T0 = 0;
+static GLint Frames = 0;
-static void
-strset (char buf[], char ch)
+
+static void
+strset (char buf[], char ch)
{
int i;
for (i = 0; i < strlen (buf); i++)
}
-static void
-Clear_Buffers ()
+static void
+Clear_Buffers ()
{
strset (Buf1, 0);
strset (Buf2, 0);
}
-static void
-LoadTriplet (TDA A)
+static void
+LoadTriplet (TDA A)
{
Clear_Buffers ();
fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
}
-static void
-LoadReal (float *a)
+static void
+LoadReal (float *a)
{
Clear_Buffers ();
fscanf (mainfile, "%s %s", Buf1, Buf2);
}
-static void
-LoadInteger (int *a)
+static void
+LoadInteger (int *a)
{
Clear_Buffers ();
fscanf (mainfile, "%s %s", Buf1, Buf2);
}
-static void
-LoadText (char *a)
+static void
+LoadText (char *a)
{
Clear_Buffers ();
fscanf (mainfile, "%s %s", Buf1, Buf2);
}
-static void
-getdata (char filename[])
+static void
+getdata (char filename[])
{
int gear_count = 0, axle_count = 0, belt_count = 0, i;
-
+
mainfile = fopen (filename, "r");
if (!mainfile) {
printf("Error: couldn't open %s\n", filename);
if (!(strcmp (Buf1, "BACKGROUND")))
LoadTriplet (background);
-
+
if (!(strcmp (Buf1, "ANAME")))
{
LoadText (a[axle_count].name);
axle_count++;
}
-
+
if (!(strcmp (Buf1, "ARADIUS")))
LoadReal (&a[axle_count - 1].radius);
-
+
if (!(strcmp (Buf1, "AAXIS")))
LoadInteger (&a[axle_count - 1].axis);
-
+
if (!(strcmp (Buf1, "ACOLOR")))
LoadTriplet (a[axle_count - 1].color);
-
+
if (!(strcmp (Buf1, "APOSITION")))
LoadTriplet (a[axle_count - 1].position);
-
+
if (!(strcmp (Buf1, "ALENGTH")))
LoadReal (&a[axle_count - 1].length);
-
+
if (!(strcmp (Buf1, "AMOTORED")))
LoadInteger (&a[axle_count - 1].motored);
-
+
if (!(strcmp (Buf1, "AANGULARVELOCITY")))
LoadReal (&a[axle_count - 1].angular_velocity);
-
+
if (!(strcmp (Buf1, "ADIRECTION")))
LoadInteger (&a[axle_count - 1].direction);
-
+
if (!(strcmp (Buf1, "GNAME")))
{
LoadText (g[gear_count].name);
gear_count++;
}
-
+
if (!(strcmp (Buf1, "GTYPE")))
LoadText (g[gear_count - 1].type);
-
+
if (!(strcmp (Buf1, "GFACE")))
LoadInteger (&g[gear_count - 1].face);
-
+
if (!(strcmp (Buf1, "GRADIUS")))
LoadReal (&g[gear_count - 1].radius);
-
+
if (!(strcmp (Buf1, "GWIDTH")))
LoadReal (&g[gear_count - 1].width);
-
+
if (!(strcmp (Buf1, "GTEETH")))
LoadInteger (&g[gear_count - 1].teeth);
-
+
if (!(strcmp (Buf1, "GTOOTHDEPTH")))
LoadReal (&g[gear_count - 1].tooth_depth);
-
+
if (!(strcmp (Buf1, "GCOLOR")))
LoadTriplet (g[gear_count - 1].color);
-
+
if (!(strcmp (Buf1, "GAXLE")))
LoadText (g[gear_count - 1].axle_name);
-
+
if (!(strcmp (Buf1, "GPOSITION")))
LoadInteger (&g[gear_count - 1].relative_position);
-
+
if (!(strcmp (Buf1, "BELTNAME")))
{
LoadText (b[belt_count].name);
belt_count++;
}
-
+
if (!(strcmp (Buf1, "GEAR1NAME")))
LoadText (b[belt_count - 1].gear1_name);
-
+
if (!(strcmp (Buf1, "GEAR2NAME")))
LoadText (b[belt_count - 1].gear2_name);
}
-
+
while (Buf1[0] != 0);
-
+
for (i = 0; i < number_of_gears; i++)
{
g[i].axis = -1;
g[i].direction = 0;
g[i].angular_velocity = 0.0;
}
-
+
number_of_gears = gear_count;
number_of_axles = axle_count;
number_of_belts = belt_count;
}
-static void
-axle (GLint j, GLfloat radius, GLfloat length)
+static void
+axle (GLint j, GLfloat radius, GLfloat length)
{
GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
-
- /* draw main cylinder */
+
+ /* draw main cylinder */
glBegin (GL_QUADS);
for (angle = 0.0; angle < 360.0; angle += 5.0)
{
glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
}
glEnd ();
-
- /* draw front face */
+
+ /* draw front face */
glNormal3f (0.0, 0.0, 1.0);
glBegin (GL_TRIANGLES);
for (angle = 0.0; angle < 360.0; angle += 5.0)
glVertex3f (0.0, 0.0, length / 2);
}
glEnd ();
-
- /* draw back face */
+
+ /* draw back face */
glNormal3f (0.0, 0.0, -1.0);
glBegin (GL_TRIANGLES);
for (angle = 0.0; angle <= 360.0; angle += 5.0)
-static void
-gear (GLint j, char type[], GLfloat radius, GLfloat width,
- GLint teeth, GLfloat tooth_depth)
+static void
+gear (GLint j, char type[], GLfloat radius, GLfloat width,
+ GLint teeth, GLfloat tooth_depth)
{
GLint i;
GLfloat r1, r2;
r1 = radius - tooth_depth;
r2 = radius;
-
+
da = 2.0 * M_PI / teeth / 4.0;
if (!g[j].face)
{
n = 1.0;
}
- /* draw front face */
+ /* draw front face */
if (!(strcmp (type, "NORMAL")))
{
glNormal3f (0.0, 0.0, 1.0 * n);
}
glEnd ();
}
-
- /* draw front sides of teeth */
+
+ /* draw front sides of teeth */
if (!(strcmp (type, "NORMAL")))
{
glNormal3f (0.0, 0.0, 1.0 * n);
}
glEnd ();
}
-
+
glNormal3f (0.0, 0.0, -1.0 * n);
-
- /* draw back face */
+
+ /* draw back face */
glBegin (GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++)
{
glVertex3f (0.0, 0.0, -width * fraction);
}
glEnd ();
-
- /* draw back sides of teeth */
+
+ /* draw back sides of teeth */
glNormal3f (0.0, 0.0, -1.0 * n);
glBegin (GL_QUADS);
da = 2.0 * M_PI / teeth / 4.0;
glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
}
glEnd ();
-
-
- /* draw outward faces of teeth */
+
+
+ /* draw outward faces of teeth */
if (!(strcmp (type, "NORMAL")))
{
glBegin (GL_QUAD_STRIP);
for (i = 0; i < teeth; i++)
{
angle = i * 2.0 * M_PI / teeth;
-
+
glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
u = r2 * cos (angle + da) - r1 * cos (angle);
glNormal3f (cos (angle), sin (angle), n);
}
}
-
+
glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction);
glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction);
glEnd ();
}
-static void
-belt (struct GEAR g1, struct GEAR g2)
+static void
+belt (struct GEAR g1, struct GEAR g2)
{
GLfloat D, alpha, phi, angle, incr, width;
GLint indexes[3] =
{
0, 0, 0
};
-
+
GLfloat col[3] =
{
0.0, 0.0, 0.0
};
-
+
width = min (g1.width, g2.width);
D = sqrt (pow (g1.position[0] - g2.position[0], 2) + pow (g1.position[1] - g2.position[1], 2) + pow (g1.position[2] - g2.position[2], 2));
alpha = acos ((g2.position[0] - g1.position[0]) / D);
}
-static int
-axle_find (char axle_name[])
+static int
+axle_find (char axle_name[])
{
int i;
-
+
for (i = 0; i < number_of_axles; i++)
{
if (!(strcmp (axle_name, a[i].name)))
}
-static int
-gear_find (char gear_name[])
+static int
+gear_find (char gear_name[])
{
int i;
-
+
for (i = 0; i < number_of_gears; i++)
{
if (!(strcmp (gear_name, g[i].name)))
}
-static void
-process ()
+static void
+process ()
{
GLfloat x, y, z, D, dist;
GLint axle_index, i, j, g1, g2, k;
char error[80];
-
+
for (i = 0; i < number_of_gears; i++)
{
x = 0.0;
y = 1.0;
else
z = 1.0;
-
+
g[i].position[0] = a[axle_index].position[0] + x * g[i].relative_position;
g[i].position[1] = a[axle_index].position[1] + y * g[i].relative_position;
g[i].position[2] = a[axle_index].position[2] + z * g[i].relative_position;
}
-
+
for (k = 0; k < number_of_axles; k++)
{
for (i = 0; i < number_of_gears - 1; i++)
if (D < 1.1 * (g[i].radius - g[i].tooth_depth + g[j].radius - g[j].tooth_depth))
{
printf (error, "Gear %s and %s are too close to each other.", g[i].name, g[j].name);
-
+
/*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
exit (1);
}
-
+
if (g[i].axis == 0)
{
dist = g[i].position[0] - g[j].position[0];
}
else
dist = g[i].position[2] - g[j].position[2];
-
+
dist = fabs (dist);
-
+
if (dist < (g[i].width / 2 + g[j].width / 2))
{
if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius)))
/*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
exit (1);
}
-
+
g[j].motored = (a[axle_index].motored = 1);
g[j].direction = (a[axle_index].direction = -g[i].direction);
a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
}
-
+
if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius)))
{
axle_index = axle_find (g[i].axle_name);
/*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
exit (1);
}
-
+
g[i].motored = (a[axle_index].motored = 1);
g[i].direction = (a[axle_index].direction = -g[j].direction);
a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
-
+
}
}
}
-
+
if (!(strcmp (g[i].type, g[j].type)) && (!(strcmp (g[i].type, "BEVEL"))) && ((strcmp (g[i].axle_name, g[j].axle_name) != 0)) && (g[i].axis != g[j].axis))
{
D = sqrt (pow (g[i].position[0] - g[j].position[0], 2) + pow (g[i].position[1] - g[j].position[1], 2) + pow (g[i].position[2] - g[j].position[2], 2));
a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
}
-
-
+
+
if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
{
axle_index = axle_find (g[i].axle_name);
}
}
}
-
+
for (i = 0; i < number_of_gears; i++)
{
axle_index = axle_find (g[i].axle_name);
g[i].angular_velocity = a[axle_index].angular_velocity;
}
}
-
+
for (i = 0; i < number_of_belts; i++)
{
g1 = gear_find (b[i].gear1_name);
/*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
exit (1);
}
-
+
if ((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))
{
/*
MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
exit(1);
}
- */
+ */
if (g[g1].axis == 0)
{
dist = g[g1].position[0] - g[g2].position[0];
}
else
dist = g[g1].position[2] - g[g2].position[2];
-
+
dist = fabs (dist);
-
+
if (dist > (g[g1].width / 2 + g[g2].width / 2))
{
printf (error, "Belt %s invalid.", b[i].name);
/*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
exit (1);
}
-
+
if (dist < (g[g1].width / 2 + g[g2].width / 2))
{
if (D < g[g1].radius + g[g2].radius)
/*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
exit (1);
}
-
+
if ((g[g1].motored) && (!(g[g2].motored)))
{
axle_index = axle_find (g[g2].axle_name);
g[g2].direction = (a[axle_index].direction = g[g1].direction);
g[g2].angular_velocity = (a[axle_index].angular_velocity = g[g1].angular_velocity * g[g1].radius / g[g2].radius);
}
-
+
if ((!(g[g1].motored)) && (g[g2].motored))
{
axle_index = axle_find (g[g1].axle_name);
}
}
}
-
+
for (i = 0; i < number_of_gears; i++)
{
axle_index = axle_find (g[i].axle_name);
GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
-static void
-draw (void)
+static void
+draw (void)
{
int i;
GLfloat x, y, z;
int index;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
+
glPushMatrix ();
glRotatef (view_rotx, 1.0, 0.0, 0.0);
glRotatef (view_roty, 0.0, 1.0, 0.0);
glRotatef (view_rotz, 0.0, 0.0, 1.0);
-
+
for (i = 0; i < number_of_gears; i++)
{
x = 0.0;
x = 1.0;
else
z = 1.0;
-
+
if (z != 1.0)
glRotatef (90.0, x, y, z);
-
+
glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0);
glCallList (g[i].id);
glPopMatrix ();
}
-
+
for (i = 0; i < number_of_axles; i++)
{
x = 0.0;
if (z != 1.0)
glRotatef (90.0, x, y, z);
-
+
glCallList (a[i].id);
glPopMatrix ();
}
-
+
for (i = 0; i < number_of_belts; i++)
{
x = 0.0;
x = 1.0;
else
z = 1.0;
-
+
if (z != 1.0)
glRotatef (90.0, x, y, z);
-
+
glCallList (b[i].id);
glPopMatrix ();
}
-
+
glPopMatrix ();
glutSwapBuffers ();
+
+ {
+ GLint t = glutGet(GLUT_ELAPSED_TIME);
+ Frames++;
+ if (t - T0 >= 5000) {
+ GLfloat seconds = (t - T0) / 1000.0;
+ GLfloat fps = Frames / seconds;
+ printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
+ T0 = t;
+ Frames = 0;
+ }
+ }
}
-static void
-idle (void)
+static void
+idle (void)
{
int i;
for (i = 0; i < number_of_gears; i++)
-/* change view angle, exit upon ESC */
-static void
-key (unsigned char k, int x, int y)
+/* change view angle, exit upon ESC */
+static void
+key (unsigned char k, int x, int y)
{
switch (k)
{
-/* new window size or exposure */
-static void
-reshape (int width, int height)
+/* new window size or exposure */
+static void
+reshape (int width, int height)
{
glViewport (0, 0, (GLint) width, (GLint) height);
glMatrixMode (GL_PROJECTION);
GLfloat h = (GLfloat) height / (GLfloat) width;
glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
}
-
+
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTranslatef (0.0, 0.0, -40.0);
-static void
-init (void)
+static void
+init (void)
{
GLfloat matShine = 20.00F;
GLfloat light0Pos[4] =
0.70F, 0.70F, 1.25F, 0.50F
};
int i;
-
+
glClearColor (background[0], background[1], background[2], 1.0F);
glClearIndex ((GLfloat) 0.0);
-
+
glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine);
glLightfv (GL_LIGHT0, GL_POSITION, light0Pos);
glEnable (GL_LIGHT0);
-
+
glEnable (GL_LIGHTING);
glEnable (GL_DEPTH_TEST);
for (i = 0; i < number_of_gears; i++)
g[i].angle = 0.0;
-
+
for (i = 0; i < number_of_gears; i++)
{
g[i].id = glGenLists (1);
gear (i, g[i].type, g[i].radius, g[i].width, g[i].teeth, g[i].tooth_depth);
glEndList ();
}
-
+
for (i = 0; i < number_of_axles; i++)
{
a[i].id = glGenLists (1);
axle (i, a[i].radius, a[i].length);
glEndList ();
}
-
+
for (i = 0; i < number_of_belts; i++)
{
b[i].id = glGenLists (1);
belt (g[gear_find (b[i].gear1_name)], g[gear_find (b[i].gear2_name)]);
glEndList ();
}
-
+
glEnable (GL_COLOR_MATERIAL);
}
-int
-main (int argc, char *argv[])
+int
+main (int argc, char *argv[])
{
char *file;
glutInitWindowPosition (0, 0);
glutInitWindowSize(640,480);
glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
-
+
if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
exit (1);
getdata (file);
process ();
init ();
-
+
glutDisplayFunc (draw);
glutReshapeFunc (reshape);
glutKeyboardFunc (key);
glutMainLoop ();
return 0;
}
-