c612ad74bf0ffa54d0324462aae489eb9523635f
1 /* $Id: geartrain.c,v 1.7 2000/11/30 01:44:24 gareth Exp $ */
4 * GearTrain Simulator * Version: 1.00
6 * Copyright (C) 1999 Shobhan Kumar Dutta All Rights Reserved.
7 * <skdutta@del3.vsnl.net.in>
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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
35 #define min(x, y) ( x < y ? x : y )
38 #define M_PI 3.14159265
40 typedef GLfloat TDA
[4];
55 GLfloat angular_velocity
;
71 GLfloat angular_velocity
;
73 GLint relative_position
;
100 char Buf1
[256], Buf2
[256], Buf3
[256], Buf4
[256], Buf5
[256];
103 static GLint Frames
= 0;
107 strset (char buf
[], char ch
)
110 for (i
= 0; i
< strlen (buf
); i
++)
130 fscanf (mainfile
, "%s %s %s %s", Buf1
, Buf2
, Buf3
, Buf4
);
141 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
150 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
159 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
165 getdata (char filename
[])
167 int gear_count
= 0, axle_count
= 0, belt_count
= 0, i
;
169 mainfile
= fopen (filename
, "r");
171 printf("Error: couldn't open %s\n", filename
);
178 fscanf (mainfile
, "%s", Buf1
);
179 if (ferror (mainfile
))
181 printf ("\nError opening file !\n");
185 if (!(strcmp (Buf1
, "BACKGROUND")))
186 LoadTriplet (background
);
188 if (!(strcmp (Buf1
, "ANAME")))
190 LoadText (a
[axle_count
].name
);
194 if (!(strcmp (Buf1
, "ARADIUS")))
195 LoadReal (&a
[axle_count
- 1].radius
);
197 if (!(strcmp (Buf1
, "AAXIS")))
198 LoadInteger (&a
[axle_count
- 1].axis
);
200 if (!(strcmp (Buf1
, "ACOLOR")))
201 LoadTriplet (a
[axle_count
- 1].color
);
203 if (!(strcmp (Buf1
, "APOSITION")))
204 LoadTriplet (a
[axle_count
- 1].position
);
206 if (!(strcmp (Buf1
, "ALENGTH")))
207 LoadReal (&a
[axle_count
- 1].length
);
209 if (!(strcmp (Buf1
, "AMOTORED")))
210 LoadInteger (&a
[axle_count
- 1].motored
);
212 if (!(strcmp (Buf1
, "AANGULARVELOCITY")))
213 LoadReal (&a
[axle_count
- 1].angular_velocity
);
215 if (!(strcmp (Buf1
, "ADIRECTION")))
216 LoadInteger (&a
[axle_count
- 1].direction
);
218 if (!(strcmp (Buf1
, "GNAME")))
220 LoadText (g
[gear_count
].name
);
224 if (!(strcmp (Buf1
, "GTYPE")))
225 LoadText (g
[gear_count
- 1].type
);
227 if (!(strcmp (Buf1
, "GFACE")))
228 LoadInteger (&g
[gear_count
- 1].face
);
230 if (!(strcmp (Buf1
, "GRADIUS")))
231 LoadReal (&g
[gear_count
- 1].radius
);
233 if (!(strcmp (Buf1
, "GWIDTH")))
234 LoadReal (&g
[gear_count
- 1].width
);
236 if (!(strcmp (Buf1
, "GTEETH")))
237 LoadInteger (&g
[gear_count
- 1].teeth
);
239 if (!(strcmp (Buf1
, "GTOOTHDEPTH")))
240 LoadReal (&g
[gear_count
- 1].tooth_depth
);
242 if (!(strcmp (Buf1
, "GCOLOR")))
243 LoadTriplet (g
[gear_count
- 1].color
);
245 if (!(strcmp (Buf1
, "GAXLE")))
246 LoadText (g
[gear_count
- 1].axle_name
);
248 if (!(strcmp (Buf1
, "GPOSITION")))
249 LoadInteger (&g
[gear_count
- 1].relative_position
);
251 if (!(strcmp (Buf1
, "BELTNAME")))
253 LoadText (b
[belt_count
].name
);
257 if (!(strcmp (Buf1
, "GEAR1NAME")))
258 LoadText (b
[belt_count
- 1].gear1_name
);
260 if (!(strcmp (Buf1
, "GEAR2NAME")))
261 LoadText (b
[belt_count
- 1].gear2_name
);
264 while (Buf1
[0] != 0);
266 for (i
= 0; i
< number_of_gears
; i
++)
270 g
[i
].angular_velocity
= 0.0;
273 number_of_gears
= gear_count
;
274 number_of_axles
= axle_count
;
275 number_of_belts
= belt_count
;
281 axle (GLint j
, GLfloat radius
, GLfloat length
)
283 GLfloat angle
, rad
, incr
= 10.0 * M_PI
/ 180.0;
285 /* draw main cylinder */
287 for (angle
= 0.0; angle
< 360.0; angle
+= 5.0)
289 rad
= angle
* M_PI
/ 180.0;
290 glNormal3f (cos (rad
), sin (rad
), 0.0);
291 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), length
/ 2);
292 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), -length
/ 2);
293 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), -length
/ 2);
294 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), length
/ 2);
298 /* draw front face */
299 glNormal3f (0.0, 0.0, 1.0);
300 glBegin (GL_TRIANGLES
);
301 for (angle
= 0.0; angle
< 360.0; angle
+= 5.0)
303 rad
= angle
* M_PI
/ 180.0;
304 glVertex3f (0.0, 0.0, length
/ 2);
305 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), length
/ 2);
306 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), length
/ 2);
307 glVertex3f (0.0, 0.0, length
/ 2);
312 glNormal3f (0.0, 0.0, -1.0);
313 glBegin (GL_TRIANGLES
);
314 for (angle
= 0.0; angle
<= 360.0; angle
+= 5.0)
316 rad
= angle
* M_PI
/ 180.0;
317 glVertex3f (0.0, 0.0, -length
/ 2);
318 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), -length
/ 2);
319 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), -length
/ 2);
320 glVertex3f (0.0, 0.0, -length
/ 2);
328 gear (GLint j
, char type
[], GLfloat radius
, GLfloat width
,
329 GLint teeth
, GLfloat tooth_depth
)
334 GLfloat u
, v
, len
, fraction
= 0.5;
337 r1
= radius
- tooth_depth
;
340 da
= 2.0 * M_PI
/ teeth
/ 4.0;
346 if (!(strcmp (type
, "NORMAL")))
352 /* draw front face */
353 if (!(strcmp (type
, "NORMAL")))
355 glNormal3f (0.0, 0.0, 1.0 * n
);
356 glBegin (GL_QUAD_STRIP
);
357 for (i
= 0; i
<= teeth
; i
++)
359 angle
= i
* 2.0 * M_PI
/ teeth
;
360 glVertex3f (0.0, 0.0, width
* fraction
);
361 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
362 glVertex3f (0.0, 0.0, width
* fraction
);
363 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
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 ((r2
- width
) * cos (angle
), (r2
- width
) * sin (angle
), width
* fraction
);
376 glVertex3f (0.0, 0.0, width
* fraction
);
377 glVertex3f ((r2
- width
) * cos (angle
+ 3 * da
), (r2
- width
) * sin (angle
+ 3 * da
), width
* fraction
);
382 /* draw front sides of teeth */
383 if (!(strcmp (type
, "NORMAL")))
385 glNormal3f (0.0, 0.0, 1.0 * n
);
387 da
= 2.0 * M_PI
/ teeth
/ 4.0;
388 for (i
= 0; i
< teeth
; i
++)
390 angle
= i
* 2.0 * M_PI
/ teeth
;
391 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
392 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), width
* fraction
);
393 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), width
* fraction
);
394 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
399 glNormal3f (0.0, 0.0, -1.0 * n
);
402 glBegin (GL_QUAD_STRIP
);
403 for (i
= 0; i
<= teeth
; i
++)
405 angle
= i
* 2.0 * M_PI
/ teeth
;
406 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
407 glVertex3f (0.0, 0.0, -width
* fraction
);
408 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
409 glVertex3f (0.0, 0.0, -width
* fraction
);
413 /* draw back sides of teeth */
414 glNormal3f (0.0, 0.0, -1.0 * n
);
416 da
= 2.0 * M_PI
/ teeth
/ 4.0;
417 for (i
= 0; i
< teeth
; i
++)
419 angle
= i
* 2.0 * M_PI
/ teeth
;
420 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
421 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
422 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
423 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
428 /* draw outward faces of teeth */
429 if (!(strcmp (type
, "NORMAL")))
431 glBegin (GL_QUAD_STRIP
);
432 for (i
= 0; i
< teeth
; i
++)
434 angle
= i
* 2.0 * M_PI
/ teeth
;
436 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
437 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
438 u
= r2
* cos (angle
+ da
) - r1
* cos (angle
);
439 v
= r2
* sin (angle
+ da
) - r1
* sin (angle
);
440 len
= sqrt (u
* u
+ v
* v
);
443 glNormal3f (v
, -u
, 0.0);
444 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), width
* fraction
);
445 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
446 glNormal3f (cos (angle
), sin (angle
), 0.0);
447 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), width
* fraction
);
448 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
449 u
= r1
* cos (angle
+ 3 * da
) - r2
* cos (angle
+ 2 * da
);
450 v
= r1
* sin (angle
+ 3 * da
) - r2
* sin (angle
+ 2 * da
);
451 glNormal3f (v
, -u
, 0.0);
452 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
453 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
454 glNormal3f (cos (angle
), sin (angle
), 0.0);
459 glBegin (GL_QUAD_STRIP
);
460 for (i
= 0; i
< teeth
; i
++)
462 angle
= i
* 2.0 * M_PI
/ teeth
;
463 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
464 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
465 u
= r2
* cos (angle
+ da
) - r1
* cos (angle
);
466 v
= r2
* sin (angle
+ da
) - r1
* sin (angle
);
467 len
= sqrt (u
* u
+ v
* v
);
470 glNormal3f (v
, -u
, 0.0);
471 glVertex3f ((r2
- width
) * cos (angle
+ da
), (r2
- width
) * sin (angle
+ da
), width
* fraction
);
472 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
473 glNormal3f (cos (angle
), sin (angle
), n
);
474 glVertex3f ((r2
- width
) * cos (angle
+ 2 * da
), (r2
- width
) * sin (angle
+ 2 * da
), width
* fraction
);
475 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
476 u
= r1
* cos (angle
+ 3 * da
) - r2
* cos (angle
+ 2 * da
);
477 v
= r1
* sin (angle
+ 3 * da
) - r2
* sin (angle
+ 2 * da
);
478 glNormal3f (v
, -u
, 0.0);
479 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
480 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
481 glNormal3f (cos (angle
), sin (angle
), n
);
485 glVertex3f (r1
* cos (0), r1
* sin (0), width
* fraction
);
486 glVertex3f (r1
* cos (0), r1
* sin (0), -width
* fraction
);
492 belt (struct GEAR g1
, struct GEAR g2
)
494 GLfloat D
, alpha
, phi
, angle
, incr
, width
;
505 width
= min (g1
.width
, g2
.width
);
506 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));
507 alpha
= acos ((g2
.position
[0] - g1
.position
[0]) / D
);
508 phi
= acos ((g1
.radius
- g2
.radius
) / D
);
511 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
512 incr
= 1.2 * 360.0 / g1
.teeth
* M_PI
/ 180.00;
513 for (angle
= alpha
+ phi
; angle
<= 2 * M_PI
- phi
+ alpha
; angle
+= 360.0 / g1
.teeth
* M_PI
/ 180.00)
515 glNormal3f (cos (angle
), sin (angle
), 0.0);
516 glVertex3f (g1
.radius
* cos (angle
), g1
.radius
* sin (angle
), width
* 0.5);
517 glVertex3f (g1
.radius
* cos (angle
), g1
.radius
* sin (angle
), -width
* 0.5);
518 glVertex3f (g1
.radius
* cos (angle
+ incr
), g1
.radius
* sin (angle
+ incr
), -width
* 0.5);
519 glVertex3f (g1
.radius
* cos (angle
+ incr
), g1
.radius
* sin (angle
+ incr
), width
* 0.5);
524 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
525 incr
= 1.2 * 360.0 / g2
.teeth
* M_PI
/ 180.00;
526 for (angle
= -phi
+ alpha
; angle
<= phi
+ alpha
; angle
+= 360.0 / g1
.teeth
* M_PI
/ 180.0)
528 glNormal3f (cos (angle
), sin (angle
), 0.0);
529 glVertex3f (g2
.radius
* cos (angle
) + g2
.position
[0] - g1
.position
[0], g2
.radius
* sin (angle
) + g2
.position
[1] - g1
.position
[1], width
* 0.5);
530 glVertex3f (g2
.radius
* cos (angle
) + g2
.position
[0] - g1
.position
[0], g2
.radius
* sin (angle
) + g2
.position
[1] - g1
.position
[1], width
* -0.5);
531 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);
532 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 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
539 glVertex3f (g1
.radius
* cos (alpha
+ phi
), g1
.radius
* sin (alpha
+ phi
), width
* 0.5);
540 glVertex3f (g1
.radius
* cos (alpha
+ phi
), g1
.radius
* sin (alpha
+ phi
), width
* -0.5);
541 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);
542 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);
543 glVertex3f (g1
.radius
* cos (alpha
- phi
), g1
.radius
* sin (alpha
- phi
), width
* 0.5);
544 glVertex3f (g1
.radius
* cos (alpha
- phi
), g1
.radius
* sin (alpha
- phi
), 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 (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 axle_find (char axle_name
[])
556 for (i
= 0; i
< number_of_axles
; i
++)
558 if (!(strcmp (axle_name
, a
[i
].name
)))
566 gear_find (char gear_name
[])
570 for (i
= 0; i
< number_of_gears
; i
++)
572 if (!(strcmp (gear_name
, g
[i
].name
)))
582 GLfloat x
, y
, z
, D
, dist
;
583 GLint axle_index
, i
, j
, g1
, g2
, k
;
586 for (i
= 0; i
< number_of_gears
; i
++)
591 axle_index
= axle_find (g
[i
].axle_name
);
592 g
[i
].axis
= a
[axle_index
].axis
;
593 g
[i
].motored
= a
[axle_index
].motored
;
594 if (a
[axle_index
].motored
)
596 g
[i
].direction
= a
[axle_index
].direction
;
597 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
601 else if (g
[i
].axis
== 1)
606 g
[i
].position
[0] = a
[axle_index
].position
[0] + x
* g
[i
].relative_position
;
607 g
[i
].position
[1] = a
[axle_index
].position
[1] + y
* g
[i
].relative_position
;
608 g
[i
].position
[2] = a
[axle_index
].position
[2] + z
* g
[i
].relative_position
;
611 for (k
= 0; k
< number_of_axles
; k
++)
613 for (i
= 0; i
< number_of_gears
- 1; i
++)
615 for (j
= 0; j
< number_of_gears
; j
++)
617 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
))
619 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));
620 if (D
< 1.1 * (g
[i
].radius
- g
[i
].tooth_depth
+ g
[j
].radius
- g
[j
].tooth_depth
))
622 printf (error
, "Gear %s and %s are too close to each other.", g
[i
].name
, g
[j
].name
);
624 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
630 dist
= g
[i
].position
[0] - g
[j
].position
[0];
632 else if (g
[i
].axis
== 1)
634 dist
= g
[i
].position
[1] - g
[j
].position
[1];
637 dist
= g
[i
].position
[2] - g
[j
].position
[2];
641 if (dist
< (g
[i
].width
/ 2 + g
[j
].width
/ 2))
643 if ((g
[i
].motored
) && (!(g
[j
].motored
)) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
645 axle_index
= axle_find (g
[j
].axle_name
);
646 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
))
648 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
649 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
653 g
[j
].motored
= (a
[axle_index
].motored
= 1);
654 g
[j
].direction
= (a
[axle_index
].direction
= -g
[i
].direction
);
655 a
[axle_index
].angular_velocity
= g
[i
].angular_velocity
* g
[i
].teeth
/ g
[j
].teeth
;
656 g
[j
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[i
].radius
/ g
[j
].radius
);
659 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
661 axle_index
= axle_find (g
[i
].axle_name
);
662 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
))
664 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
665 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
669 g
[i
].motored
= (a
[axle_index
].motored
= 1);
670 g
[i
].direction
= (a
[axle_index
].direction
= -g
[j
].direction
);
671 a
[axle_index
].angular_velocity
= g
[j
].angular_velocity
* g
[j
].teeth
/ g
[i
].teeth
;
672 g
[i
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[j
].radius
/ g
[i
].radius
);
678 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
))
680 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));
681 if ((g
[i
].motored
) && (!(g
[j
].motored
)) && (D
< 0.95 * sqrt (g
[i
].radius
* g
[i
].radius
+ g
[j
].radius
* g
[j
].radius
)))
683 axle_index
= axle_find (g
[j
].axle_name
);
684 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
))
686 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
687 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
690 g
[j
].motored
= (a
[axle_index
].motored
= 1);
691 g
[j
].direction
= (a
[axle_index
].direction
= -g
[i
].direction
);
692 a
[axle_index
].angular_velocity
= g
[i
].angular_velocity
* g
[i
].teeth
/ g
[j
].teeth
;
693 g
[j
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[i
].radius
/ g
[j
].radius
);
697 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * sqrt (g
[i
].radius
* g
[i
].radius
+ g
[j
].radius
* g
[j
].radius
)))
699 axle_index
= axle_find (g
[i
].axle_name
);
700 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
))
702 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
703 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
706 g
[i
].motored
= (a
[axle_index
].motored
= 1);
707 g
[i
].direction
= (a
[axle_index
].direction
= -g
[j
].direction
);
708 a
[axle_index
].angular_velocity
= g
[j
].angular_velocity
* g
[j
].teeth
/ g
[i
].teeth
;
709 g
[i
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[j
].radius
/ g
[i
].radius
);
715 for (i
= 0; i
< number_of_gears
; i
++)
717 axle_index
= axle_find (g
[i
].axle_name
);
718 g
[i
].motored
= a
[axle_index
].motored
;
719 if (a
[axle_index
].motored
)
721 g
[i
].direction
= a
[axle_index
].direction
;
722 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
726 for (i
= 0; i
< number_of_belts
; i
++)
728 g1
= gear_find (b
[i
].gear1_name
);
729 g2
= gear_find (b
[i
].gear2_name
);
730 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));
731 if (!((g
[g1
].axis
== g
[g2
].axis
) && (!strcmp (g
[g1
].type
, g
[g2
].type
)) && (!strcmp (g
[g1
].type
, "NORMAL"))))
733 printf (error
, "Belt %s invalid.", b
[i
].name
);
734 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
738 if ((g
[g1
].axis
== g
[g2
].axis
) && (!strcmp (g
[g1
].type
, g
[g2
].type
)) && (!strcmp (g
[g1
].type
, "NORMAL")))
741 if((g[g1].motored)&&(g[g2].motored))
742 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
744 printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
745 MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
751 dist
= g
[g1
].position
[0] - g
[g2
].position
[0];
753 else if (g
[i
].axis
== 1)
755 dist
= g
[g1
].position
[1] - g
[g2
].position
[1];
758 dist
= g
[g1
].position
[2] - g
[g2
].position
[2];
762 if (dist
> (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
764 printf (error
, "Belt %s invalid.", b
[i
].name
);
765 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
769 if (dist
< (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
771 if (D
< g
[g1
].radius
+ g
[g2
].radius
)
773 printf (error
, "Gears %s and %s too close to be linked with belts", g
[g1
].name
, g
[g2
].name
);
774 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
778 if ((g
[g1
].motored
) && (!(g
[g2
].motored
)))
780 axle_index
= axle_find (g
[g2
].axle_name
);
781 g
[g2
].motored
= (a
[axle_index
].motored
= 1);
782 g
[g2
].direction
= (a
[axle_index
].direction
= g
[g1
].direction
);
783 g
[g2
].angular_velocity
= (a
[axle_index
].angular_velocity
= g
[g1
].angular_velocity
* g
[g1
].radius
/ g
[g2
].radius
);
786 if ((!(g
[g1
].motored
)) && (g
[g2
].motored
))
788 axle_index
= axle_find (g
[g1
].axle_name
);
789 g
[g1
].motored
= (a
[axle_index
].motored
= 1);
790 g
[g1
].direction
= (a
[axle_index
].direction
= g
[g2
].direction
);
791 g
[g1
].angular_velocity
= (a
[axle_index
].angular_velocity
= g
[g2
].angular_velocity
* g
[g2
].radius
/ g
[g1
].radius
);
797 for (i
= 0; i
< number_of_gears
; i
++)
799 axle_index
= axle_find (g
[i
].axle_name
);
800 g
[i
].motored
= a
[axle_index
].motored
;
801 if (a
[axle_index
].motored
)
803 g
[i
].direction
= a
[axle_index
].direction
;
804 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
812 GLfloat view_rotx
= 20.0, view_roty
= 30.0, view_rotz
= 10.0;
822 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
825 glRotatef (view_rotx
, 1.0, 0.0, 0.0);
826 glRotatef (view_roty
, 0.0, 1.0, 0.0);
827 glRotatef (view_rotz
, 0.0, 0.0, 1.0);
829 for (i
= 0; i
< number_of_gears
; i
++)
835 /*glTranslatef( -3.0, -2.0, 0.0 );*/
836 glTranslatef (g
[i
].position
[0], g
[i
].position
[1], g
[i
].position
[2]);
839 else if (g
[i
].axis
== 1)
845 glRotatef (90.0, x
, y
, z
);
847 glRotatef (g
[i
].direction
* g
[i
].angle
, 0.0, 0.0, 1.0);
848 glCallList (g
[i
].id
);
852 for (i
= 0; i
< number_of_axles
; i
++)
858 glTranslatef (a
[i
].position
[0], a
[i
].position
[1], a
[i
].position
[2]);
861 else if (a
[i
].axis
== 1)
867 glRotatef (90.0, x
, y
, z
);
869 glCallList (a
[i
].id
);
873 for (i
= 0; i
< number_of_belts
; i
++)
879 index
= gear_find (b
[i
].gear1_name
);
880 glTranslatef (g
[index
].position
[0], g
[index
].position
[1], g
[index
].position
[2]);
881 if (g
[index
].axis
== 0)
883 else if (g
[index
].axis
== 1)
889 glRotatef (90.0, x
, y
, z
);
891 glCallList (b
[i
].id
);
899 GLint t
= glutGet(GLUT_ELAPSED_TIME
);
901 if (t
- T0
>= 5000) {
902 GLfloat seconds
= (t
- T0
) / 1000.0;
903 GLfloat fps
= Frames
/ seconds
;
904 printf("%d frames in %g seconds = %g FPS\n", Frames
, seconds
, fps
);
918 for (i
= 0; i
< number_of_gears
; i
++)
919 g
[i
].angle
+= g
[i
].angular_velocity
;
926 /* change view angle, exit upon ESC */
928 key (unsigned char k
, int x
, int y
)
958 /* new window size or exposure */
960 reshape (int width
, int height
)
962 glViewport (0, 0, (GLint
) width
, (GLint
) height
);
963 glMatrixMode (GL_PROJECTION
);
967 GLfloat w
= (GLfloat
) width
/ (GLfloat
) height
;
968 glFrustum (-w
, w
, -1.0, 1.0, 5.0, 60.0);
972 GLfloat h
= (GLfloat
) height
/ (GLfloat
) width
;
973 glFrustum (-1.0, 1.0, -h
, h
, 5.0, 60.0);
976 glMatrixMode (GL_MODELVIEW
);
978 glTranslatef (0.0, 0.0, -40.0);
979 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
987 GLfloat matShine
= 20.00F
;
988 GLfloat light0Pos
[4] =
990 0.70F
, 0.70F
, 1.25F
, 0.50F
994 glClearColor (background
[0], background
[1], background
[2], 1.0F
);
995 glClearIndex ((GLfloat
) 0.0);
997 glMaterialf (GL_FRONT_AND_BACK
, GL_SHININESS
, matShine
);
998 glLightfv (GL_LIGHT0
, GL_POSITION
, light0Pos
);
999 glEnable (GL_LIGHT0
);
1001 glEnable (GL_LIGHTING
);
1002 glEnable (GL_DEPTH_TEST
);
1003 for (i
= 0; i
< number_of_gears
; i
++)
1006 for (i
= 0; i
< number_of_gears
; i
++)
1008 g
[i
].id
= glGenLists (1);
1009 glNewList (g
[i
].id
, GL_COMPILE
);
1010 glColor3fv (g
[i
].color
);
1011 glMaterialfv (GL_FRONT
, GL_SPECULAR
, g
[i
].color
);
1012 gear (i
, g
[i
].type
, g
[i
].radius
, g
[i
].width
, g
[i
].teeth
, g
[i
].tooth_depth
);
1016 for (i
= 0; i
< number_of_axles
; i
++)
1018 a
[i
].id
= glGenLists (1);
1019 glNewList (a
[i
].id
, GL_COMPILE
);
1020 glColor3fv (a
[i
].color
);
1021 glMaterialfv (GL_FRONT
, GL_SPECULAR
, a
[i
].color
);
1022 axle (i
, a
[i
].radius
, a
[i
].length
);
1026 for (i
= 0; i
< number_of_belts
; i
++)
1028 b
[i
].id
= glGenLists (1);
1029 glNewList (b
[i
].id
, GL_COMPILE
);
1030 belt (g
[gear_find (b
[i
].gear1_name
)], g
[gear_find (b
[i
].gear2_name
)]);
1034 glEnable (GL_COLOR_MATERIAL
);
1040 main (int argc
, char *argv
[])
1045 file
= "geartrain.dat";
1049 glutInitWindowPosition (0, 0);
1050 glutInitWindowSize(640,480);
1051 glutInitDisplayMode (GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
1053 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE
)
1060 glutDisplayFunc (draw
);
1061 glutReshapeFunc (reshape
);
1062 glutKeyboardFunc (key
);
1063 glutIdleFunc (idle
);