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