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
35 #define min(x, y) ( x < y ? x : y )
39 #define M_PI 3.14159265
41 typedef GLfloat TDA
[4];
56 GLfloat angular_velocity
;
72 GLfloat angular_velocity
;
74 GLint relative_position
;
101 char Buf1
[256], Buf2
[256], Buf3
[256], Buf4
[256], Buf5
[256];
104 static GLint Frames
= 0;
109 strset (char buf
[], char ch
)
112 for (i
= 0; i
< strlen (buf
); i
++)
133 fscanf (mainfile
, "%s %s %s %s", Buf1
, Buf2
, Buf3
, Buf4
);
144 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
153 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
162 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
168 getdata (char filename
[])
170 int gear_count
= 0, axle_count
= 0, belt_count
= 0, i
;
172 mainfile
= fopen (filename
, "r");
174 printf("Error: couldn't open %s\n", filename
);
181 fscanf (mainfile
, "%s", Buf1
);
182 if (ferror (mainfile
))
184 printf ("\nError opening file !\n");
188 if (!(strcmp (Buf1
, "BACKGROUND")))
189 LoadTriplet (background
);
191 if (!(strcmp (Buf1
, "ANAME")))
193 LoadText (a
[axle_count
].name
);
197 if (!(strcmp (Buf1
, "ARADIUS")))
198 LoadReal (&a
[axle_count
- 1].radius
);
200 if (!(strcmp (Buf1
, "AAXIS")))
201 LoadInteger (&a
[axle_count
- 1].axis
);
203 if (!(strcmp (Buf1
, "ACOLOR")))
204 LoadTriplet (a
[axle_count
- 1].color
);
206 if (!(strcmp (Buf1
, "APOSITION")))
207 LoadTriplet (a
[axle_count
- 1].position
);
209 if (!(strcmp (Buf1
, "ALENGTH")))
210 LoadReal (&a
[axle_count
- 1].length
);
212 if (!(strcmp (Buf1
, "AMOTORED")))
213 LoadInteger (&a
[axle_count
- 1].motored
);
215 if (!(strcmp (Buf1
, "AANGULARVELOCITY")))
216 LoadReal (&a
[axle_count
- 1].angular_velocity
);
218 if (!(strcmp (Buf1
, "ADIRECTION")))
219 LoadInteger (&a
[axle_count
- 1].direction
);
221 if (!(strcmp (Buf1
, "GNAME")))
223 LoadText (g
[gear_count
].name
);
227 if (!(strcmp (Buf1
, "GTYPE")))
228 LoadText (g
[gear_count
- 1].type
);
230 if (!(strcmp (Buf1
, "GFACE")))
231 LoadInteger (&g
[gear_count
- 1].face
);
233 if (!(strcmp (Buf1
, "GRADIUS")))
234 LoadReal (&g
[gear_count
- 1].radius
);
236 if (!(strcmp (Buf1
, "GWIDTH")))
237 LoadReal (&g
[gear_count
- 1].width
);
239 if (!(strcmp (Buf1
, "GTEETH")))
240 LoadInteger (&g
[gear_count
- 1].teeth
);
242 if (!(strcmp (Buf1
, "GTOOTHDEPTH")))
243 LoadReal (&g
[gear_count
- 1].tooth_depth
);
245 if (!(strcmp (Buf1
, "GCOLOR")))
246 LoadTriplet (g
[gear_count
- 1].color
);
248 if (!(strcmp (Buf1
, "GAXLE")))
249 LoadText (g
[gear_count
- 1].axle_name
);
251 if (!(strcmp (Buf1
, "GPOSITION")))
252 LoadInteger (&g
[gear_count
- 1].relative_position
);
254 if (!(strcmp (Buf1
, "BELTNAME")))
256 LoadText (b
[belt_count
].name
);
260 if (!(strcmp (Buf1
, "GEAR1NAME")))
261 LoadText (b
[belt_count
- 1].gear1_name
);
263 if (!(strcmp (Buf1
, "GEAR2NAME")))
264 LoadText (b
[belt_count
- 1].gear2_name
);
267 while (Buf1
[0] != 0);
269 for (i
= 0; i
< number_of_gears
; i
++)
273 g
[i
].angular_velocity
= 0.0;
276 number_of_gears
= gear_count
;
277 number_of_axles
= axle_count
;
278 number_of_belts
= belt_count
;
284 axle (GLint j
, GLfloat radius
, GLfloat length
)
286 GLfloat angle
, rad
, incr
= 10.0 * M_PI
/ 180.0;
288 /* draw main cylinder */
290 for (angle
= 0.0; angle
< 360.0; angle
+= 5.0)
292 rad
= angle
* M_PI
/ 180.0;
293 glNormal3f (cos (rad
), sin (rad
), 0.0);
294 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), 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 (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), length
/ 2);
301 /* draw front face */
302 glNormal3f (0.0, 0.0, 1.0);
303 glBegin (GL_TRIANGLES
);
304 for (angle
= 0.0; angle
< 360.0; angle
+= 5.0)
306 rad
= angle
* M_PI
/ 180.0;
307 glVertex3f (0.0, 0.0, length
/ 2);
308 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), length
/ 2);
309 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), length
/ 2);
310 glVertex3f (0.0, 0.0, length
/ 2);
315 glNormal3f (0.0, 0.0, -1.0);
316 glBegin (GL_TRIANGLES
);
317 for (angle
= 0.0; angle
<= 360.0; angle
+= 5.0)
319 rad
= angle
* M_PI
/ 180.0;
320 glVertex3f (0.0, 0.0, -length
/ 2);
321 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), -length
/ 2);
322 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), -length
/ 2);
323 glVertex3f (0.0, 0.0, -length
/ 2);
331 gear (GLint j
, char type
[], GLfloat radius
, GLfloat width
,
332 GLint teeth
, GLfloat tooth_depth
)
337 GLfloat u
, v
, len
, fraction
= 0.5;
340 r1
= radius
- tooth_depth
;
343 da
= 2.0 * M_PI
/ teeth
/ 4.0;
349 if (!(strcmp (type
, "NORMAL")))
355 /* draw front face */
356 if (!(strcmp (type
, "NORMAL")))
358 glNormal3f (0.0, 0.0, 1.0 * n
);
359 glBegin (GL_QUAD_STRIP
);
360 for (i
= 0; i
<= teeth
; i
++)
362 angle
= i
* 2.0 * M_PI
/ teeth
;
363 glVertex3f (0.0, 0.0, width
* fraction
);
364 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
365 glVertex3f (0.0, 0.0, width
* fraction
);
366 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
372 glNormal3f (0.0, 0.0, 1.0 * n
);
373 glBegin (GL_QUAD_STRIP
);
374 for (i
= 0; i
<= teeth
; i
++)
376 angle
= i
* 2.0 * M_PI
/ teeth
;
377 glVertex3f (0.0, 0.0, width
* fraction
);
378 glVertex3f ((r2
- width
) * cos (angle
), (r2
- width
) * sin (angle
), width
* fraction
);
379 glVertex3f (0.0, 0.0, width
* fraction
);
380 glVertex3f ((r2
- width
) * cos (angle
+ 3 * da
), (r2
- width
) * sin (angle
+ 3 * da
), width
* fraction
);
385 /* draw front sides of teeth */
386 if (!(strcmp (type
, "NORMAL")))
388 glNormal3f (0.0, 0.0, 1.0 * n
);
390 da
= 2.0 * M_PI
/ teeth
/ 4.0;
391 for (i
= 0; i
< teeth
; i
++)
393 angle
= i
* 2.0 * M_PI
/ teeth
;
394 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
395 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), width
* fraction
);
396 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), width
* fraction
);
397 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
402 glNormal3f (0.0, 0.0, -1.0 * n
);
405 glBegin (GL_QUAD_STRIP
);
406 for (i
= 0; i
<= teeth
; i
++)
408 angle
= i
* 2.0 * M_PI
/ teeth
;
409 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
410 glVertex3f (0.0, 0.0, -width
* fraction
);
411 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
412 glVertex3f (0.0, 0.0, -width
* fraction
);
416 /* draw back sides of teeth */
417 glNormal3f (0.0, 0.0, -1.0 * n
);
419 da
= 2.0 * M_PI
/ teeth
/ 4.0;
420 for (i
= 0; i
< teeth
; i
++)
422 angle
= i
* 2.0 * M_PI
/ teeth
;
423 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
424 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
425 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
426 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
431 /* draw outward faces of teeth */
432 if (!(strcmp (type
, "NORMAL")))
434 glBegin (GL_QUAD_STRIP
);
435 for (i
= 0; i
< teeth
; i
++)
437 angle
= i
* 2.0 * M_PI
/ teeth
;
439 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
440 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
441 u
= r2
* cos (angle
+ da
) - r1
* cos (angle
);
442 v
= r2
* sin (angle
+ da
) - r1
* sin (angle
);
443 len
= sqrt (u
* u
+ v
* v
);
446 glNormal3f (v
, -u
, 0.0);
447 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), width
* fraction
);
448 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
449 glNormal3f (cos (angle
), sin (angle
), 0.0);
450 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), width
* fraction
);
451 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
452 u
= r1
* cos (angle
+ 3 * da
) - r2
* cos (angle
+ 2 * da
);
453 v
= r1
* sin (angle
+ 3 * da
) - r2
* sin (angle
+ 2 * da
);
454 glNormal3f (v
, -u
, 0.0);
455 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
456 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
457 glNormal3f (cos (angle
), sin (angle
), 0.0);
462 glBegin (GL_QUAD_STRIP
);
463 for (i
= 0; i
< teeth
; i
++)
465 angle
= i
* 2.0 * M_PI
/ teeth
;
466 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
467 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
468 u
= r2
* cos (angle
+ da
) - r1
* cos (angle
);
469 v
= r2
* sin (angle
+ da
) - r1
* sin (angle
);
470 len
= sqrt (u
* u
+ v
* v
);
473 glNormal3f (v
, -u
, 0.0);
474 glVertex3f ((r2
- width
) * cos (angle
+ da
), (r2
- width
) * sin (angle
+ da
), width
* fraction
);
475 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
476 glNormal3f (cos (angle
), sin (angle
), n
);
477 glVertex3f ((r2
- width
) * cos (angle
+ 2 * da
), (r2
- width
) * sin (angle
+ 2 * da
), width
* fraction
);
478 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
479 u
= r1
* cos (angle
+ 3 * da
) - r2
* cos (angle
+ 2 * da
);
480 v
= r1
* sin (angle
+ 3 * da
) - r2
* sin (angle
+ 2 * da
);
481 glNormal3f (v
, -u
, 0.0);
482 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
483 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
484 glNormal3f (cos (angle
), sin (angle
), n
);
488 glVertex3f (r1
* cos (0), r1
* sin (0), width
* fraction
);
489 glVertex3f (r1
* cos (0), r1
* sin (0), -width
* fraction
);
495 belt (struct GEAR g1
, struct GEAR g2
)
497 GLfloat D
, alpha
, phi
, angle
, incr
, width
;
508 width
= min (g1
.width
, g2
.width
);
509 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));
510 alpha
= acos ((g2
.position
[0] - g1
.position
[0]) / D
);
511 phi
= acos ((g1
.radius
- g2
.radius
) / D
);
514 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
515 incr
= 1.2 * 360.0 / g1
.teeth
* M_PI
/ 180.00;
516 for (angle
= alpha
+ phi
; angle
<= 2 * M_PI
- phi
+ alpha
; angle
+= 360.0 / g1
.teeth
* M_PI
/ 180.00)
518 glNormal3f (cos (angle
), sin (angle
), 0.0);
519 glVertex3f (g1
.radius
* cos (angle
), g1
.radius
* sin (angle
), width
* 0.5);
520 glVertex3f (g1
.radius
* cos (angle
), g1
.radius
* sin (angle
), -width
* 0.5);
521 glVertex3f (g1
.radius
* cos (angle
+ incr
), g1
.radius
* sin (angle
+ incr
), -width
* 0.5);
522 glVertex3f (g1
.radius
* cos (angle
+ incr
), g1
.radius
* sin (angle
+ incr
), width
* 0.5);
527 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
528 incr
= 1.2 * 360.0 / g2
.teeth
* M_PI
/ 180.00;
529 for (angle
= -phi
+ alpha
; angle
<= phi
+ alpha
; angle
+= 360.0 / g1
.teeth
* M_PI
/ 180.0)
531 glNormal3f (cos (angle
), sin (angle
), 0.0);
532 glVertex3f (g2
.radius
* cos (angle
) + g2
.position
[0] - g1
.position
[0], g2
.radius
* sin (angle
) + g2
.position
[1] - g1
.position
[1], width
* 0.5);
533 glVertex3f (g2
.radius
* cos (angle
) + g2
.position
[0] - g1
.position
[0], g2
.radius
* sin (angle
) + g2
.position
[1] - g1
.position
[1], width
* -0.5);
534 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);
535 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);
541 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
542 glVertex3f (g1
.radius
* cos (alpha
+ phi
), g1
.radius
* sin (alpha
+ phi
), width
* 0.5);
543 glVertex3f (g1
.radius
* cos (alpha
+ phi
), g1
.radius
* sin (alpha
+ phi
), width
* -0.5);
544 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);
545 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);
546 glVertex3f (g1
.radius
* cos (alpha
- phi
), g1
.radius
* sin (alpha
- phi
), width
* 0.5);
547 glVertex3f (g1
.radius
* cos (alpha
- phi
), g1
.radius
* sin (alpha
- phi
), width
* -0.5);
548 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);
549 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);
555 axle_find (char axle_name
[])
559 for (i
= 0; i
< number_of_axles
; i
++)
561 if (!(strcmp (axle_name
, a
[i
].name
)))
569 gear_find (char gear_name
[])
573 for (i
= 0; i
< number_of_gears
; i
++)
575 if (!(strcmp (gear_name
, g
[i
].name
)))
585 GLfloat x
, y
, z
, D
, dist
;
586 GLint axle_index
, i
, j
, g1
, g2
, k
;
589 for (i
= 0; i
< number_of_gears
; i
++)
594 axle_index
= axle_find (g
[i
].axle_name
);
595 g
[i
].axis
= a
[axle_index
].axis
;
596 g
[i
].motored
= a
[axle_index
].motored
;
597 if (a
[axle_index
].motored
)
599 g
[i
].direction
= a
[axle_index
].direction
;
600 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
604 else if (g
[i
].axis
== 1)
609 g
[i
].position
[0] = a
[axle_index
].position
[0] + x
* g
[i
].relative_position
;
610 g
[i
].position
[1] = a
[axle_index
].position
[1] + y
* g
[i
].relative_position
;
611 g
[i
].position
[2] = a
[axle_index
].position
[2] + z
* g
[i
].relative_position
;
614 for (k
= 0; k
< number_of_axles
; k
++)
616 for (i
= 0; i
< number_of_gears
- 1; i
++)
618 for (j
= 0; j
< number_of_gears
; j
++)
620 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
))
622 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));
623 if (D
< 1.1 * (g
[i
].radius
- g
[i
].tooth_depth
+ g
[j
].radius
- g
[j
].tooth_depth
))
625 printf (error
, "Gear %s and %s are too close to each other.", g
[i
].name
, g
[j
].name
);
627 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
633 dist
= g
[i
].position
[0] - g
[j
].position
[0];
635 else if (g
[i
].axis
== 1)
637 dist
= g
[i
].position
[1] - g
[j
].position
[1];
640 dist
= g
[i
].position
[2] - g
[j
].position
[2];
644 if (dist
< (g
[i
].width
/ 2 + g
[j
].width
/ 2))
646 if ((g
[i
].motored
) && (!(g
[j
].motored
)) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
648 axle_index
= axle_find (g
[j
].axle_name
);
649 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
))
651 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
652 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
656 g
[j
].motored
= (a
[axle_index
].motored
= 1);
657 g
[j
].direction
= (a
[axle_index
].direction
= -g
[i
].direction
);
658 a
[axle_index
].angular_velocity
= g
[i
].angular_velocity
* g
[i
].teeth
/ g
[j
].teeth
;
659 g
[j
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[i
].radius
/ g
[j
].radius
);
662 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
664 axle_index
= axle_find (g
[i
].axle_name
);
665 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
))
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);*/
672 g
[i
].motored
= (a
[axle_index
].motored
= 1);
673 g
[i
].direction
= (a
[axle_index
].direction
= -g
[j
].direction
);
674 a
[axle_index
].angular_velocity
= g
[j
].angular_velocity
* g
[j
].teeth
/ g
[i
].teeth
;
675 g
[i
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[j
].radius
/ g
[i
].radius
);
681 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
))
683 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));
684 if ((g
[i
].motored
) && (!(g
[j
].motored
)) && (D
< 0.95 * sqrt (g
[i
].radius
* g
[i
].radius
+ g
[j
].radius
* g
[j
].radius
)))
686 axle_index
= axle_find (g
[j
].axle_name
);
687 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
))
689 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
690 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
693 g
[j
].motored
= (a
[axle_index
].motored
= 1);
694 g
[j
].direction
= (a
[axle_index
].direction
= -g
[i
].direction
);
695 a
[axle_index
].angular_velocity
= g
[i
].angular_velocity
* g
[i
].teeth
/ g
[j
].teeth
;
696 g
[j
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[i
].radius
/ g
[j
].radius
);
700 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * sqrt (g
[i
].radius
* g
[i
].radius
+ g
[j
].radius
* g
[j
].radius
)))
702 axle_index
= axle_find (g
[i
].axle_name
);
703 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
))
705 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
706 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
709 g
[i
].motored
= (a
[axle_index
].motored
= 1);
710 g
[i
].direction
= (a
[axle_index
].direction
= -g
[j
].direction
);
711 a
[axle_index
].angular_velocity
= g
[j
].angular_velocity
* g
[j
].teeth
/ g
[i
].teeth
;
712 g
[i
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[j
].radius
/ g
[i
].radius
);
718 for (i
= 0; i
< number_of_gears
; i
++)
720 axle_index
= axle_find (g
[i
].axle_name
);
721 g
[i
].motored
= a
[axle_index
].motored
;
722 if (a
[axle_index
].motored
)
724 g
[i
].direction
= a
[axle_index
].direction
;
725 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
729 for (i
= 0; i
< number_of_belts
; i
++)
731 g1
= gear_find (b
[i
].gear1_name
);
732 g2
= gear_find (b
[i
].gear2_name
);
733 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));
734 if (!((g
[g1
].axis
== g
[g2
].axis
) && (!strcmp (g
[g1
].type
, g
[g2
].type
)) && (!strcmp (g
[g1
].type
, "NORMAL"))))
736 printf (error
, "Belt %s invalid.", b
[i
].name
);
737 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
741 if ((g
[g1
].axis
== g
[g2
].axis
) && (!strcmp (g
[g1
].type
, g
[g2
].type
)) && (!strcmp (g
[g1
].type
, "NORMAL")))
744 if((g[g1].motored)&&(g[g2].motored))
745 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
747 printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
748 MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
754 dist
= g
[g1
].position
[0] - g
[g2
].position
[0];
756 else if (g
[i
].axis
== 1)
758 dist
= g
[g1
].position
[1] - g
[g2
].position
[1];
761 dist
= g
[g1
].position
[2] - g
[g2
].position
[2];
765 if (dist
> (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
767 printf (error
, "Belt %s invalid.", b
[i
].name
);
768 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
772 if (dist
< (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
774 if (D
< g
[g1
].radius
+ g
[g2
].radius
)
776 printf (error
, "Gears %s and %s too close to be linked with belts", g
[g1
].name
, g
[g2
].name
);
777 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
781 if ((g
[g1
].motored
) && (!(g
[g2
].motored
)))
783 axle_index
= axle_find (g
[g2
].axle_name
);
784 g
[g2
].motored
= (a
[axle_index
].motored
= 1);
785 g
[g2
].direction
= (a
[axle_index
].direction
= g
[g1
].direction
);
786 g
[g2
].angular_velocity
= (a
[axle_index
].angular_velocity
= g
[g1
].angular_velocity
* g
[g1
].radius
/ g
[g2
].radius
);
789 if ((!(g
[g1
].motored
)) && (g
[g2
].motored
))
791 axle_index
= axle_find (g
[g1
].axle_name
);
792 g
[g1
].motored
= (a
[axle_index
].motored
= 1);
793 g
[g1
].direction
= (a
[axle_index
].direction
= g
[g2
].direction
);
794 g
[g1
].angular_velocity
= (a
[axle_index
].angular_velocity
= g
[g2
].angular_velocity
* g
[g2
].radius
/ g
[g1
].radius
);
800 for (i
= 0; i
< number_of_gears
; i
++)
802 axle_index
= axle_find (g
[i
].axle_name
);
803 g
[i
].motored
= a
[axle_index
].motored
;
804 if (a
[axle_index
].motored
)
806 g
[i
].direction
= a
[axle_index
].direction
;
807 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
815 GLfloat view_rotx
= 20.0, view_roty
= 30.0, view_rotz
= 10.0;
825 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
828 glRotatef (view_rotx
, 1.0, 0.0, 0.0);
829 glRotatef (view_roty
, 0.0, 1.0, 0.0);
830 glRotatef (view_rotz
, 0.0, 0.0, 1.0);
832 for (i
= 0; i
< number_of_gears
; i
++)
838 /*glTranslatef( -3.0, -2.0, 0.0 );*/
839 glTranslatef (g
[i
].position
[0], g
[i
].position
[1], g
[i
].position
[2]);
842 else if (g
[i
].axis
== 1)
848 glRotatef (90.0, x
, y
, z
);
850 glRotatef (g
[i
].direction
* g
[i
].angle
, 0.0, 0.0, 1.0);
851 glCallList (g
[i
].id
);
855 for (i
= 0; i
< number_of_axles
; i
++)
861 glTranslatef (a
[i
].position
[0], a
[i
].position
[1], a
[i
].position
[2]);
864 else if (a
[i
].axis
== 1)
870 glRotatef (90.0, x
, y
, z
);
872 glCallList (a
[i
].id
);
876 for (i
= 0; i
< number_of_belts
; i
++)
882 index
= gear_find (b
[i
].gear1_name
);
883 glTranslatef (g
[index
].position
[0], g
[index
].position
[1], g
[index
].position
[2]);
884 if (g
[index
].axis
== 0)
886 else if (g
[index
].axis
== 1)
892 glRotatef (90.0, x
, y
, z
);
894 glCallList (b
[i
].id
);
902 GLint t
= glutGet(GLUT_ELAPSED_TIME
);
904 if (t
- T0
>= 5000) {
905 GLfloat seconds
= (t
- T0
) / 1000.0;
906 GLfloat fps
= Frames
/ seconds
;
907 printf("%d frames in %g seconds = %g FPS\n", Frames
, seconds
, fps
);
920 static double t0
= -1.;
921 double dt
, t
= glutGet(GLUT_ELAPSED_TIME
) / 1000.0;
926 for (i
= 0; i
< number_of_gears
; i
++)
927 g
[i
].angle
+= g
[i
].angular_velocity
* dt
;
934 /* change view angle, exit upon ESC */
936 key (unsigned char k
, int x
, int y
)
966 /* new window size or exposure */
968 reshape (int width
, int height
)
970 glViewport (0, 0, (GLint
) width
, (GLint
) height
);
971 glMatrixMode (GL_PROJECTION
);
975 GLfloat w
= (GLfloat
) width
/ (GLfloat
) height
;
976 glFrustum (-w
, w
, -1.0, 1.0, 5.0, 60.0);
980 GLfloat h
= (GLfloat
) height
/ (GLfloat
) width
;
981 glFrustum (-1.0, 1.0, -h
, h
, 5.0, 60.0);
984 glMatrixMode (GL_MODELVIEW
);
986 glTranslatef (0.0, 0.0, -40.0);
987 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
995 GLfloat matShine
= 20.00F
;
996 GLfloat light0Pos
[4] =
998 0.70F
, 0.70F
, 1.25F
, 0.50F
1002 glClearColor (background
[0], background
[1], background
[2], 1.0F
);
1003 glClearIndex ((GLfloat
) 0.0);
1005 glMaterialf (GL_FRONT_AND_BACK
, GL_SHININESS
, matShine
);
1006 glLightfv (GL_LIGHT0
, GL_POSITION
, light0Pos
);
1007 glEnable (GL_LIGHT0
);
1009 glEnable (GL_LIGHTING
);
1010 glEnable (GL_DEPTH_TEST
);
1011 for (i
= 0; i
< number_of_gears
; i
++)
1014 for (i
= 0; i
< number_of_gears
; i
++)
1016 g
[i
].id
= glGenLists (1);
1017 glNewList (g
[i
].id
, GL_COMPILE
);
1018 glColor3fv (g
[i
].color
);
1019 glMaterialfv (GL_FRONT
, GL_SPECULAR
, g
[i
].color
);
1020 gear (i
, g
[i
].type
, g
[i
].radius
, g
[i
].width
, g
[i
].teeth
, g
[i
].tooth_depth
);
1024 for (i
= 0; i
< number_of_axles
; i
++)
1026 a
[i
].id
= glGenLists (1);
1027 glNewList (a
[i
].id
, GL_COMPILE
);
1028 glColor3fv (a
[i
].color
);
1029 glMaterialfv (GL_FRONT
, GL_SPECULAR
, a
[i
].color
);
1030 axle (i
, a
[i
].radius
, a
[i
].length
);
1034 for (i
= 0; i
< number_of_belts
; i
++)
1036 b
[i
].id
= glGenLists (1);
1037 glNewList (b
[i
].id
, GL_COMPILE
);
1038 belt (g
[gear_find (b
[i
].gear1_name
)], g
[gear_find (b
[i
].gear2_name
)]);
1042 glEnable (GL_COLOR_MATERIAL
);
1048 main (int argc
, char *argv
[])
1052 glutInitWindowSize(640,480);
1053 glutInit(&argc
, argv
);
1054 glutInitDisplayMode (GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
1056 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE
)
1060 file
= "geartrain.dat";
1068 glutDisplayFunc (draw
);
1069 glutReshapeFunc (reshape
);
1070 glutKeyboardFunc (key
);
1071 glutIdleFunc (idle
);