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