| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066 | 
							- /* $Id: geartrain.c,v 1.7 2000/11/30 01:44:24 gareth Exp $ */
 - 
 - /*
 -  * GearTrain Simulator * Version:  1.00
 -  *
 -  * Copyright (C) 1999  Shobhan Kumar Dutta  All Rights Reserved.
 -  * <skdutta@del3.vsnl.net.in>
 -  *
 -  * Permission is hereby granted, free of charge, to any person obtaining a
 -  * copy of this software and associated documentation files (the "Software"),
 -  * to deal in the Software without restriction, including without limitation
 -  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 -  * and/or sell copies of the Software, and to permit persons to whom the
 -  * Software is furnished to do so, subject to the following conditions:
 -  *
 -  * The above copyright notice and this permission notice shall be included
 -  * in all copies or substantial portions of the Software.
 -  *
 -  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 -  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 -  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 -  * SHOBHAN KUMAR DUTTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 -  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
 -  * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 -  * SOFTWARE.
 -  */
 - 
 - 
 - #include <math.h>
 - #include <stdlib.h>
 - #include <GL/glut.h>
 - #include <string.h>
 - #include <stdio.h>
 - 
 - #define min(x, y) ( x < y ? x : y )
 - 
 - #ifndef M_PI
 - #define M_PI 3.14159265
 - #endif	/*  */
 - typedef GLfloat TDA[4];
 - 
 - TDA background;
 - 
 - 
 - struct AXLE
 -   {
 -     char name[20];
 -       GLint id;
 -       GLfloat radius;
 -       GLint axis;
 -       TDA color;
 -       TDA position;
 -       GLfloat length;
 -       GLint motored;
 -       GLfloat angular_velocity;
 -       GLint direction;
 -   };
 - 
 - 
 - struct GEAR
 -   {
 -     char name[20];
 -     char type[7];
 -       GLint face;
 -       GLint id;
 -       GLfloat radius;
 -       GLfloat width;
 -       GLint teeth;
 -       GLfloat tooth_depth;
 -       GLfloat angle;
 -       GLfloat angular_velocity;
 -       TDA color;
 -       GLint relative_position;
 -       TDA position;
 -     char axle_name[20];
 -       GLint axis;
 -       GLint direction;
 -       GLint motored;
 -   };
 - 
 - 
 - struct BELT
 -   {
 -     char name[20];
 -       GLint id;
 -     char gear1_name[20];
 -     char gear2_name[20];
 -   };
 - 
 - 
 - FILE * mainfile;
 - struct GEAR g[10];
 - struct AXLE a[10];
 - struct BELT b[10];
 - int number_of_gears;
 - int number_of_axles;
 - int number_of_belts;
 - 
 - 
 - 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)
 - {
 -     int i;
 -     for (i = 0; i < strlen (buf); i++)
 -       buf[i] = ch;
 - }
 - 
 - 
 - static void
 - Clear_Buffers ()
 - {
 -     strset (Buf1, 0);
 -     strset (Buf2, 0);
 -     strset (Buf3, 0);
 -     strset (Buf4, 0);
 -     strset (Buf5, 0);
 - }
 - 
 - 
 - static void
 - LoadTriplet (TDA A)
 - {
 -     Clear_Buffers ();
 -     fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
 -     A[0] = atof (Buf2);
 -     A[1] = atof (Buf3);
 -     A[2] = atof (Buf4);
 - }
 - 
 - 
 - static void
 - LoadReal (float *a)
 - {
 -     Clear_Buffers ();
 -     fscanf (mainfile, "%s %s", Buf1, Buf2);
 -     *a = atof (Buf2);
 - }
 - 
 - 
 - static void
 - LoadInteger (int *a)
 - {
 -     Clear_Buffers ();
 -     fscanf (mainfile, "%s %s", Buf1, Buf2);
 -     *a = atoi (Buf2);
 - }
 - 
 - 
 - static void
 - LoadText (char *a)
 - {
 -     Clear_Buffers ();
 -     fscanf (mainfile, "%s %s", Buf1, Buf2);
 -     strcpy (a, Buf2);
 - }
 - 
 - 
 - 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);
 -        exit(-1);
 -     }
 - 
 -     do
 -     {
 - 	Clear_Buffers ();
 - 	fscanf (mainfile, "%s", Buf1);
 - 	if (ferror (mainfile))
 - 	{
 - 	    printf ("\nError opening file !\n");
 - 	    exit (1);
 - 	}
 - 
 - 	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;
 -     fclose (mainfile);
 - }
 - 
 - 
 - static void
 - axle (GLint j, GLfloat radius, GLfloat length)
 - {
 -     GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
 - 
 -     /* draw main cylinder */
 -     glBegin (GL_QUADS);
 -     for (angle = 0.0; angle < 360.0; angle += 5.0)
 -     {
 - 	rad = angle * M_PI / 180.0;
 - 	glNormal3f (cos (rad), sin (rad), 0.0);
 - 	glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
 - 	glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
 - 	glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
 - 	glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
 -     }
 -     glEnd ();
 - 
 -     /* draw front face */
 -     glNormal3f (0.0, 0.0, 1.0);
 -     glBegin (GL_TRIANGLES);
 -     for (angle = 0.0; angle < 360.0; angle += 5.0)
 -     {
 - 	rad = angle * M_PI / 180.0;
 - 	glVertex3f (0.0, 0.0, length / 2);
 -       	glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
 - 	glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
 - 	glVertex3f (0.0, 0.0, length / 2);
 -     }
 -     glEnd ();
 - 
 -     /* draw back face */
 -     glNormal3f (0.0, 0.0, -1.0);
 -     glBegin (GL_TRIANGLES);
 -     for (angle = 0.0; angle <= 360.0; angle += 5.0)
 -     {
 - 	rad = angle * M_PI / 180.0;
 - 	glVertex3f (0.0, 0.0, -length / 2);
 - 	glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
 - 	glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
 - 	glVertex3f (0.0, 0.0, -length / 2);
 -     }
 -     glEnd ();
 - }
 - 
 - 
 - 
 - static void
 - gear (GLint j, char type[], GLfloat radius, GLfloat width,
 -       GLint teeth, GLfloat tooth_depth)
 - {
 -     GLint i;
 -     GLfloat r1, r2;
 -     GLfloat angle, da;
 -     GLfloat u, v, len, fraction = 0.5;
 -     GLfloat n = 1.0;
 - 
 -     r1 = radius - tooth_depth;
 -     r2 = radius;
 - 
 -     da = 2.0 * M_PI / teeth / 4.0;
 -     if (!g[j].face)
 -     {
 - 	fraction = -0.5;
 - 	n = -1.0;
 -     }
 -     if (!(strcmp (type, "NORMAL")))
 -     {
 - 	fraction = 0.5;
 - 	n = 1.0;
 -     }
 - 
 -     /* draw front face */
 -     if (!(strcmp (type, "NORMAL")))
 -     {
 - 	glNormal3f (0.0, 0.0, 1.0 * n);
 - 	glBegin (GL_QUAD_STRIP);
 - 	for (i = 0; i <= teeth; i++)
 - 	{
 - 	    angle = i * 2.0 * M_PI / teeth;
 - 	    glVertex3f (0.0, 0.0, width * fraction);
 - 	    glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
 - 	    glVertex3f (0.0, 0.0, width * fraction);
 - 	    glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
 - 	}
 - 	glEnd ();
 -     }
 -     else
 -     {
 - 	glNormal3f (0.0, 0.0, 1.0 * n);
 - 	glBegin (GL_QUAD_STRIP);
 - 	for (i = 0; i <= teeth; i++)
 - 	{
 - 	    angle = i * 2.0 * M_PI / teeth;
 - 	    glVertex3f (0.0, 0.0, width * fraction);
 - 	    glVertex3f ((r2 - width) * cos (angle), (r2 - width) * sin (angle), width * fraction);
 - 	    glVertex3f (0.0, 0.0, width * fraction);
 - 	    glVertex3f ((r2 - width) * cos (angle + 3 * da), (r2 - width) * sin (angle + 3 * da), width * fraction);
 - 	}
 - 	glEnd ();
 -     }
 - 
 -     /* draw front sides of teeth */
 -     if (!(strcmp (type, "NORMAL")))
 -     {
 - 	glNormal3f (0.0, 0.0, 1.0 * n);
 - 	glBegin (GL_QUADS);
 - 	da = 2.0 * M_PI / teeth / 4.0;
 - 	for (i = 0; i < teeth; i++)
 - 	{
 - 	    angle = i * 2.0 * M_PI / teeth;
 - 	    glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
 - 	    glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
 - 	    glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
 - 	    glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
 - 	}
 - 	glEnd ();
 -     }
 - 
 -     glNormal3f (0.0, 0.0, -1.0 * n);
 - 
 -     /* draw back face */
 -     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 (0.0, 0.0, -width * fraction);
 - 	glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
 - 	glVertex3f (0.0, 0.0, -width * fraction);
 -     }
 -     glEnd ();
 - 
 -     /* draw back sides of teeth */
 -     glNormal3f (0.0, 0.0, -1.0 * n);
 -     glBegin (GL_QUADS);
 -     da = 2.0 * M_PI / teeth / 4.0;
 -     for (i = 0; i < teeth; i++)
 -     {
 - 	angle = i * 2.0 * M_PI / teeth;
 - 	glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
 - 	glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
 - 	glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
 - 	glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
 -     }
 -     glEnd ();
 - 
 - 
 -     /* 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);
 - 	    v = r2 * sin (angle + da) - r1 * sin (angle);
 - 	    len = sqrt (u * u + v * v);
 - 	    u /= len;
 - 	    v /= len;
 - 	    glNormal3f (v, -u, 0.0);
 - 	    glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
 - 	    glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
 - 	    glNormal3f (cos (angle), sin (angle), 0.0);
 - 	    glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
 - 	    glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
 - 	    u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
 - 	    v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
 - 	    glNormal3f (v, -u, 0.0);
 - 	    glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
 - 	    glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
 - 	    glNormal3f (cos (angle), sin (angle), 0.0);
 - 	}
 -     }
 -     else
 -     {
 - 	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);
 - 	    v = r2 * sin (angle + da) - r1 * sin (angle);
 - 	    len = sqrt (u * u + v * v);
 - 	    u /= len;
 - 	    v /= len;
 - 	    glNormal3f (v, -u, 0.0);
 - 	    glVertex3f ((r2 - width) * cos (angle + da), (r2 - width) * sin (angle + da), width * fraction);
 - 	    glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
 - 	    glNormal3f (cos (angle), sin (angle), n);
 - 	    glVertex3f ((r2 - width) * cos (angle + 2 * da), (r2 - width) * sin (angle + 2 * da), width * fraction);
 - 	    glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
 - 	    u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
 - 	    v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
 - 	    glNormal3f (v, -u, 0.0);
 - 	    glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
 - 	    glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
 - 	    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)
 - {
 -     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);
 -     phi = acos ((g1.radius - g2.radius) / D);
 -     glBegin (GL_QUADS);
 -     glColor3fv (col);
 -     glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
 -     incr = 1.2 * 360.0 / g1.teeth * M_PI / 180.00;
 -     for (angle = alpha + phi; angle <= 2 * M_PI - phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.00)
 -     {
 - 	glNormal3f (cos (angle), sin (angle), 0.0);
 - 	glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), width * 0.5);
 - 	glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), -width * 0.5);
 - 	glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), -width * 0.5);
 - 	glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), width * 0.5);
 -     }
 -     glEnd ();
 -     glBegin (GL_QUADS);
 -     glColor3fv (col);
 -     glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
 -     incr = 1.2 * 360.0 / g2.teeth * M_PI / 180.00;
 -     for (angle = -phi + alpha; angle <= phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.0)
 -     {
 - 	glNormal3f (cos (angle), sin (angle), 0.0);
 - 	glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * 0.5);
 - 	glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * -0.5);
 - 	glVertex3f (g2.radius * cos (angle + incr) + g2.position[0] - g1.position[0], g2.radius * sin (angle + incr) + g2.position[1] - g1.position[1], width * -0.5);
 - 	glVertex3f (g2.radius * cos (angle + incr) + g2.position[0] - g1.position[0], g2.radius * sin (angle + incr) + g2.position[1] - g1.position[1], width * 0.5);
 -     }
 -     glEnd ();
 - 
 -     glBegin (GL_QUADS);
 -     glColor3fv (col);
 -     glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
 -     glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * 0.5);
 -     glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * -0.5);
 -     glVertex3f (g2.radius * cos (alpha + phi) + g2.position[0] - g1.position[0], g2.radius * sin (alpha + phi) + g2.position[1] - g1.position[1], width * -0.5);
 -     glVertex3f (g2.radius * cos (alpha + phi) + g2.position[0] - g1.position[0], g2.radius * sin (alpha + phi) + g2.position[1] - g1.position[1], width * 0.5);
 -     glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * 0.5);
 -     glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * -0.5);
 -     glVertex3f (g2.radius * cos (alpha - phi) + g2.position[0] - g1.position[0], g2.radius * sin (alpha - phi) + g2.position[1] - g1.position[1], width * -0.5);
 -     glVertex3f (g2.radius * cos (alpha - phi) + g2.position[0] - g1.position[0], g2.radius * sin (alpha - phi) + g2.position[1] - g1.position[1], width * 0.5);
 -     glEnd ();
 - }
 - 
 - 
 - static int
 - axle_find (char axle_name[])
 - {
 -     int i;
 - 
 -     for (i = 0; i < number_of_axles; i++)
 -     {
 - 	if (!(strcmp (axle_name, a[i].name)))
 -            break;
 -     }
 -     return i;
 - }
 - 
 - 
 - static int
 - gear_find (char gear_name[])
 - {
 -     int i;
 - 
 -     for (i = 0; i < number_of_gears; i++)
 -     {
 - 	if (!(strcmp (gear_name, g[i].name)))
 -            break;
 -     }
 -     return i;
 - }
 - 
 - 
 - 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 = 0.0;
 - 	z = 0.0;
 - 	axle_index = axle_find (g[i].axle_name);
 - 	g[i].axis = a[axle_index].axis;
 - 	g[i].motored = a[axle_index].motored;
 - 	if (a[axle_index].motored)
 - 	{
 - 	    g[i].direction = a[axle_index].direction;
 - 	    g[i].angular_velocity = a[axle_index].angular_velocity;
 - 	}
 - 	if (g[i].axis == 0)
 -            x = 1.0;
 -         else if (g[i].axis == 1)
 -            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++)
 - 	{
 - 	    for (j = 0; j < number_of_gears; j++)
 - 	    {
 - 		if (!(strcmp (g[i].type, g[j].type)) && (!(strcmp (g[i].type, "NORMAL"))) && ((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));
 - 		    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 if (g[i].axis == 1)
 - 		    {
 - 			dist = g[i].position[1] - g[j].position[1];
 - 		    }
 - 		    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)))
 - 			{
 - 			    axle_index = axle_find (g[j].axle_name);
 - 			    if ((a[axle_index].direction != 0) && (g[j].angular_velocity != g[i].angular_velocity * g[i].teeth / g[j].teeth * g[i].radius / g[j].radius))
 - 			    {
 - 				printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
 -                                 /*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);
 - 			    if ((a[axle_index].direction != 0) && (g[i].angular_velocity != g[j].angular_velocity * g[j].teeth / g[i].teeth * g[j].radius / g[i].radius))
 - 			    {
 - 				printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].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));
 - 		    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[j].axle_name);
 - 			if ((a[axle_index].direction != 0) && (g[j].angular_velocity != g[i].angular_velocity * g[i].teeth / g[j].teeth * g[i].radius / g[j].radius))
 - 			{
 - 			    printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
 -                             /*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 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
 - 		    {
 - 			axle_index = axle_find (g[i].axle_name);
 - 			if ((a[axle_index].direction != 0) && (g[i].angular_velocity != g[j].angular_velocity * g[j].teeth / g[i].teeth * g[j].radius / g[i].radius))
 - 			{
 - 			    printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].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);
 - 		    }
 - 		}
 - 	    }
 - 	}
 - 
 - 	for (i = 0; i < number_of_gears; i++)
 - 	{
 - 	    axle_index = axle_find (g[i].axle_name);
 - 	    g[i].motored = a[axle_index].motored;
 - 	    if (a[axle_index].motored)
 - 	    {
 - 		g[i].direction = a[axle_index].direction;
 - 		g[i].angular_velocity = a[axle_index].angular_velocity;
 - 	    }
 - 	}
 - 
 - 	for (i = 0; i < number_of_belts; i++)
 - 	{
 - 	    g1 = gear_find (b[i].gear1_name);
 - 	    g2 = gear_find (b[i].gear2_name);
 - 	    D = sqrt (pow (g[g1].position[0] - g[g2].position[0], 2) + pow (g[g1].position[1] - g[g2].position[1], 2) + pow (g[g1].position[2] - g[g2].position[2], 2));
 - 	    if (!((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL"))))
 - 	    {
 - 		printf (error, "Belt %s invalid.", b[i].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")))
 - 	    {
 - 	      /*
 - 	         if((g[g1].motored)&&(g[g2].motored))
 - 	         if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
 - 	         {
 - 	         printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
 - 	         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 if (g[i].axis == 1)
 - 		{
 - 		    dist = g[g1].position[1] - g[g2].position[1];
 - 		}
 - 		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)
 - 		    {
 - 			printf (error, "Gears %s and %s too close to be linked with belts", g[g1].name, g[g2].name);
 -                         /*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].motored = (a[axle_index].motored = 1);
 - 			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);
 - 			g[g1].motored = (a[axle_index].motored = 1);
 - 			g[g1].direction = (a[axle_index].direction = g[g2].direction);
 - 			g[g1].angular_velocity = (a[axle_index].angular_velocity = g[g2].angular_velocity * g[g2].radius / g[g1].radius);
 - 		    }
 - 		}
 - 	    }
 - 	}
 - 
 - 	for (i = 0; i < number_of_gears; i++)
 - 	{
 - 	    axle_index = axle_find (g[i].axle_name);
 - 	    g[i].motored = a[axle_index].motored;
 - 	    if (a[axle_index].motored)
 - 	    {
 - 		g[i].direction = a[axle_index].direction;
 - 		g[i].angular_velocity = a[axle_index].angular_velocity;
 - 	    }
 - 	}
 -     }
 - }
 - 
 - 
 - 
 - GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
 - 
 - 
 - 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;
 - 	y = 0.0;
 - 	z = 0.0;
 - 	glPushMatrix ();
 - /*glTranslatef( -3.0, -2.0, 0.0 );*/
 - 	glTranslatef (g[i].position[0], g[i].position[1], g[i].position[2]);
 - 	if (g[i].axis == 0)
 -            y = 1.0;
 -         else if (g[i].axis == 1)
 -            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;
 - 	y = 0.0;
 - 	z = 0.0;
 - 	glPushMatrix ();
 - 	glTranslatef (a[i].position[0], a[i].position[1], a[i].position[2]);
 - 	if (a[i].axis == 0)
 -            y = 1.0;
 -         else if (a[i].axis == 1)
 -            x = 1.0;
 -         else
 -            z = 1.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;
 - 	y = 0.0;
 - 	z = 0.0;
 - 	glPushMatrix ();
 - 	index = gear_find (b[i].gear1_name);
 - 	glTranslatef (g[index].position[0], g[index].position[1], g[index].position[2]);
 - 	if (g[index].axis == 0)
 -            y = 1.0;
 -         else if (g[index].axis == 1)
 -            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)
 - {
 -     int i;
 -     for (i = 0; i < number_of_gears; i++)
 -       g[i].angle += g[i].angular_velocity;
 -     glutPostRedisplay();
 - }
 - 
 - 
 - 
 - 
 - /* change view angle, exit upon ESC */
 - static void
 - key (unsigned char k, int x, int y)
 - {
 -     switch (k)
 -     {
 -     case 'x':
 - 	view_rotx += 5.0;
 -         break;
 -     case 'X':
 - 	view_rotx -= 5.0;
 -         break;
 -     case 'y':
 - 	view_roty += 5.0;
 -         break;
 -     case 'Y':
 - 	view_roty -= 5.0;
 -         break;
 -     case 'z':
 - 	view_rotz += 5.0;
 -         break;
 -     case 'Z':
 - 	view_rotz -= 5.0;
 -         break;
 -     case 0x1B:
 - 	exit(0);
 -     }
 - }
 - 
 - 
 - 
 - 
 - /* new window size or exposure */
 - static void
 - reshape (int width, int height)
 - {
 -     glViewport (0, 0, (GLint) width, (GLint) height);
 -     glMatrixMode (GL_PROJECTION);
 -     glLoadIdentity ();
 -     if (width > height)
 -     {
 - 	GLfloat w = (GLfloat) width / (GLfloat) height;
 - 	glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
 -     }
 -     else
 -     {
 - 	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);
 -     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 - }
 - 
 - 
 - 
 - 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);
 - 	glNewList (g[i].id, GL_COMPILE);
 - 	glColor3fv (g[i].color);
 - 	glMaterialfv (GL_FRONT, GL_SPECULAR, g[i].color);
 - 	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);
 - 	glNewList (a[i].id, GL_COMPILE);
 - 	glColor3fv (a[i].color);
 - 	glMaterialfv (GL_FRONT, GL_SPECULAR, a[i].color);
 - 	axle (i, a[i].radius, a[i].length);
 - 	glEndList ();
 -     }
 - 
 -     for (i = 0; i < number_of_belts; i++)
 -     {
 - 	b[i].id = glGenLists (1);
 - 	glNewList (b[i].id, GL_COMPILE);
 - 	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[])
 - {
 -     char *file;
 - 
 -     if (argc < 2)
 -        file = "geartrain.dat";
 -     else
 -        file = argv[1];
 - 
 -     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);
 -     glutIdleFunc (idle);
 -     glutMainLoop ();
 -     return 0;
 - }
 
 
  |