91c3411d7c96715ff85db81ac3d55cb1ed70c6dc
1 /* $Id: geartrain.c,v 1.2 2000/03/22 23:14:54 brianp Exp $ */
6 * Contributed by Shobhan Kumar Dutta <skdutta@del3.vsnl.net.in>
16 #define min(x, y) ( x < y ? x : y )
19 #define M_PI 3.14159265
21 typedef GLfloat TDA
[4];
36 GLfloat angular_velocity
;
52 GLfloat angular_velocity
;
54 GLint relative_position
;
81 char Buf1
[256], Buf2
[256], Buf3
[256], Buf4
[256], Buf5
[256];
85 strset (char buf
[], char ch
)
88 for (i
= 0; i
< strlen (buf
); i
++)
108 fscanf (mainfile
, "%s %s %s %s", Buf1
, Buf2
, Buf3
, Buf4
);
119 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
128 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
137 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
143 getdata (char filename
[])
145 int gear_count
= 0, axle_count
= 0, belt_count
= 0, i
;
147 mainfile
= fopen (filename
, "r");
151 fscanf (mainfile
, "%s", Buf1
);
152 if (ferror (mainfile
))
154 printf ("\nError opening file !\n");
158 if (!(strcmp (Buf1
, "BACKGROUND")))
159 LoadTriplet (background
);
161 if (!(strcmp (Buf1
, "ANAME")))
163 LoadText (a
[axle_count
].name
);
167 if (!(strcmp (Buf1
, "ARADIUS")))
168 LoadReal (&a
[axle_count
- 1].radius
);
170 if (!(strcmp (Buf1
, "AAXIS")))
171 LoadInteger (&a
[axle_count
- 1].axis
);
173 if (!(strcmp (Buf1
, "ACOLOR")))
174 LoadTriplet (a
[axle_count
- 1].color
);
176 if (!(strcmp (Buf1
, "APOSITION")))
177 LoadTriplet (a
[axle_count
- 1].position
);
179 if (!(strcmp (Buf1
, "ALENGTH")))
180 LoadReal (&a
[axle_count
- 1].length
);
182 if (!(strcmp (Buf1
, "AMOTORED")))
183 LoadInteger (&a
[axle_count
- 1].motored
);
185 if (!(strcmp (Buf1
, "AANGULARVELOCITY")))
186 LoadReal (&a
[axle_count
- 1].angular_velocity
);
188 if (!(strcmp (Buf1
, "ADIRECTION")))
189 LoadInteger (&a
[axle_count
- 1].direction
);
191 if (!(strcmp (Buf1
, "GNAME")))
193 LoadText (g
[gear_count
].name
);
197 if (!(strcmp (Buf1
, "GTYPE")))
198 LoadText (g
[gear_count
- 1].type
);
200 if (!(strcmp (Buf1
, "GFACE")))
201 LoadInteger (&g
[gear_count
- 1].face
);
203 if (!(strcmp (Buf1
, "GRADIUS")))
204 LoadReal (&g
[gear_count
- 1].radius
);
206 if (!(strcmp (Buf1
, "GWIDTH")))
207 LoadReal (&g
[gear_count
- 1].width
);
209 if (!(strcmp (Buf1
, "GTEETH")))
210 LoadInteger (&g
[gear_count
- 1].teeth
);
212 if (!(strcmp (Buf1
, "GTOOTHDEPTH")))
213 LoadReal (&g
[gear_count
- 1].tooth_depth
);
215 if (!(strcmp (Buf1
, "GCOLOR")))
216 LoadTriplet (g
[gear_count
- 1].color
);
218 if (!(strcmp (Buf1
, "GAXLE")))
219 LoadText (g
[gear_count
- 1].axle_name
);
221 if (!(strcmp (Buf1
, "GPOSITION")))
222 LoadInteger (&g
[gear_count
- 1].relative_position
);
224 if (!(strcmp (Buf1
, "BELTNAME")))
226 LoadText (b
[belt_count
].name
);
230 if (!(strcmp (Buf1
, "GEAR1NAME")))
231 LoadText (b
[belt_count
- 1].gear1_name
);
233 if (!(strcmp (Buf1
, "GEAR2NAME")))
234 LoadText (b
[belt_count
- 1].gear2_name
);
237 while (Buf1
[0] != 0);
239 for (i
= 0; i
< number_of_gears
; i
++)
243 g
[i
].angular_velocity
= 0.0;
246 number_of_gears
= gear_count
;
247 number_of_axles
= axle_count
;
248 number_of_belts
= belt_count
;
254 axle (GLint j
, GLfloat radius
, GLfloat length
)
256 GLfloat angle
, rad
, incr
= 10.0 * M_PI
/ 180.0;
262 /* draw main cylinder */
264 for (angle
= 0.0; angle
< 360.0; angle
+= 5.0)
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);
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)
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);
289 glNormal3f (0.0, 0.0, -1.0);
290 glBegin (GL_TRIANGLES
);
291 for (angle
= 0.0; angle
<= 360.0; angle
+= 5.0)
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);
305 gear (GLint j
, char type
[], GLfloat radius
, GLfloat width
,
306 GLint teeth
, GLfloat tooth_depth
)
311 GLfloat u
, v
, len
, fraction
= 0.5;
318 r1
= radius
- tooth_depth
;
321 da
= 2.0 * M_PI
/ teeth
/ 4.0;
327 if (!(strcmp (type
, "NORMAL")))
333 /* draw front face */
334 if (!(strcmp (type
, "NORMAL")))
336 glNormal3f (0.0, 0.0, 1.0 * n
);
337 glBegin (GL_QUAD_STRIP
);
338 for (i
= 0; i
<= teeth
; i
++)
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
);
350 glNormal3f (0.0, 0.0, 1.0 * n
);
351 glBegin (GL_QUAD_STRIP
);
352 for (i
= 0; i
<= teeth
; i
++)
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
);
363 /* draw front sides of teeth */
364 if (!(strcmp (type
, "NORMAL")))
366 glNormal3f (0.0, 0.0, 1.0 * n
);
368 da
= 2.0 * M_PI
/ teeth
/ 4.0;
369 for (i
= 0; i
< teeth
; i
++)
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
);
380 glNormal3f (0.0, 0.0, -1.0 * n
);
383 glBegin (GL_QUAD_STRIP
);
384 for (i
= 0; i
<= teeth
; i
++)
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
);
394 /* draw back sides of teeth */
395 glNormal3f (0.0, 0.0, -1.0 * n
);
397 da
= 2.0 * M_PI
/ teeth
/ 4.0;
398 for (i
= 0; i
< teeth
; i
++)
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
);
409 /* draw outward faces of teeth */
410 if (!(strcmp (type
, "NORMAL")))
412 glBegin (GL_QUAD_STRIP
);
413 for (i
= 0; i
< teeth
; i
++)
415 angle
= i
* 2.0 * M_PI
/ teeth
;
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
);
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);
440 glBegin (GL_QUAD_STRIP
);
441 for (i
= 0; i
< teeth
; i
++)
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
);
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
);
466 glVertex3f (r1
* cos (0), r1
* sin (0), width
* fraction
);
467 glVertex3f (r1
* cos (0), r1
* sin (0), -width
* fraction
);
473 belt (struct GEAR g1
, struct GEAR g2
)
475 GLfloat D
, alpha
, phi
, angle
, incr
, width
;
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
);
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)
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);
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)
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);
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);
533 axle_find (char axle_name
[])
537 for (i
= 0; i
< number_of_axles
; i
++)
539 if (!(strcmp (axle_name
, a
[i
].name
)))
547 gear_find (char gear_name
[])
551 for (i
= 0; i
< number_of_gears
; i
++)
553 if (!(strcmp (gear_name
, g
[i
].name
)))
563 GLfloat x
, y
, z
, D
, dist
;
564 GLint axle_index
, i
, j
, g1
, g2
, k
;
567 for (i
= 0; i
< number_of_gears
; i
++)
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
)
577 g
[i
].direction
= a
[axle_index
].direction
;
578 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
582 else if (g
[i
].axis
== 1)
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
;
592 for (k
= 0; k
< number_of_axles
; k
++)
594 for (i
= 0; i
< number_of_gears
- 1; i
++)
596 for (j
= 0; j
< number_of_gears
; j
++)
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
))
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
))
603 printf (error
, "Gear %s and %s are too close to each other.", g
[i
].name
, g
[j
].name
);
605 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
611 dist
= g
[i
].position
[0] - g
[j
].position
[0];
613 else if (g
[i
].axis
== 1)
615 dist
= g
[i
].position
[1] - g
[j
].position
[1];
618 dist
= g
[i
].position
[2] - g
[j
].position
[2];
622 if (dist
< (g
[i
].width
/ 2 + g
[j
].width
/ 2))
624 if ((g
[i
].motored
) && (!(g
[j
].motored
)) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
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
))
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);*/
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
);
640 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
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
))
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);*/
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
);
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
))
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
)))
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
))
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);*/
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
);
678 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * sqrt (g
[i
].radius
* g
[i
].radius
+ g
[j
].radius
* g
[j
].radius
)))
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
))
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);*/
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
);
696 for (i
= 0; i
< number_of_gears
; i
++)
698 axle_index
= axle_find (g
[i
].axle_name
);
699 g
[i
].motored
= a
[axle_index
].motored
;
700 if (a
[axle_index
].motored
)
702 g
[i
].direction
= a
[axle_index
].direction
;
703 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
707 for (i
= 0; i
< number_of_belts
; i
++)
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"))))
714 printf (error
, "Belt %s invalid.", b
[i
].name
);
715 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
719 if ((g
[g1
].axis
== g
[g2
].axis
) && (!strcmp (g
[g1
].type
, g
[g2
].type
)) && (!strcmp (g
[g1
].type
, "NORMAL")))
722 if((g[g1].motored)&&(g[g2].motored))
723 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
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);
732 dist
= g
[g1
].position
[0] - g
[g2
].position
[0];
734 else if (g
[i
].axis
== 1)
736 dist
= g
[g1
].position
[1] - g
[g2
].position
[1];
739 dist
= g
[g1
].position
[2] - g
[g2
].position
[2];
743 if (dist
> (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
745 printf (error
, "Belt %s invalid.", b
[i
].name
);
746 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
750 if (dist
< (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
752 if (D
< g
[g1
].radius
+ g
[g2
].radius
)
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);*/
759 if ((g
[g1
].motored
) && (!(g
[g2
].motored
)))
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
);
767 if ((!(g
[g1
].motored
)) && (g
[g2
].motored
))
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
);
778 for (i
= 0; i
< number_of_gears
; i
++)
780 axle_index
= axle_find (g
[i
].axle_name
);
781 g
[i
].motored
= a
[axle_index
].motored
;
782 if (a
[axle_index
].motored
)
784 g
[i
].direction
= a
[axle_index
].direction
;
785 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
793 GLfloat view_rotx
= 20.0, view_roty
= 30.0, view_rotz
= 10.0;
803 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
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);
810 for (i
= 0; i
< number_of_gears
; i
++)
816 /*glTranslatef( -3.0, -2.0, 0.0 );*/
817 glTranslatef (g
[i
].position
[0], g
[i
].position
[1], g
[i
].position
[2]);
820 else if (g
[i
].axis
== 1)
826 glRotatef (90.0, x
, y
, z
);
828 glRotatef (g
[i
].direction
* g
[i
].angle
, 0.0, 0.0, 1.0);
829 glCallList (g
[i
].id
);
833 for (i
= 0; i
< number_of_axles
; i
++)
839 glTranslatef (a
[i
].position
[0], a
[i
].position
[1], a
[i
].position
[2]);
842 else if (a
[i
].axis
== 1)
848 glRotatef (90.0, x
, y
, z
);
850 glCallList (a
[i
].id
);
854 for (i
= 0; i
< number_of_belts
; i
++)
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)
864 else if (g
[index
].axis
== 1)
870 glRotatef (90.0, x
, y
, z
);
872 glCallList (b
[i
].id
);
887 for (i
= 0; i
< number_of_gears
; i
++)
888 g
[i
].angle
+= g
[i
].angular_velocity
;
895 /* change view angle, exit upon ESC */
897 key (unsigned char k
, int x
, int y
)
927 /* new window size or exposure */
929 reshape (int width
, int height
)
931 glViewport (0, 0, (GLint
) width
, (GLint
) height
);
932 glMatrixMode (GL_PROJECTION
);
936 GLfloat w
= (GLfloat
) width
/ (GLfloat
) height
;
937 glFrustum (-w
, w
, -1.0, 1.0, 5.0, 60.0);
941 GLfloat h
= (GLfloat
) height
/ (GLfloat
) width
;
942 glFrustum (-1.0, 1.0, -h
, h
, 5.0, 60.0);
945 glMatrixMode (GL_MODELVIEW
);
947 glTranslatef (0.0, 0.0, -40.0);
948 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
956 GLfloat matShine
= 20.00F
;
957 GLfloat light0Pos
[4] =
959 0.70F
, 0.70F
, 1.25F
, 0.50F
963 glClearColor (background
[0], background
[1], background
[2], 1.0F
);
964 glClearIndex ((GLfloat
) 0.0);
966 glMaterialf (GL_FRONT_AND_BACK
, GL_SHININESS
, matShine
);
967 glLightfv (GL_LIGHT0
, GL_POSITION
, light0Pos
);
968 glEnable (GL_LIGHT0
);
970 glEnable (GL_LIGHTING
);
971 glEnable (GL_DEPTH_TEST
);
972 for (i
= 0; i
< number_of_gears
; i
++)
975 for (i
= 0; i
< number_of_gears
; i
++)
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
);
985 for (i
= 0; i
< number_of_axles
; i
++)
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
);
995 for (i
= 0; i
< number_of_belts
; i
++)
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
)]);
1003 glEnable (GL_COLOR_MATERIAL
);
1009 main (int argc
, char *argv
[])
1014 file
= "geartrain.dat";
1018 glutInitWindowPosition (0, 0);
1019 glutInitWindowSize(640,480);
1020 glutInitDisplayMode (GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
1022 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE
)
1029 glutDisplayFunc (draw
);
1030 glutReshapeFunc (reshape
);
1031 glutKeyboardFunc (key
);
1032 glutIdleFunc (idle
);