blob: 7c42aeb3d5211928ae0f51730c730163194ceca7 [file] [log] [blame]
Brian Paul5a564052000-03-29 17:56:02 +00001/* $Id: geartrain.c,v 1.3 2000/03/29 17:56:02 brianp Exp $ */
Brian Paul392a7002000-03-06 23:34:42 +00002
3/*
4 * Geartrain simulation
5 *
6 * Contributed by Shobhan Kumar Dutta <skdutta@del3.vsnl.net.in>
7 */
8
9
10#include <math.h>
11#include <stdlib.h>
12#include <GL/glut.h>
13#include <string.h>
14#include <stdio.h>
15
16#define min(x, y) ( x < y ? x : y )
17
18#ifndef M_PI
19#define M_PI 3.14159265
20#endif /* */
Brian Paul3769b3f2000-03-22 23:14:54 +000021typedef GLfloat TDA[4];
Brian Paul392a7002000-03-06 23:34:42 +000022
23TDA background;
24
25
26struct AXLE
27 {
28 char name[20];
29 GLint id;
30 GLfloat radius;
31 GLint axis;
32 TDA color;
33 TDA position;
34 GLfloat length;
35 GLint motored;
36 GLfloat angular_velocity;
37 GLint direction;
38 };
39
40
41struct GEAR
42 {
43 char name[20];
44 char type[7];
45 GLint face;
46 GLint id;
47 GLfloat radius;
48 GLfloat width;
49 GLint teeth;
50 GLfloat tooth_depth;
51 GLfloat angle;
52 GLfloat angular_velocity;
53 TDA color;
54 GLint relative_position;
55 TDA position;
56 char axle_name[20];
57 GLint axis;
58 GLint direction;
59 GLint motored;
60 };
61
62
63struct BELT
64 {
65 char name[20];
66 GLint id;
67 char gear1_name[20];
68 char gear2_name[20];
69 };
70
71
72FILE * mainfile;
73struct GEAR g[10];
74struct AXLE a[10];
75struct BELT b[10];
76int number_of_gears;
77int number_of_axles;
78int number_of_belts;
79
80
81char Buf1[256], Buf2[256], Buf3[256], Buf4[256], Buf5[256];
82
83
84void
85strset (char buf[], char ch)
86{
87 int i;
88 for (i = 0; i < strlen (buf); i++)
89 buf[i] = ch;
90}
91
92
93void
94Clear_Buffers ()
95{
96 strset (Buf1, 0);
97 strset (Buf2, 0);
98 strset (Buf3, 0);
99 strset (Buf4, 0);
100 strset (Buf5, 0);
101}
102
103
104void
105LoadTriplet (TDA A)
106{
107 Clear_Buffers ();
108 fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
109 A[0] = atof (Buf2);
110 A[1] = atof (Buf3);
111 A[2] = atof (Buf4);
112}
113
114
115void
116LoadReal (float *a)
117{
118 Clear_Buffers ();
119 fscanf (mainfile, "%s %s", Buf1, Buf2);
120 *a = atof (Buf2);
121}
122
123
124void
125LoadInteger (int *a)
126{
127 Clear_Buffers ();
128 fscanf (mainfile, "%s %s", Buf1, Buf2);
129 *a = atoi (Buf2);
130}
131
132
133void
134LoadText (char *a)
135{
136 Clear_Buffers ();
137 fscanf (mainfile, "%s %s", Buf1, Buf2);
138 strcpy (a, Buf2);
139}
140
141
142void
143getdata (char filename[])
144{
145 int gear_count = 0, axle_count = 0, belt_count = 0, i;
146
147 mainfile = fopen (filename, "r");
Brian Paul5a564052000-03-29 17:56:02 +0000148 if (!mainfile) {
149 printf("Error: couldn't open %s\n", filename);
150 exit(-1);
151 }
152
Brian Paul392a7002000-03-06 23:34:42 +0000153 do
154 {
155 Clear_Buffers ();
156 fscanf (mainfile, "%s", Buf1);
157 if (ferror (mainfile))
158 {
159 printf ("\nError opening file !\n");
160 exit (1);
161 }
162
163 if (!(strcmp (Buf1, "BACKGROUND")))
164 LoadTriplet (background);
165
166 if (!(strcmp (Buf1, "ANAME")))
167 {
168 LoadText (a[axle_count].name);
169 axle_count++;
170 }
171
172 if (!(strcmp (Buf1, "ARADIUS")))
173 LoadReal (&a[axle_count - 1].radius);
174
175 if (!(strcmp (Buf1, "AAXIS")))
176 LoadInteger (&a[axle_count - 1].axis);
177
178 if (!(strcmp (Buf1, "ACOLOR")))
179 LoadTriplet (a[axle_count - 1].color);
180
181 if (!(strcmp (Buf1, "APOSITION")))
182 LoadTriplet (a[axle_count - 1].position);
183
184 if (!(strcmp (Buf1, "ALENGTH")))
185 LoadReal (&a[axle_count - 1].length);
186
187 if (!(strcmp (Buf1, "AMOTORED")))
188 LoadInteger (&a[axle_count - 1].motored);
189
190 if (!(strcmp (Buf1, "AANGULARVELOCITY")))
191 LoadReal (&a[axle_count - 1].angular_velocity);
192
193 if (!(strcmp (Buf1, "ADIRECTION")))
194 LoadInteger (&a[axle_count - 1].direction);
195
196 if (!(strcmp (Buf1, "GNAME")))
197 {
198 LoadText (g[gear_count].name);
199 gear_count++;
200 }
201
202 if (!(strcmp (Buf1, "GTYPE")))
203 LoadText (g[gear_count - 1].type);
204
205 if (!(strcmp (Buf1, "GFACE")))
206 LoadInteger (&g[gear_count - 1].face);
207
208 if (!(strcmp (Buf1, "GRADIUS")))
209 LoadReal (&g[gear_count - 1].radius);
210
211 if (!(strcmp (Buf1, "GWIDTH")))
212 LoadReal (&g[gear_count - 1].width);
213
214 if (!(strcmp (Buf1, "GTEETH")))
215 LoadInteger (&g[gear_count - 1].teeth);
216
217 if (!(strcmp (Buf1, "GTOOTHDEPTH")))
218 LoadReal (&g[gear_count - 1].tooth_depth);
219
220 if (!(strcmp (Buf1, "GCOLOR")))
221 LoadTriplet (g[gear_count - 1].color);
222
223 if (!(strcmp (Buf1, "GAXLE")))
224 LoadText (g[gear_count - 1].axle_name);
225
226 if (!(strcmp (Buf1, "GPOSITION")))
227 LoadInteger (&g[gear_count - 1].relative_position);
228
229 if (!(strcmp (Buf1, "BELTNAME")))
230 {
231 LoadText (b[belt_count].name);
232 belt_count++;
233 }
234
235 if (!(strcmp (Buf1, "GEAR1NAME")))
236 LoadText (b[belt_count - 1].gear1_name);
237
238 if (!(strcmp (Buf1, "GEAR2NAME")))
239 LoadText (b[belt_count - 1].gear2_name);
240 }
241
242 while (Buf1[0] != 0);
243
244 for (i = 0; i < number_of_gears; i++)
245 {
246 g[i].axis = -1;
247 g[i].direction = 0;
248 g[i].angular_velocity = 0.0;
249 }
250
251 number_of_gears = gear_count;
252 number_of_axles = axle_count;
253 number_of_belts = belt_count;
254 fclose (mainfile);
255}
256
257
258static void
259axle (GLint j, GLfloat radius, GLfloat length)
260{
261 GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
262 GLint indexes[3] =
263 {
264 0, 0, 0
265 };
266
267 /* draw main cylinder */
268 glBegin (GL_QUADS);
269 for (angle = 0.0; angle < 360.0; angle += 5.0)
270 {
271 rad = angle * M_PI / 180.0;
272 glNormal3f (cos (rad), sin (rad), 0.0);
273 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
274 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
275 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
276 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
277 }
278 glEnd ();
279
280 /* draw front face */
281 glNormal3f (0.0, 0.0, 1.0);
282 glBegin (GL_TRIANGLES);
283 for (angle = 0.0; angle < 360.0; angle += 5.0)
284 {
285 rad = angle * M_PI / 180.0;
286 glVertex3f (0.0, 0.0, length / 2);
287 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
288 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
289 glVertex3f (0.0, 0.0, length / 2);
290 }
291 glEnd ();
292
293 /* draw back face */
294 glNormal3f (0.0, 0.0, -1.0);
295 glBegin (GL_TRIANGLES);
296 for (angle = 0.0; angle <= 360.0; angle += 5.0)
297 {
298 rad = angle * M_PI / 180.0;
299 glVertex3f (0.0, 0.0, -length / 2);
300 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
301 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
302 glVertex3f (0.0, 0.0, -length / 2);
303 }
304 glEnd ();
305}
306
307
308
309static void
310gear (GLint j, char type[], GLfloat radius, GLfloat width,
311 GLint teeth, GLfloat tooth_depth)
312{
313 GLint i;
314 GLfloat r1, r2;
315 GLfloat angle, da;
316 GLfloat u, v, len, fraction = 0.5;
317 GLfloat n = 1.0;
318 GLint indexes[3] =
319 {
320 0, 0, 0
321 };
322
323 r1 = radius - tooth_depth;
324 r2 = radius;
325
326 da = 2.0 * M_PI / teeth / 4.0;
327 if (!g[j].face)
328 {
329 fraction = -0.5;
330 n = -1.0;
331 }
332 if (!(strcmp (type, "NORMAL")))
333 {
334 fraction = 0.5;
335 n = 1.0;
336 }
337
338 /* draw front face */
339 if (!(strcmp (type, "NORMAL")))
340 {
341 glNormal3f (0.0, 0.0, 1.0 * n);
342 glBegin (GL_QUAD_STRIP);
343 for (i = 0; i <= teeth; i++)
344 {
345 angle = i * 2.0 * M_PI / teeth;
346 glVertex3f (0.0, 0.0, width * fraction);
347 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
348 glVertex3f (0.0, 0.0, width * fraction);
349 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
350 }
351 glEnd ();
352 }
353 else
354 {
355 glNormal3f (0.0, 0.0, 1.0 * n);
356 glBegin (GL_QUAD_STRIP);
357 for (i = 0; i <= teeth; i++)
358 {
359 angle = i * 2.0 * M_PI / teeth;
360 glVertex3f (0.0, 0.0, width * fraction);
361 glVertex3f ((r2 - width) * cos (angle), (r2 - width) * sin (angle), width * fraction);
362 glVertex3f (0.0, 0.0, width * fraction);
363 glVertex3f ((r2 - width) * cos (angle + 3 * da), (r2 - width) * sin (angle + 3 * da), width * fraction);
364 }
365 glEnd ();
366 }
367
368 /* draw front sides of teeth */
369 if (!(strcmp (type, "NORMAL")))
370 {
371 glNormal3f (0.0, 0.0, 1.0 * n);
372 glBegin (GL_QUADS);
373 da = 2.0 * M_PI / teeth / 4.0;
374 for (i = 0; i < teeth; i++)
375 {
376 angle = i * 2.0 * M_PI / teeth;
377 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
378 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
379 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
380 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
381 }
382 glEnd ();
383 }
384
385 glNormal3f (0.0, 0.0, -1.0 * n);
386
387 /* draw back face */
388 glBegin (GL_QUAD_STRIP);
389 for (i = 0; i <= teeth; i++)
390 {
391 angle = i * 2.0 * M_PI / teeth;
392 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
393 glVertex3f (0.0, 0.0, -width * fraction);
394 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
395 glVertex3f (0.0, 0.0, -width * fraction);
396 }
397 glEnd ();
398
399 /* draw back sides of teeth */
400 glNormal3f (0.0, 0.0, -1.0 * n);
401 glBegin (GL_QUADS);
402 da = 2.0 * M_PI / teeth / 4.0;
403 for (i = 0; i < teeth; i++)
404 {
405 angle = i * 2.0 * M_PI / teeth;
406 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
407 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
408 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
409 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
410 }
411 glEnd ();
412
413
414 /* draw outward faces of teeth */
415 if (!(strcmp (type, "NORMAL")))
416 {
417 glBegin (GL_QUAD_STRIP);
418 for (i = 0; i < teeth; i++)
419 {
420 angle = i * 2.0 * M_PI / teeth;
421
422 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
423 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
424 u = r2 * cos (angle + da) - r1 * cos (angle);
425 v = r2 * sin (angle + da) - r1 * sin (angle);
426 len = sqrt (u * u + v * v);
427 u /= len;
428 v /= len;
429 glNormal3f (v, -u, 0.0);
430 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
431 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
432 glNormal3f (cos (angle), sin (angle), 0.0);
433 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
434 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
435 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
436 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
437 glNormal3f (v, -u, 0.0);
438 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
439 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
440 glNormal3f (cos (angle), sin (angle), 0.0);
441 }
442 }
443 else
444 {
445 glBegin (GL_QUAD_STRIP);
446 for (i = 0; i < teeth; i++)
447 {
448 angle = i * 2.0 * M_PI / teeth;
449 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
450 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
451 u = r2 * cos (angle + da) - r1 * cos (angle);
452 v = r2 * sin (angle + da) - r1 * sin (angle);
453 len = sqrt (u * u + v * v);
454 u /= len;
455 v /= len;
456 glNormal3f (v, -u, 0.0);
457 glVertex3f ((r2 - width) * cos (angle + da), (r2 - width) * sin (angle + da), width * fraction);
458 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
459 glNormal3f (cos (angle), sin (angle), n);
460 glVertex3f ((r2 - width) * cos (angle + 2 * da), (r2 - width) * sin (angle + 2 * da), width * fraction);
461 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
462 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
463 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
464 glNormal3f (v, -u, 0.0);
465 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
466 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
467 glNormal3f (cos (angle), sin (angle), n);
468 }
469 }
470
471 glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction);
472 glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction);
473 glEnd ();
474}
475
476
477static void
478belt (struct GEAR g1, struct GEAR g2)
479{
480 GLfloat D, alpha, phi, angle, incr, width;
481 GLint indexes[3] =
482 {
483 0, 0, 0
484 };
485
486 GLfloat col[3] =
487 {
488 0.0, 0.0, 0.0
489 };
490
491 width = min (g1.width, g2.width);
492 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));
493 alpha = acos ((g2.position[0] - g1.position[0]) / D);
494 phi = acos ((g1.radius - g2.radius) / D);
495 glBegin (GL_QUADS);
496 glColor3fv (col);
497 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
498 incr = 1.2 * 360.0 / g1.teeth * M_PI / 180.00;
499 for (angle = alpha + phi; angle <= 2 * M_PI - phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.00)
500 {
501 glNormal3f (cos (angle), sin (angle), 0.0);
502 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), width * 0.5);
503 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), -width * 0.5);
504 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), -width * 0.5);
505 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), width * 0.5);
506 }
507 glEnd ();
508 glBegin (GL_QUADS);
509 glColor3fv (col);
510 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
511 incr = 1.2 * 360.0 / g2.teeth * M_PI / 180.00;
512 for (angle = -phi + alpha; angle <= phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.0)
513 {
514 glNormal3f (cos (angle), sin (angle), 0.0);
515 glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * 0.5);
516 glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * -0.5);
517 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);
518 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);
519 }
520 glEnd ();
521
522 glBegin (GL_QUADS);
523 glColor3fv (col);
524 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
525 glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * 0.5);
526 glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * -0.5);
527 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);
528 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);
529 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * 0.5);
530 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * -0.5);
531 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);
532 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);
533 glEnd ();
534}
535
536
537int
538axle_find (char axle_name[])
539{
540 int i;
541
542 for (i = 0; i < number_of_axles; i++)
543 {
544 if (!(strcmp (axle_name, a[i].name)))
545 break;
546 }
547 return i;
548}
549
550
551int
552gear_find (char gear_name[])
553{
554 int i;
555
556 for (i = 0; i < number_of_gears; i++)
557 {
558 if (!(strcmp (gear_name, g[i].name)))
559 break;
560 }
561 return i;
562}
563
564
565void
566process ()
567{
568 GLfloat x, y, z, D, dist;
569 GLint axle_index, i, j, g1, g2, k;
570 char error[80];
571
572 for (i = 0; i < number_of_gears; i++)
573 {
574 x = 0.0;
575 y = 0.0;
576 z = 0.0;
577 axle_index = axle_find (g[i].axle_name);
578 g[i].axis = a[axle_index].axis;
579 g[i].motored = a[axle_index].motored;
580 if (a[axle_index].motored)
581 {
582 g[i].direction = a[axle_index].direction;
583 g[i].angular_velocity = a[axle_index].angular_velocity;
584 }
585 if (g[i].axis == 0)
586 x = 1.0;
587 else if (g[i].axis == 1)
588 y = 1.0;
589 else
590 z = 1.0;
591
592 g[i].position[0] = a[axle_index].position[0] + x * g[i].relative_position;
593 g[i].position[1] = a[axle_index].position[1] + y * g[i].relative_position;
594 g[i].position[2] = a[axle_index].position[2] + z * g[i].relative_position;
595 }
596
597 for (k = 0; k < number_of_axles; k++)
598 {
599 for (i = 0; i < number_of_gears - 1; i++)
600 {
601 for (j = 0; j < number_of_gears; j++)
602 {
603 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))
604 {
605 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));
606 if (D < 1.1 * (g[i].radius - g[i].tooth_depth + g[j].radius - g[j].tooth_depth))
607 {
608 printf (error, "Gear %s and %s are too close to each other.", g[i].name, g[j].name);
609
610 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
611 exit (1);
612 }
613
614 if (g[i].axis == 0)
615 {
616 dist = g[i].position[0] - g[j].position[0];
617 }
618 else if (g[i].axis == 1)
619 {
620 dist = g[i].position[1] - g[j].position[1];
621 }
622 else
623 dist = g[i].position[2] - g[j].position[2];
624
625 dist = fabs (dist);
626
627 if (dist < (g[i].width / 2 + g[j].width / 2))
628 {
629 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius)))
630 {
631 axle_index = axle_find (g[j].axle_name);
632 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))
633 {
634 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
635 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
636 exit (1);
637 }
638
639 g[j].motored = (a[axle_index].motored = 1);
640 g[j].direction = (a[axle_index].direction = -g[i].direction);
641 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
642 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
643 }
644
645 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius)))
646 {
647 axle_index = axle_find (g[i].axle_name);
648 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))
649 {
650 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
651 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
652 exit (1);
653 }
654
655 g[i].motored = (a[axle_index].motored = 1);
656 g[i].direction = (a[axle_index].direction = -g[j].direction);
657 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
658 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
659
660 }
661 }
662 }
663
664 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))
665 {
666 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));
667 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
668 {
669 axle_index = axle_find (g[j].axle_name);
670 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))
671 {
672 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
673 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
674 exit (1);
675 }
676 g[j].motored = (a[axle_index].motored = 1);
677 g[j].direction = (a[axle_index].direction = -g[i].direction);
678 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
679 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
680 }
681
682
683 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
684 {
685 axle_index = axle_find (g[i].axle_name);
686 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))
687 {
688 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
689 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
690 exit (1);
691 }
692 g[i].motored = (a[axle_index].motored = 1);
693 g[i].direction = (a[axle_index].direction = -g[j].direction);
694 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
695 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
696 }
697 }
698 }
699 }
700
701 for (i = 0; i < number_of_gears; i++)
702 {
703 axle_index = axle_find (g[i].axle_name);
704 g[i].motored = a[axle_index].motored;
705 if (a[axle_index].motored)
706 {
707 g[i].direction = a[axle_index].direction;
708 g[i].angular_velocity = a[axle_index].angular_velocity;
709 }
710 }
711
712 for (i = 0; i < number_of_belts; i++)
713 {
714 g1 = gear_find (b[i].gear1_name);
715 g2 = gear_find (b[i].gear2_name);
716 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));
717 if (!((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL"))))
718 {
719 printf (error, "Belt %s invalid.", b[i].name);
720 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
721 exit (1);
722 }
723
724 if ((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))
725 {
726 /*
727 if((g[g1].motored)&&(g[g2].motored))
728 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
729 {
730 printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
731 MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
732 exit(1);
733 }
734 */
735 if (g[g1].axis == 0)
736 {
737 dist = g[g1].position[0] - g[g2].position[0];
738 }
739 else if (g[i].axis == 1)
740 {
741 dist = g[g1].position[1] - g[g2].position[1];
742 }
743 else
744 dist = g[g1].position[2] - g[g2].position[2];
745
746 dist = fabs (dist);
747
748 if (dist > (g[g1].width / 2 + g[g2].width / 2))
749 {
750 printf (error, "Belt %s invalid.", b[i].name);
751 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
752 exit (1);
753 }
754
755 if (dist < (g[g1].width / 2 + g[g2].width / 2))
756 {
757 if (D < g[g1].radius + g[g2].radius)
758 {
759 printf (error, "Gears %s and %s too close to be linked with belts", g[g1].name, g[g2].name);
760 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
761 exit (1);
762 }
763
764 if ((g[g1].motored) && (!(g[g2].motored)))
765 {
766 axle_index = axle_find (g[g2].axle_name);
767 g[g2].motored = (a[axle_index].motored = 1);
768 g[g2].direction = (a[axle_index].direction = g[g1].direction);
769 g[g2].angular_velocity = (a[axle_index].angular_velocity = g[g1].angular_velocity * g[g1].radius / g[g2].radius);
770 }
771
772 if ((!(g[g1].motored)) && (g[g2].motored))
773 {
774 axle_index = axle_find (g[g1].axle_name);
775 g[g1].motored = (a[axle_index].motored = 1);
776 g[g1].direction = (a[axle_index].direction = g[g2].direction);
777 g[g1].angular_velocity = (a[axle_index].angular_velocity = g[g2].angular_velocity * g[g2].radius / g[g1].radius);
778 }
779 }
780 }
781 }
782
783 for (i = 0; i < number_of_gears; i++)
784 {
785 axle_index = axle_find (g[i].axle_name);
786 g[i].motored = a[axle_index].motored;
787 if (a[axle_index].motored)
788 {
789 g[i].direction = a[axle_index].direction;
790 g[i].angular_velocity = a[axle_index].angular_velocity;
791 }
792 }
793 }
794}
795
796
797
798GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
799
800
801static void
802draw (void)
803{
804 int i;
805 GLfloat x, y, z;
806 int index;
807
808 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
809
810 glPushMatrix ();
811 glRotatef (view_rotx, 1.0, 0.0, 0.0);
812 glRotatef (view_roty, 0.0, 1.0, 0.0);
813 glRotatef (view_rotz, 0.0, 0.0, 1.0);
814
815 for (i = 0; i < number_of_gears; i++)
816 {
817 x = 0.0;
818 y = 0.0;
819 z = 0.0;
820 glPushMatrix ();
821/*glTranslatef( -3.0, -2.0, 0.0 );*/
822 glTranslatef (g[i].position[0], g[i].position[1], g[i].position[2]);
823 if (g[i].axis == 0)
824 y = 1.0;
825 else if (g[i].axis == 1)
826 x = 1.0;
827 else
828 z = 1.0;
829
830 if (z != 1.0)
831 glRotatef (90.0, x, y, z);
832
833 glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0);
834 glCallList (g[i].id);
835 glPopMatrix ();
836 }
837
838 for (i = 0; i < number_of_axles; i++)
839 {
840 x = 0.0;
841 y = 0.0;
842 z = 0.0;
843 glPushMatrix ();
844 glTranslatef (a[i].position[0], a[i].position[1], a[i].position[2]);
845 if (a[i].axis == 0)
846 y = 1.0;
847 else if (a[i].axis == 1)
848 x = 1.0;
849 else
850 z = 1.0;
851
852 if (z != 1.0)
853 glRotatef (90.0, x, y, z);
854
855 glCallList (a[i].id);
856 glPopMatrix ();
857 }
858
859 for (i = 0; i < number_of_belts; i++)
860 {
861 x = 0.0;
862 y = 0.0;
863 z = 0.0;
864 glPushMatrix ();
865 index = gear_find (b[i].gear1_name);
866 glTranslatef (g[index].position[0], g[index].position[1], g[index].position[2]);
867 if (g[index].axis == 0)
868 y = 1.0;
869 else if (g[index].axis == 1)
870 x = 1.0;
871 else
872 z = 1.0;
873
874 if (z != 1.0)
875 glRotatef (90.0, x, y, z);
876
877 glCallList (b[i].id);
878 glPopMatrix ();
879 }
880
881 glPopMatrix ();
882 glutSwapBuffers ();
883}
884
885
886
887
888static void
889idle (void)
890{
891 int i;
892 for (i = 0; i < number_of_gears; i++)
893 g[i].angle += g[i].angular_velocity;
894 glutPostRedisplay();
895}
896
897
898
899
900/* change view angle, exit upon ESC */
901static void
902key (unsigned char k, int x, int y)
903{
904 switch (k)
905 {
906 case 'x':
907 view_rotx += 5.0;
908 break;
909 case 'X':
910 view_rotx -= 5.0;
911 break;
912 case 'y':
913 view_roty += 5.0;
914 break;
915 case 'Y':
916 view_roty -= 5.0;
917 break;
918 case 'z':
919 view_rotz += 5.0;
920 break;
921 case 'Z':
922 view_rotz -= 5.0;
923 break;
924 case 0x1B:
925 exit(0);
926 }
927}
928
929
930
931
932/* new window size or exposure */
933static void
934reshape (int width, int height)
935{
936 glViewport (0, 0, (GLint) width, (GLint) height);
937 glMatrixMode (GL_PROJECTION);
938 glLoadIdentity ();
939 if (width > height)
940 {
941 GLfloat w = (GLfloat) width / (GLfloat) height;
942 glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
943 }
944 else
945 {
946 GLfloat h = (GLfloat) height / (GLfloat) width;
947 glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
948 }
949
950 glMatrixMode (GL_MODELVIEW);
951 glLoadIdentity ();
952 glTranslatef (0.0, 0.0, -40.0);
953 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
954}
955
956
957
958static void
959init (void)
960{
961 GLfloat matShine = 20.00F;
962 GLfloat light0Pos[4] =
963 {
964 0.70F, 0.70F, 1.25F, 0.50F
965 };
966 int i;
967
968 glClearColor (background[0], background[1], background[2], 1.0F);
969 glClearIndex ((GLfloat) 0.0);
970
971 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine);
972 glLightfv (GL_LIGHT0, GL_POSITION, light0Pos);
973 glEnable (GL_LIGHT0);
974
975 glEnable (GL_LIGHTING);
976 glEnable (GL_DEPTH_TEST);
977 for (i = 0; i < number_of_gears; i++)
978 g[i].angle = 0.0;
979
980 for (i = 0; i < number_of_gears; i++)
981 {
982 g[i].id = glGenLists (1);
983 glNewList (g[i].id, GL_COMPILE);
984 glColor3fv (g[i].color);
985 glMaterialfv (GL_FRONT, GL_SPECULAR, g[i].color);
986 gear (i, g[i].type, g[i].radius, g[i].width, g[i].teeth, g[i].tooth_depth);
987 glEndList ();
988 }
989
990 for (i = 0; i < number_of_axles; i++)
991 {
992 a[i].id = glGenLists (1);
993 glNewList (a[i].id, GL_COMPILE);
994 glColor3fv (a[i].color);
995 glMaterialfv (GL_FRONT, GL_SPECULAR, a[i].color);
996 axle (i, a[i].radius, a[i].length);
997 glEndList ();
998 }
999
1000 for (i = 0; i < number_of_belts; i++)
1001 {
1002 b[i].id = glGenLists (1);
1003 glNewList (b[i].id, GL_COMPILE);
1004 belt (g[gear_find (b[i].gear1_name)], g[gear_find (b[i].gear2_name)]);
1005 glEndList ();
1006 }
1007
1008 glEnable (GL_COLOR_MATERIAL);
1009}
1010
1011
1012
1013int
1014main (int argc, char *argv[])
1015{
1016 char *file;
1017
1018 if (argc < 2)
1019 file = "geartrain.dat";
1020 else
1021 file = argv[1];
1022
1023 glutInitWindowPosition (0, 0);
1024 glutInitWindowSize(640,480);
1025 glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
1026
1027 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
1028 exit (1);
1029
1030 getdata (file);
1031 process ();
1032 init ();
1033
1034 glutDisplayFunc (draw);
1035 glutReshapeFunc (reshape);
1036 glutKeyboardFunc (key);
1037 glutIdleFunc (idle);
1038 glutMainLoop ();
1039 return 0;
1040}
1041