3 * GearTrain Simulator * Version: 1.00
5 * Copyright (C) 1999 Shobhan Kumar Dutta All Rights Reserved.
6 * <skdutta@del3.vsnl.net.in>
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * SHOBHAN KUMAR DUTTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
23 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 #define min(x, y) ( x < y ? x : y )
40 #define M_PI 3.14159265
42 typedef GLfloat TDA
[4];
57 GLfloat angular_velocity
;
73 GLfloat angular_velocity
;
75 GLint relative_position
;
102 char Buf1
[256], Buf2
[256], Buf3
[256], Buf4
[256], Buf5
[256];
105 static GLint Frames
= 0;
110 strset (char buf
[], char ch
)
113 for (i
= 0; i
< strlen (buf
); i
++)
135 result
= fscanf (mainfile
, "%s %s %s %s", Buf1
, Buf2
, Buf3
, Buf4
);
136 assert(result
!= EOF
);
148 result
= fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
149 assert(result
!= EOF
);
159 result
= fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
160 assert(result
!= EOF
);
170 result
= fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
171 assert(result
!= EOF
);
177 getdata (char filename
[])
179 int gear_count
= 0, axle_count
= 0, belt_count
= 0, i
;
181 mainfile
= fopen (filename
, "r");
183 printf("Error: couldn't open %s\n", filename
);
191 result
= fscanf (mainfile
, "%s", Buf1
);
193 if (ferror (mainfile
))
195 printf ("\nError opening file !\n");
199 if (!(strcmp (Buf1
, "BACKGROUND")))
200 LoadTriplet (background
);
202 if (!(strcmp (Buf1
, "ANAME")))
204 LoadText (a
[axle_count
].name
);
208 if (!(strcmp (Buf1
, "ARADIUS")))
209 LoadReal (&a
[axle_count
- 1].radius
);
211 if (!(strcmp (Buf1
, "AAXIS")))
212 LoadInteger (&a
[axle_count
- 1].axis
);
214 if (!(strcmp (Buf1
, "ACOLOR")))
215 LoadTriplet (a
[axle_count
- 1].color
);
217 if (!(strcmp (Buf1
, "APOSITION")))
218 LoadTriplet (a
[axle_count
- 1].position
);
220 if (!(strcmp (Buf1
, "ALENGTH")))
221 LoadReal (&a
[axle_count
- 1].length
);
223 if (!(strcmp (Buf1
, "AMOTORED")))
224 LoadInteger (&a
[axle_count
- 1].motored
);
226 if (!(strcmp (Buf1
, "AANGULARVELOCITY")))
227 LoadReal (&a
[axle_count
- 1].angular_velocity
);
229 if (!(strcmp (Buf1
, "ADIRECTION")))
230 LoadInteger (&a
[axle_count
- 1].direction
);
232 if (!(strcmp (Buf1
, "GNAME")))
234 LoadText (g
[gear_count
].name
);
238 if (!(strcmp (Buf1
, "GTYPE")))
239 LoadText (g
[gear_count
- 1].type
);
241 if (!(strcmp (Buf1
, "GFACE")))
242 LoadInteger (&g
[gear_count
- 1].face
);
244 if (!(strcmp (Buf1
, "GRADIUS")))
245 LoadReal (&g
[gear_count
- 1].radius
);
247 if (!(strcmp (Buf1
, "GWIDTH")))
248 LoadReal (&g
[gear_count
- 1].width
);
250 if (!(strcmp (Buf1
, "GTEETH")))
251 LoadInteger (&g
[gear_count
- 1].teeth
);
253 if (!(strcmp (Buf1
, "GTOOTHDEPTH")))
254 LoadReal (&g
[gear_count
- 1].tooth_depth
);
256 if (!(strcmp (Buf1
, "GCOLOR")))
257 LoadTriplet (g
[gear_count
- 1].color
);
259 if (!(strcmp (Buf1
, "GAXLE")))
260 LoadText (g
[gear_count
- 1].axle_name
);
262 if (!(strcmp (Buf1
, "GPOSITION")))
263 LoadInteger (&g
[gear_count
- 1].relative_position
);
265 if (!(strcmp (Buf1
, "BELTNAME")))
267 LoadText (b
[belt_count
].name
);
271 if (!(strcmp (Buf1
, "GEAR1NAME")))
272 LoadText (b
[belt_count
- 1].gear1_name
);
274 if (!(strcmp (Buf1
, "GEAR2NAME")))
275 LoadText (b
[belt_count
- 1].gear2_name
);
278 while (Buf1
[0] != 0);
280 for (i
= 0; i
< number_of_gears
; i
++)
284 g
[i
].angular_velocity
= 0.0;
287 number_of_gears
= gear_count
;
288 number_of_axles
= axle_count
;
289 number_of_belts
= belt_count
;
295 axle (GLint j
, GLfloat radius
, GLfloat length
)
297 GLfloat angle
, rad
, incr
= 10.0 * M_PI
/ 180.0;
299 /* draw main cylinder */
301 for (angle
= 0.0; angle
< 360.0; angle
+= 5.0)
303 rad
= angle
* M_PI
/ 180.0;
304 glNormal3f (cos (rad
), sin (rad
), 0.0);
305 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), 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 (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), length
/ 2);
312 /* draw front face */
313 glNormal3f (0.0, 0.0, 1.0);
314 glBegin (GL_TRIANGLES
);
315 for (angle
= 0.0; angle
< 360.0; angle
+= 5.0)
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);
326 glNormal3f (0.0, 0.0, -1.0);
327 glBegin (GL_TRIANGLES
);
328 for (angle
= 0.0; angle
<= 360.0; angle
+= 5.0)
330 rad
= angle
* M_PI
/ 180.0;
331 glVertex3f (0.0, 0.0, -length
/ 2);
332 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), -length
/ 2);
333 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), -length
/ 2);
334 glVertex3f (0.0, 0.0, -length
/ 2);
342 gear (GLint j
, char type
[], GLfloat radius
, GLfloat width
,
343 GLint teeth
, GLfloat tooth_depth
)
348 GLfloat u
, v
, len
, fraction
= 0.5;
351 r1
= radius
- tooth_depth
;
354 da
= 2.0 * M_PI
/ teeth
/ 4.0;
360 if (!(strcmp (type
, "NORMAL")))
366 /* draw front face */
367 if (!(strcmp (type
, "NORMAL")))
369 glNormal3f (0.0, 0.0, 1.0 * n
);
370 glBegin (GL_QUAD_STRIP
);
371 for (i
= 0; i
<= teeth
; i
++)
373 angle
= i
* 2.0 * M_PI
/ teeth
;
374 glVertex3f (0.0, 0.0, width
* fraction
);
375 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
376 glVertex3f (0.0, 0.0, width
* fraction
);
377 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
383 glNormal3f (0.0, 0.0, 1.0 * n
);
384 glBegin (GL_QUAD_STRIP
);
385 for (i
= 0; i
<= teeth
; i
++)
387 angle
= i
* 2.0 * M_PI
/ teeth
;
388 glVertex3f (0.0, 0.0, width
* fraction
);
389 glVertex3f ((r2
- width
) * cos (angle
), (r2
- width
) * sin (angle
), width
* fraction
);
390 glVertex3f (0.0, 0.0, width
* fraction
);
391 glVertex3f ((r2
- width
) * cos (angle
+ 3 * da
), (r2
- width
) * sin (angle
+ 3 * da
), width
* fraction
);
396 /* draw front sides of teeth */
397 if (!(strcmp (type
, "NORMAL")))
399 glNormal3f (0.0, 0.0, 1.0 * n
);
401 da
= 2.0 * M_PI
/ teeth
/ 4.0;
402 for (i
= 0; i
< teeth
; i
++)
404 angle
= i
* 2.0 * M_PI
/ teeth
;
405 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
406 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), width
* fraction
);
407 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), width
* fraction
);
408 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
413 glNormal3f (0.0, 0.0, -1.0 * n
);
416 glBegin (GL_QUAD_STRIP
);
417 for (i
= 0; i
<= teeth
; i
++)
419 angle
= i
* 2.0 * M_PI
/ teeth
;
420 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
421 glVertex3f (0.0, 0.0, -width
* fraction
);
422 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
423 glVertex3f (0.0, 0.0, -width
* fraction
);
427 /* draw back sides of teeth */
428 glNormal3f (0.0, 0.0, -1.0 * n
);
430 da
= 2.0 * M_PI
/ teeth
/ 4.0;
431 for (i
= 0; i
< teeth
; i
++)
433 angle
= i
* 2.0 * M_PI
/ teeth
;
434 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
435 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
436 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
437 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
442 /* draw outward faces of teeth */
443 if (!(strcmp (type
, "NORMAL")))
445 glBegin (GL_QUAD_STRIP
);
446 for (i
= 0; i
< teeth
; i
++)
448 angle
= i
* 2.0 * M_PI
/ teeth
;
450 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
451 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
452 u
= r2
* cos (angle
+ da
) - r1
* cos (angle
);
453 v
= r2
* sin (angle
+ da
) - r1
* sin (angle
);
454 len
= sqrt (u
* u
+ v
* v
);
457 glNormal3f (v
, -u
, 0.0);
458 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), width
* fraction
);
459 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
460 glNormal3f (cos (angle
), sin (angle
), 0.0);
461 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), width
* fraction
);
462 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
463 u
= r1
* cos (angle
+ 3 * da
) - r2
* cos (angle
+ 2 * da
);
464 v
= r1
* sin (angle
+ 3 * da
) - r2
* sin (angle
+ 2 * da
);
465 glNormal3f (v
, -u
, 0.0);
466 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
467 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
468 glNormal3f (cos (angle
), sin (angle
), 0.0);
473 glBegin (GL_QUAD_STRIP
);
474 for (i
= 0; i
< teeth
; i
++)
476 angle
= i
* 2.0 * M_PI
/ teeth
;
477 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
478 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
479 u
= r2
* cos (angle
+ da
) - r1
* cos (angle
);
480 v
= r2
* sin (angle
+ da
) - r1
* sin (angle
);
481 len
= sqrt (u
* u
+ v
* v
);
484 glNormal3f (v
, -u
, 0.0);
485 glVertex3f ((r2
- width
) * cos (angle
+ da
), (r2
- width
) * sin (angle
+ da
), width
* fraction
);
486 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
487 glNormal3f (cos (angle
), sin (angle
), n
);
488 glVertex3f ((r2
- width
) * cos (angle
+ 2 * da
), (r2
- width
) * sin (angle
+ 2 * da
), width
* fraction
);
489 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
490 u
= r1
* cos (angle
+ 3 * da
) - r2
* cos (angle
+ 2 * da
);
491 v
= r1
* sin (angle
+ 3 * da
) - r2
* sin (angle
+ 2 * da
);
492 glNormal3f (v
, -u
, 0.0);
493 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
494 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
495 glNormal3f (cos (angle
), sin (angle
), n
);
499 glVertex3f (r1
* cos (0), r1
* sin (0), width
* fraction
);
500 glVertex3f (r1
* cos (0), r1
* sin (0), -width
* fraction
);
506 belt (struct GEAR g1
, struct GEAR g2
)
508 GLfloat D
, alpha
, phi
, angle
, incr
, width
;
519 width
= min (g1
.width
, g2
.width
);
520 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));
521 alpha
= acos ((g2
.position
[0] - g1
.position
[0]) / D
);
522 phi
= acos ((g1
.radius
- g2
.radius
) / D
);
525 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
526 incr
= 1.2 * 360.0 / g1
.teeth
* M_PI
/ 180.00;
527 for (angle
= alpha
+ phi
; angle
<= 2 * M_PI
- phi
+ alpha
; angle
+= 360.0 / g1
.teeth
* M_PI
/ 180.00)
529 glNormal3f (cos (angle
), sin (angle
), 0.0);
530 glVertex3f (g1
.radius
* cos (angle
), g1
.radius
* sin (angle
), width
* 0.5);
531 glVertex3f (g1
.radius
* cos (angle
), g1
.radius
* sin (angle
), -width
* 0.5);
532 glVertex3f (g1
.radius
* cos (angle
+ incr
), g1
.radius
* sin (angle
+ incr
), -width
* 0.5);
533 glVertex3f (g1
.radius
* cos (angle
+ incr
), g1
.radius
* sin (angle
+ incr
), width
* 0.5);
538 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
539 incr
= 1.2 * 360.0 / g2
.teeth
* M_PI
/ 180.00;
540 for (angle
= -phi
+ alpha
; angle
<= phi
+ alpha
; angle
+= 360.0 / g1
.teeth
* M_PI
/ 180.0)
542 glNormal3f (cos (angle
), sin (angle
), 0.0);
543 glVertex3f (g2
.radius
* cos (angle
) + g2
.position
[0] - g1
.position
[0], g2
.radius
* sin (angle
) + g2
.position
[1] - g1
.position
[1], width
* 0.5);
544 glVertex3f (g2
.radius
* cos (angle
) + g2
.position
[0] - g1
.position
[0], g2
.radius
* sin (angle
) + g2
.position
[1] - g1
.position
[1], width
* -0.5);
545 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);
546 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);
552 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
553 glVertex3f (g1
.radius
* cos (alpha
+ phi
), g1
.radius
* sin (alpha
+ phi
), width
* 0.5);
554 glVertex3f (g1
.radius
* cos (alpha
+ phi
), g1
.radius
* sin (alpha
+ phi
), width
* -0.5);
555 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);
556 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);
557 glVertex3f (g1
.radius
* cos (alpha
- phi
), g1
.radius
* sin (alpha
- phi
), width
* 0.5);
558 glVertex3f (g1
.radius
* cos (alpha
- phi
), g1
.radius
* sin (alpha
- phi
), width
* -0.5);
559 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);
560 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);
566 axle_find (char axle_name
[])
570 for (i
= 0; i
< number_of_axles
; i
++)
572 if (!(strcmp (axle_name
, a
[i
].name
)))
580 gear_find (char gear_name
[])
584 for (i
= 0; i
< number_of_gears
; i
++)
586 if (!(strcmp (gear_name
, g
[i
].name
)))
596 GLfloat x
, y
, z
, D
, dist
;
597 GLint axle_index
, i
, j
, g1
, g2
, k
;
600 for (i
= 0; i
< number_of_gears
; i
++)
605 axle_index
= axle_find (g
[i
].axle_name
);
606 g
[i
].axis
= a
[axle_index
].axis
;
607 g
[i
].motored
= a
[axle_index
].motored
;
608 if (a
[axle_index
].motored
)
610 g
[i
].direction
= a
[axle_index
].direction
;
611 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
615 else if (g
[i
].axis
== 1)
620 g
[i
].position
[0] = a
[axle_index
].position
[0] + x
* g
[i
].relative_position
;
621 g
[i
].position
[1] = a
[axle_index
].position
[1] + y
* g
[i
].relative_position
;
622 g
[i
].position
[2] = a
[axle_index
].position
[2] + z
* g
[i
].relative_position
;
625 for (k
= 0; k
< number_of_axles
; k
++)
627 for (i
= 0; i
< number_of_gears
- 1; i
++)
629 for (j
= 0; j
< number_of_gears
; j
++)
631 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
))
633 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));
634 if (D
< 1.1 * (g
[i
].radius
- g
[i
].tooth_depth
+ g
[j
].radius
- g
[j
].tooth_depth
))
636 printf (error
, "Gear %s and %s are too close to each other.", g
[i
].name
, g
[j
].name
);
638 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
644 dist
= g
[i
].position
[0] - g
[j
].position
[0];
646 else if (g
[i
].axis
== 1)
648 dist
= g
[i
].position
[1] - g
[j
].position
[1];
651 dist
= g
[i
].position
[2] - g
[j
].position
[2];
655 if (dist
< (g
[i
].width
/ 2 + g
[j
].width
/ 2))
657 if ((g
[i
].motored
) && (!(g
[j
].motored
)) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
659 axle_index
= axle_find (g
[j
].axle_name
);
660 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
))
662 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
663 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
667 g
[j
].motored
= (a
[axle_index
].motored
= 1);
668 g
[j
].direction
= (a
[axle_index
].direction
= -g
[i
].direction
);
669 a
[axle_index
].angular_velocity
= g
[i
].angular_velocity
* g
[i
].teeth
/ g
[j
].teeth
;
670 g
[j
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[i
].radius
/ g
[j
].radius
);
673 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
675 axle_index
= axle_find (g
[i
].axle_name
);
676 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
))
678 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
679 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
683 g
[i
].motored
= (a
[axle_index
].motored
= 1);
684 g
[i
].direction
= (a
[axle_index
].direction
= -g
[j
].direction
);
685 a
[axle_index
].angular_velocity
= g
[j
].angular_velocity
* g
[j
].teeth
/ g
[i
].teeth
;
686 g
[i
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[j
].radius
/ g
[i
].radius
);
692 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
))
694 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));
695 if ((g
[i
].motored
) && (!(g
[j
].motored
)) && (D
< 0.95 * sqrt (g
[i
].radius
* g
[i
].radius
+ g
[j
].radius
* g
[j
].radius
)))
697 axle_index
= axle_find (g
[j
].axle_name
);
698 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
))
700 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
701 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
704 g
[j
].motored
= (a
[axle_index
].motored
= 1);
705 g
[j
].direction
= (a
[axle_index
].direction
= -g
[i
].direction
);
706 a
[axle_index
].angular_velocity
= g
[i
].angular_velocity
* g
[i
].teeth
/ g
[j
].teeth
;
707 g
[j
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[i
].radius
/ g
[j
].radius
);
711 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * sqrt (g
[i
].radius
* g
[i
].radius
+ g
[j
].radius
* g
[j
].radius
)))
713 axle_index
= axle_find (g
[i
].axle_name
);
714 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
))
716 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
717 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
720 g
[i
].motored
= (a
[axle_index
].motored
= 1);
721 g
[i
].direction
= (a
[axle_index
].direction
= -g
[j
].direction
);
722 a
[axle_index
].angular_velocity
= g
[j
].angular_velocity
* g
[j
].teeth
/ g
[i
].teeth
;
723 g
[i
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[j
].radius
/ g
[i
].radius
);
729 for (i
= 0; i
< number_of_gears
; i
++)
731 axle_index
= axle_find (g
[i
].axle_name
);
732 g
[i
].motored
= a
[axle_index
].motored
;
733 if (a
[axle_index
].motored
)
735 g
[i
].direction
= a
[axle_index
].direction
;
736 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
740 for (i
= 0; i
< number_of_belts
; i
++)
742 g1
= gear_find (b
[i
].gear1_name
);
743 g2
= gear_find (b
[i
].gear2_name
);
744 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));
745 if (!((g
[g1
].axis
== g
[g2
].axis
) && (!strcmp (g
[g1
].type
, g
[g2
].type
)) && (!strcmp (g
[g1
].type
, "NORMAL"))))
747 printf (error
, "Belt %s invalid.", b
[i
].name
);
748 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
752 if ((g
[g1
].axis
== g
[g2
].axis
) && (!strcmp (g
[g1
].type
, g
[g2
].type
)) && (!strcmp (g
[g1
].type
, "NORMAL")))
755 if((g[g1].motored)&&(g[g2].motored))
756 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
758 printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
759 MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
765 dist
= g
[g1
].position
[0] - g
[g2
].position
[0];
767 else if (g
[i
].axis
== 1)
769 dist
= g
[g1
].position
[1] - g
[g2
].position
[1];
772 dist
= g
[g1
].position
[2] - g
[g2
].position
[2];
776 if (dist
> (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
778 printf (error
, "Belt %s invalid.", b
[i
].name
);
779 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
783 if (dist
< (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
785 if (D
< g
[g1
].radius
+ g
[g2
].radius
)
787 printf (error
, "Gears %s and %s too close to be linked with belts", g
[g1
].name
, g
[g2
].name
);
788 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
792 if ((g
[g1
].motored
) && (!(g
[g2
].motored
)))
794 axle_index
= axle_find (g
[g2
].axle_name
);
795 g
[g2
].motored
= (a
[axle_index
].motored
= 1);
796 g
[g2
].direction
= (a
[axle_index
].direction
= g
[g1
].direction
);
797 g
[g2
].angular_velocity
= (a
[axle_index
].angular_velocity
= g
[g1
].angular_velocity
* g
[g1
].radius
/ g
[g2
].radius
);
800 if ((!(g
[g1
].motored
)) && (g
[g2
].motored
))
802 axle_index
= axle_find (g
[g1
].axle_name
);
803 g
[g1
].motored
= (a
[axle_index
].motored
= 1);
804 g
[g1
].direction
= (a
[axle_index
].direction
= g
[g2
].direction
);
805 g
[g1
].angular_velocity
= (a
[axle_index
].angular_velocity
= g
[g2
].angular_velocity
* g
[g2
].radius
/ g
[g1
].radius
);
811 for (i
= 0; i
< number_of_gears
; i
++)
813 axle_index
= axle_find (g
[i
].axle_name
);
814 g
[i
].motored
= a
[axle_index
].motored
;
815 if (a
[axle_index
].motored
)
817 g
[i
].direction
= a
[axle_index
].direction
;
818 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
826 GLfloat view_rotx
= 20.0, view_roty
= 30.0, view_rotz
= 10.0;
836 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
839 glRotatef (view_rotx
, 1.0, 0.0, 0.0);
840 glRotatef (view_roty
, 0.0, 1.0, 0.0);
841 glRotatef (view_rotz
, 0.0, 0.0, 1.0);
843 for (i
= 0; i
< number_of_gears
; i
++)
849 /*glTranslatef( -3.0, -2.0, 0.0 );*/
850 glTranslatef (g
[i
].position
[0], g
[i
].position
[1], g
[i
].position
[2]);
853 else if (g
[i
].axis
== 1)
859 glRotatef (90.0, x
, y
, z
);
861 glRotatef (g
[i
].direction
* g
[i
].angle
, 0.0, 0.0, 1.0);
862 glCallList (g
[i
].id
);
866 for (i
= 0; i
< number_of_axles
; i
++)
872 glTranslatef (a
[i
].position
[0], a
[i
].position
[1], a
[i
].position
[2]);
875 else if (a
[i
].axis
== 1)
881 glRotatef (90.0, x
, y
, z
);
883 glCallList (a
[i
].id
);
887 for (i
= 0; i
< number_of_belts
; i
++)
893 index
= gear_find (b
[i
].gear1_name
);
894 glTranslatef (g
[index
].position
[0], g
[index
].position
[1], g
[index
].position
[2]);
895 if (g
[index
].axis
== 0)
897 else if (g
[index
].axis
== 1)
903 glRotatef (90.0, x
, y
, z
);
905 glCallList (b
[i
].id
);
913 GLint t
= glutGet(GLUT_ELAPSED_TIME
);
915 if (t
- T0
>= 5000) {
916 GLfloat seconds
= (t
- T0
) / 1000.0;
917 GLfloat fps
= Frames
/ seconds
;
918 printf("%d frames in %g seconds = %g FPS\n", Frames
, seconds
, fps
);
931 static double t0
= -1.;
932 double dt
, t
= glutGet(GLUT_ELAPSED_TIME
) / 1000.0;
937 for (i
= 0; i
< number_of_gears
; i
++)
938 g
[i
].angle
+= g
[i
].angular_velocity
* dt
;
945 /* change view angle, exit upon ESC */
947 key (unsigned char k
, int x
, int y
)
977 /* new window size or exposure */
979 reshape (int width
, int height
)
981 glViewport (0, 0, (GLint
) width
, (GLint
) height
);
982 glMatrixMode (GL_PROJECTION
);
986 GLfloat w
= (GLfloat
) width
/ (GLfloat
) height
;
987 glFrustum (-w
, w
, -1.0, 1.0, 5.0, 60.0);
991 GLfloat h
= (GLfloat
) height
/ (GLfloat
) width
;
992 glFrustum (-1.0, 1.0, -h
, h
, 5.0, 60.0);
995 glMatrixMode (GL_MODELVIEW
);
997 glTranslatef (0.0, 0.0, -40.0);
998 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
1006 GLfloat matShine
= 20.00F
;
1007 GLfloat light0Pos
[4] =
1009 0.70F
, 0.70F
, 1.25F
, 0.50F
1013 glClearColor (background
[0], background
[1], background
[2], 1.0F
);
1014 glClearIndex ((GLfloat
) 0.0);
1016 glMaterialf (GL_FRONT_AND_BACK
, GL_SHININESS
, matShine
);
1017 glLightfv (GL_LIGHT0
, GL_POSITION
, light0Pos
);
1018 glEnable (GL_LIGHT0
);
1020 glEnable (GL_LIGHTING
);
1021 glEnable (GL_DEPTH_TEST
);
1022 for (i
= 0; i
< number_of_gears
; i
++)
1025 for (i
= 0; i
< number_of_gears
; i
++)
1027 g
[i
].id
= glGenLists (1);
1028 glNewList (g
[i
].id
, GL_COMPILE
);
1029 glColor3fv (g
[i
].color
);
1030 glMaterialfv (GL_FRONT
, GL_SPECULAR
, g
[i
].color
);
1031 gear (i
, g
[i
].type
, g
[i
].radius
, g
[i
].width
, g
[i
].teeth
, g
[i
].tooth_depth
);
1035 for (i
= 0; i
< number_of_axles
; i
++)
1037 a
[i
].id
= glGenLists (1);
1038 glNewList (a
[i
].id
, GL_COMPILE
);
1039 glColor3fv (a
[i
].color
);
1040 glMaterialfv (GL_FRONT
, GL_SPECULAR
, a
[i
].color
);
1041 axle (i
, a
[i
].radius
, a
[i
].length
);
1045 for (i
= 0; i
< number_of_belts
; i
++)
1047 b
[i
].id
= glGenLists (1);
1048 glNewList (b
[i
].id
, GL_COMPILE
);
1049 belt (g
[gear_find (b
[i
].gear1_name
)], g
[gear_find (b
[i
].gear2_name
)]);
1053 glEnable (GL_COLOR_MATERIAL
);
1059 main (int argc
, char *argv
[])
1063 glutInitWindowSize(640,480);
1064 glutInit(&argc
, argv
);
1065 glutInitDisplayMode (GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
1067 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE
)
1071 file
= "geartrain.dat";
1079 glutDisplayFunc (draw
);
1080 glutReshapeFunc (reshape
);
1081 glutKeyboardFunc (key
);
1082 glutIdleFunc (idle
);