1 /* $Id: geartrain.c,v 1.6 2000/04/06 02:22:59 brianp 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];
104 strset (char buf
[], char ch
)
107 for (i
= 0; i
< strlen (buf
); i
++)
127 fscanf (mainfile
, "%s %s %s %s", Buf1
, Buf2
, Buf3
, Buf4
);
138 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
147 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
156 fscanf (mainfile
, "%s %s", Buf1
, Buf2
);
162 getdata (char filename
[])
164 int gear_count
= 0, axle_count
= 0, belt_count
= 0, i
;
166 mainfile
= fopen (filename
, "r");
168 printf("Error: couldn't open %s\n", filename
);
175 fscanf (mainfile
, "%s", Buf1
);
176 if (ferror (mainfile
))
178 printf ("\nError opening file !\n");
182 if (!(strcmp (Buf1
, "BACKGROUND")))
183 LoadTriplet (background
);
185 if (!(strcmp (Buf1
, "ANAME")))
187 LoadText (a
[axle_count
].name
);
191 if (!(strcmp (Buf1
, "ARADIUS")))
192 LoadReal (&a
[axle_count
- 1].radius
);
194 if (!(strcmp (Buf1
, "AAXIS")))
195 LoadInteger (&a
[axle_count
- 1].axis
);
197 if (!(strcmp (Buf1
, "ACOLOR")))
198 LoadTriplet (a
[axle_count
- 1].color
);
200 if (!(strcmp (Buf1
, "APOSITION")))
201 LoadTriplet (a
[axle_count
- 1].position
);
203 if (!(strcmp (Buf1
, "ALENGTH")))
204 LoadReal (&a
[axle_count
- 1].length
);
206 if (!(strcmp (Buf1
, "AMOTORED")))
207 LoadInteger (&a
[axle_count
- 1].motored
);
209 if (!(strcmp (Buf1
, "AANGULARVELOCITY")))
210 LoadReal (&a
[axle_count
- 1].angular_velocity
);
212 if (!(strcmp (Buf1
, "ADIRECTION")))
213 LoadInteger (&a
[axle_count
- 1].direction
);
215 if (!(strcmp (Buf1
, "GNAME")))
217 LoadText (g
[gear_count
].name
);
221 if (!(strcmp (Buf1
, "GTYPE")))
222 LoadText (g
[gear_count
- 1].type
);
224 if (!(strcmp (Buf1
, "GFACE")))
225 LoadInteger (&g
[gear_count
- 1].face
);
227 if (!(strcmp (Buf1
, "GRADIUS")))
228 LoadReal (&g
[gear_count
- 1].radius
);
230 if (!(strcmp (Buf1
, "GWIDTH")))
231 LoadReal (&g
[gear_count
- 1].width
);
233 if (!(strcmp (Buf1
, "GTEETH")))
234 LoadInteger (&g
[gear_count
- 1].teeth
);
236 if (!(strcmp (Buf1
, "GTOOTHDEPTH")))
237 LoadReal (&g
[gear_count
- 1].tooth_depth
);
239 if (!(strcmp (Buf1
, "GCOLOR")))
240 LoadTriplet (g
[gear_count
- 1].color
);
242 if (!(strcmp (Buf1
, "GAXLE")))
243 LoadText (g
[gear_count
- 1].axle_name
);
245 if (!(strcmp (Buf1
, "GPOSITION")))
246 LoadInteger (&g
[gear_count
- 1].relative_position
);
248 if (!(strcmp (Buf1
, "BELTNAME")))
250 LoadText (b
[belt_count
].name
);
254 if (!(strcmp (Buf1
, "GEAR1NAME")))
255 LoadText (b
[belt_count
- 1].gear1_name
);
257 if (!(strcmp (Buf1
, "GEAR2NAME")))
258 LoadText (b
[belt_count
- 1].gear2_name
);
261 while (Buf1
[0] != 0);
263 for (i
= 0; i
< number_of_gears
; i
++)
267 g
[i
].angular_velocity
= 0.0;
270 number_of_gears
= gear_count
;
271 number_of_axles
= axle_count
;
272 number_of_belts
= belt_count
;
278 axle (GLint j
, GLfloat radius
, GLfloat length
)
280 GLfloat angle
, rad
, incr
= 10.0 * M_PI
/ 180.0;
282 /* draw main cylinder */
284 for (angle
= 0.0; angle
< 360.0; angle
+= 5.0)
286 rad
= angle
* M_PI
/ 180.0;
287 glNormal3f (cos (rad
), sin (rad
), 0.0);
288 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), length
/ 2);
289 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), -length
/ 2);
290 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), -length
/ 2);
291 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), length
/ 2);
295 /* draw front face */
296 glNormal3f (0.0, 0.0, 1.0);
297 glBegin (GL_TRIANGLES
);
298 for (angle
= 0.0; angle
< 360.0; angle
+= 5.0)
300 rad
= angle
* M_PI
/ 180.0;
301 glVertex3f (0.0, 0.0, length
/ 2);
302 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), length
/ 2);
303 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), length
/ 2);
304 glVertex3f (0.0, 0.0, length
/ 2);
309 glNormal3f (0.0, 0.0, -1.0);
310 glBegin (GL_TRIANGLES
);
311 for (angle
= 0.0; angle
<= 360.0; angle
+= 5.0)
313 rad
= angle
* M_PI
/ 180.0;
314 glVertex3f (0.0, 0.0, -length
/ 2);
315 glVertex3f (radius
* cos (rad
), radius
* sin (rad
), -length
/ 2);
316 glVertex3f (radius
* cos (rad
+ incr
), radius
* sin (rad
+ incr
), -length
/ 2);
317 glVertex3f (0.0, 0.0, -length
/ 2);
325 gear (GLint j
, char type
[], GLfloat radius
, GLfloat width
,
326 GLint teeth
, GLfloat tooth_depth
)
331 GLfloat u
, v
, len
, fraction
= 0.5;
334 r1
= radius
- tooth_depth
;
337 da
= 2.0 * M_PI
/ teeth
/ 4.0;
343 if (!(strcmp (type
, "NORMAL")))
349 /* draw front face */
350 if (!(strcmp (type
, "NORMAL")))
352 glNormal3f (0.0, 0.0, 1.0 * n
);
353 glBegin (GL_QUAD_STRIP
);
354 for (i
= 0; i
<= teeth
; i
++)
356 angle
= i
* 2.0 * M_PI
/ teeth
;
357 glVertex3f (0.0, 0.0, width
* fraction
);
358 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
359 glVertex3f (0.0, 0.0, width
* fraction
);
360 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
366 glNormal3f (0.0, 0.0, 1.0 * n
);
367 glBegin (GL_QUAD_STRIP
);
368 for (i
= 0; i
<= teeth
; i
++)
370 angle
= i
* 2.0 * M_PI
/ teeth
;
371 glVertex3f (0.0, 0.0, width
* fraction
);
372 glVertex3f ((r2
- width
) * cos (angle
), (r2
- width
) * sin (angle
), width
* fraction
);
373 glVertex3f (0.0, 0.0, width
* fraction
);
374 glVertex3f ((r2
- width
) * cos (angle
+ 3 * da
), (r2
- width
) * sin (angle
+ 3 * da
), width
* fraction
);
379 /* draw front sides of teeth */
380 if (!(strcmp (type
, "NORMAL")))
382 glNormal3f (0.0, 0.0, 1.0 * n
);
384 da
= 2.0 * M_PI
/ teeth
/ 4.0;
385 for (i
= 0; i
< teeth
; i
++)
387 angle
= i
* 2.0 * M_PI
/ teeth
;
388 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
389 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), width
* fraction
);
390 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), width
* fraction
);
391 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
396 glNormal3f (0.0, 0.0, -1.0 * n
);
399 glBegin (GL_QUAD_STRIP
);
400 for (i
= 0; i
<= teeth
; i
++)
402 angle
= i
* 2.0 * M_PI
/ teeth
;
403 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
404 glVertex3f (0.0, 0.0, -width
* fraction
);
405 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
406 glVertex3f (0.0, 0.0, -width
* fraction
);
410 /* draw back sides of teeth */
411 glNormal3f (0.0, 0.0, -1.0 * n
);
413 da
= 2.0 * M_PI
/ teeth
/ 4.0;
414 for (i
= 0; i
< teeth
; i
++)
416 angle
= i
* 2.0 * M_PI
/ teeth
;
417 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
418 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
419 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
420 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
425 /* draw outward faces of teeth */
426 if (!(strcmp (type
, "NORMAL")))
428 glBegin (GL_QUAD_STRIP
);
429 for (i
= 0; i
< teeth
; i
++)
431 angle
= i
* 2.0 * M_PI
/ teeth
;
433 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
434 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
435 u
= r2
* cos (angle
+ da
) - r1
* cos (angle
);
436 v
= r2
* sin (angle
+ da
) - r1
* sin (angle
);
437 len
= sqrt (u
* u
+ v
* v
);
440 glNormal3f (v
, -u
, 0.0);
441 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), width
* fraction
);
442 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
443 glNormal3f (cos (angle
), sin (angle
), 0.0);
444 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), width
* fraction
);
445 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
446 u
= r1
* cos (angle
+ 3 * da
) - r2
* cos (angle
+ 2 * da
);
447 v
= r1
* sin (angle
+ 3 * da
) - r2
* sin (angle
+ 2 * da
);
448 glNormal3f (v
, -u
, 0.0);
449 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
450 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
451 glNormal3f (cos (angle
), sin (angle
), 0.0);
456 glBegin (GL_QUAD_STRIP
);
457 for (i
= 0; i
< teeth
; i
++)
459 angle
= i
* 2.0 * M_PI
/ teeth
;
460 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), width
* fraction
);
461 glVertex3f (r1
* cos (angle
), r1
* sin (angle
), -width
* fraction
);
462 u
= r2
* cos (angle
+ da
) - r1
* cos (angle
);
463 v
= r2
* sin (angle
+ da
) - r1
* sin (angle
);
464 len
= sqrt (u
* u
+ v
* v
);
467 glNormal3f (v
, -u
, 0.0);
468 glVertex3f ((r2
- width
) * cos (angle
+ da
), (r2
- width
) * sin (angle
+ da
), width
* fraction
);
469 glVertex3f (r2
* cos (angle
+ da
), r2
* sin (angle
+ da
), -width
* fraction
);
470 glNormal3f (cos (angle
), sin (angle
), n
);
471 glVertex3f ((r2
- width
) * cos (angle
+ 2 * da
), (r2
- width
) * sin (angle
+ 2 * da
), width
* fraction
);
472 glVertex3f (r2
* cos (angle
+ 2 * da
), r2
* sin (angle
+ 2 * da
), -width
* fraction
);
473 u
= r1
* cos (angle
+ 3 * da
) - r2
* cos (angle
+ 2 * da
);
474 v
= r1
* sin (angle
+ 3 * da
) - r2
* sin (angle
+ 2 * da
);
475 glNormal3f (v
, -u
, 0.0);
476 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), width
* fraction
);
477 glVertex3f (r1
* cos (angle
+ 3 * da
), r1
* sin (angle
+ 3 * da
), -width
* fraction
);
478 glNormal3f (cos (angle
), sin (angle
), n
);
482 glVertex3f (r1
* cos (0), r1
* sin (0), width
* fraction
);
483 glVertex3f (r1
* cos (0), r1
* sin (0), -width
* fraction
);
489 belt (struct GEAR g1
, struct GEAR g2
)
491 GLfloat D
, alpha
, phi
, angle
, incr
, width
;
502 width
= min (g1
.width
, g2
.width
);
503 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));
504 alpha
= acos ((g2
.position
[0] - g1
.position
[0]) / D
);
505 phi
= acos ((g1
.radius
- g2
.radius
) / D
);
508 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
509 incr
= 1.2 * 360.0 / g1
.teeth
* M_PI
/ 180.00;
510 for (angle
= alpha
+ phi
; angle
<= 2 * M_PI
- phi
+ alpha
; angle
+= 360.0 / g1
.teeth
* M_PI
/ 180.00)
512 glNormal3f (cos (angle
), sin (angle
), 0.0);
513 glVertex3f (g1
.radius
* cos (angle
), g1
.radius
* sin (angle
), width
* 0.5);
514 glVertex3f (g1
.radius
* cos (angle
), g1
.radius
* sin (angle
), -width
* 0.5);
515 glVertex3f (g1
.radius
* cos (angle
+ incr
), g1
.radius
* sin (angle
+ incr
), -width
* 0.5);
516 glVertex3f (g1
.radius
* cos (angle
+ incr
), g1
.radius
* sin (angle
+ incr
), width
* 0.5);
521 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
522 incr
= 1.2 * 360.0 / g2
.teeth
* M_PI
/ 180.00;
523 for (angle
= -phi
+ alpha
; angle
<= phi
+ alpha
; angle
+= 360.0 / g1
.teeth
* M_PI
/ 180.0)
525 glNormal3f (cos (angle
), sin (angle
), 0.0);
526 glVertex3f (g2
.radius
* cos (angle
) + g2
.position
[0] - g1
.position
[0], g2
.radius
* sin (angle
) + g2
.position
[1] - g1
.position
[1], width
* 0.5);
527 glVertex3f (g2
.radius
* cos (angle
) + g2
.position
[0] - g1
.position
[0], g2
.radius
* sin (angle
) + g2
.position
[1] - g1
.position
[1], width
* -0.5);
528 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);
529 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 glMaterialiv (GL_FRONT
, GL_COLOR_INDEXES
, indexes
);
536 glVertex3f (g1
.radius
* cos (alpha
+ phi
), g1
.radius
* sin (alpha
+ phi
), width
* 0.5);
537 glVertex3f (g1
.radius
* cos (alpha
+ phi
), g1
.radius
* sin (alpha
+ phi
), width
* -0.5);
538 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);
539 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);
540 glVertex3f (g1
.radius
* cos (alpha
- phi
), g1
.radius
* sin (alpha
- phi
), width
* 0.5);
541 glVertex3f (g1
.radius
* cos (alpha
- phi
), g1
.radius
* sin (alpha
- phi
), 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 (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 axle_find (char axle_name
[])
553 for (i
= 0; i
< number_of_axles
; i
++)
555 if (!(strcmp (axle_name
, a
[i
].name
)))
563 gear_find (char gear_name
[])
567 for (i
= 0; i
< number_of_gears
; i
++)
569 if (!(strcmp (gear_name
, g
[i
].name
)))
579 GLfloat x
, y
, z
, D
, dist
;
580 GLint axle_index
, i
, j
, g1
, g2
, k
;
583 for (i
= 0; i
< number_of_gears
; i
++)
588 axle_index
= axle_find (g
[i
].axle_name
);
589 g
[i
].axis
= a
[axle_index
].axis
;
590 g
[i
].motored
= a
[axle_index
].motored
;
591 if (a
[axle_index
].motored
)
593 g
[i
].direction
= a
[axle_index
].direction
;
594 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
598 else if (g
[i
].axis
== 1)
603 g
[i
].position
[0] = a
[axle_index
].position
[0] + x
* g
[i
].relative_position
;
604 g
[i
].position
[1] = a
[axle_index
].position
[1] + y
* g
[i
].relative_position
;
605 g
[i
].position
[2] = a
[axle_index
].position
[2] + z
* g
[i
].relative_position
;
608 for (k
= 0; k
< number_of_axles
; k
++)
610 for (i
= 0; i
< number_of_gears
- 1; i
++)
612 for (j
= 0; j
< number_of_gears
; j
++)
614 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
))
616 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));
617 if (D
< 1.1 * (g
[i
].radius
- g
[i
].tooth_depth
+ g
[j
].radius
- g
[j
].tooth_depth
))
619 printf (error
, "Gear %s and %s are too close to each other.", g
[i
].name
, g
[j
].name
);
621 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
627 dist
= g
[i
].position
[0] - g
[j
].position
[0];
629 else if (g
[i
].axis
== 1)
631 dist
= g
[i
].position
[1] - g
[j
].position
[1];
634 dist
= g
[i
].position
[2] - g
[j
].position
[2];
638 if (dist
< (g
[i
].width
/ 2 + g
[j
].width
/ 2))
640 if ((g
[i
].motored
) && (!(g
[j
].motored
)) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
642 axle_index
= axle_find (g
[j
].axle_name
);
643 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
))
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
[j
].motored
= (a
[axle_index
].motored
= 1);
651 g
[j
].direction
= (a
[axle_index
].direction
= -g
[i
].direction
);
652 a
[axle_index
].angular_velocity
= g
[i
].angular_velocity
* g
[i
].teeth
/ g
[j
].teeth
;
653 g
[j
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[i
].radius
/ g
[j
].radius
);
656 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * (g
[i
].radius
+ g
[j
].radius
)))
658 axle_index
= axle_find (g
[i
].axle_name
);
659 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
))
661 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
662 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
666 g
[i
].motored
= (a
[axle_index
].motored
= 1);
667 g
[i
].direction
= (a
[axle_index
].direction
= -g
[j
].direction
);
668 a
[axle_index
].angular_velocity
= g
[j
].angular_velocity
* g
[j
].teeth
/ g
[i
].teeth
;
669 g
[i
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[j
].radius
/ g
[i
].radius
);
675 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
))
677 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));
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
[j
].axle_name
);
681 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
))
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
[j
].motored
= (a
[axle_index
].motored
= 1);
688 g
[j
].direction
= (a
[axle_index
].direction
= -g
[i
].direction
);
689 a
[axle_index
].angular_velocity
= g
[i
].angular_velocity
* g
[i
].teeth
/ g
[j
].teeth
;
690 g
[j
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[i
].radius
/ g
[j
].radius
);
694 if ((!(g
[i
].motored
)) && (g
[j
].motored
) && (D
< 0.95 * sqrt (g
[i
].radius
* g
[i
].radius
+ g
[j
].radius
* g
[j
].radius
)))
696 axle_index
= axle_find (g
[i
].axle_name
);
697 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
))
699 printf (error
, "Error in tooth linkage of gears %s and %s.", g
[i
].name
, g
[j
].name
);
700 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
703 g
[i
].motored
= (a
[axle_index
].motored
= 1);
704 g
[i
].direction
= (a
[axle_index
].direction
= -g
[j
].direction
);
705 a
[axle_index
].angular_velocity
= g
[j
].angular_velocity
* g
[j
].teeth
/ g
[i
].teeth
;
706 g
[i
].angular_velocity
= (a
[axle_index
].angular_velocity
*= g
[j
].radius
/ g
[i
].radius
);
712 for (i
= 0; i
< number_of_gears
; i
++)
714 axle_index
= axle_find (g
[i
].axle_name
);
715 g
[i
].motored
= a
[axle_index
].motored
;
716 if (a
[axle_index
].motored
)
718 g
[i
].direction
= a
[axle_index
].direction
;
719 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
723 for (i
= 0; i
< number_of_belts
; i
++)
725 g1
= gear_find (b
[i
].gear1_name
);
726 g2
= gear_find (b
[i
].gear2_name
);
727 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));
728 if (!((g
[g1
].axis
== g
[g2
].axis
) && (!strcmp (g
[g1
].type
, g
[g2
].type
)) && (!strcmp (g
[g1
].type
, "NORMAL"))))
730 printf (error
, "Belt %s invalid.", b
[i
].name
);
731 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
735 if ((g
[g1
].axis
== g
[g2
].axis
) && (!strcmp (g
[g1
].type
, g
[g2
].type
)) && (!strcmp (g
[g1
].type
, "NORMAL")))
738 if((g[g1].motored)&&(g[g2].motored))
739 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
741 printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
742 MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
748 dist
= g
[g1
].position
[0] - g
[g2
].position
[0];
750 else if (g
[i
].axis
== 1)
752 dist
= g
[g1
].position
[1] - g
[g2
].position
[1];
755 dist
= g
[g1
].position
[2] - g
[g2
].position
[2];
759 if (dist
> (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
761 printf (error
, "Belt %s invalid.", b
[i
].name
);
762 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
766 if (dist
< (g
[g1
].width
/ 2 + g
[g2
].width
/ 2))
768 if (D
< g
[g1
].radius
+ g
[g2
].radius
)
770 printf (error
, "Gears %s and %s too close to be linked with belts", g
[g1
].name
, g
[g2
].name
);
771 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
775 if ((g
[g1
].motored
) && (!(g
[g2
].motored
)))
777 axle_index
= axle_find (g
[g2
].axle_name
);
778 g
[g2
].motored
= (a
[axle_index
].motored
= 1);
779 g
[g2
].direction
= (a
[axle_index
].direction
= g
[g1
].direction
);
780 g
[g2
].angular_velocity
= (a
[axle_index
].angular_velocity
= g
[g1
].angular_velocity
* g
[g1
].radius
/ g
[g2
].radius
);
783 if ((!(g
[g1
].motored
)) && (g
[g2
].motored
))
785 axle_index
= axle_find (g
[g1
].axle_name
);
786 g
[g1
].motored
= (a
[axle_index
].motored
= 1);
787 g
[g1
].direction
= (a
[axle_index
].direction
= g
[g2
].direction
);
788 g
[g1
].angular_velocity
= (a
[axle_index
].angular_velocity
= g
[g2
].angular_velocity
* g
[g2
].radius
/ g
[g1
].radius
);
794 for (i
= 0; i
< number_of_gears
; i
++)
796 axle_index
= axle_find (g
[i
].axle_name
);
797 g
[i
].motored
= a
[axle_index
].motored
;
798 if (a
[axle_index
].motored
)
800 g
[i
].direction
= a
[axle_index
].direction
;
801 g
[i
].angular_velocity
= a
[axle_index
].angular_velocity
;
809 GLfloat view_rotx
= 20.0, view_roty
= 30.0, view_rotz
= 10.0;
819 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
822 glRotatef (view_rotx
, 1.0, 0.0, 0.0);
823 glRotatef (view_roty
, 0.0, 1.0, 0.0);
824 glRotatef (view_rotz
, 0.0, 0.0, 1.0);
826 for (i
= 0; i
< number_of_gears
; i
++)
832 /*glTranslatef( -3.0, -2.0, 0.0 );*/
833 glTranslatef (g
[i
].position
[0], g
[i
].position
[1], g
[i
].position
[2]);
836 else if (g
[i
].axis
== 1)
842 glRotatef (90.0, x
, y
, z
);
844 glRotatef (g
[i
].direction
* g
[i
].angle
, 0.0, 0.0, 1.0);
845 glCallList (g
[i
].id
);
849 for (i
= 0; i
< number_of_axles
; i
++)
855 glTranslatef (a
[i
].position
[0], a
[i
].position
[1], a
[i
].position
[2]);
858 else if (a
[i
].axis
== 1)
864 glRotatef (90.0, x
, y
, z
);
866 glCallList (a
[i
].id
);
870 for (i
= 0; i
< number_of_belts
; i
++)
876 index
= gear_find (b
[i
].gear1_name
);
877 glTranslatef (g
[index
].position
[0], g
[index
].position
[1], g
[index
].position
[2]);
878 if (g
[index
].axis
== 0)
880 else if (g
[index
].axis
== 1)
886 glRotatef (90.0, x
, y
, z
);
888 glCallList (b
[i
].id
);
903 for (i
= 0; i
< number_of_gears
; i
++)
904 g
[i
].angle
+= g
[i
].angular_velocity
;
911 /* change view angle, exit upon ESC */
913 key (unsigned char k
, int x
, int y
)
943 /* new window size or exposure */
945 reshape (int width
, int height
)
947 glViewport (0, 0, (GLint
) width
, (GLint
) height
);
948 glMatrixMode (GL_PROJECTION
);
952 GLfloat w
= (GLfloat
) width
/ (GLfloat
) height
;
953 glFrustum (-w
, w
, -1.0, 1.0, 5.0, 60.0);
957 GLfloat h
= (GLfloat
) height
/ (GLfloat
) width
;
958 glFrustum (-1.0, 1.0, -h
, h
, 5.0, 60.0);
961 glMatrixMode (GL_MODELVIEW
);
963 glTranslatef (0.0, 0.0, -40.0);
964 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
972 GLfloat matShine
= 20.00F
;
973 GLfloat light0Pos
[4] =
975 0.70F
, 0.70F
, 1.25F
, 0.50F
979 glClearColor (background
[0], background
[1], background
[2], 1.0F
);
980 glClearIndex ((GLfloat
) 0.0);
982 glMaterialf (GL_FRONT_AND_BACK
, GL_SHININESS
, matShine
);
983 glLightfv (GL_LIGHT0
, GL_POSITION
, light0Pos
);
984 glEnable (GL_LIGHT0
);
986 glEnable (GL_LIGHTING
);
987 glEnable (GL_DEPTH_TEST
);
988 for (i
= 0; i
< number_of_gears
; i
++)
991 for (i
= 0; i
< number_of_gears
; i
++)
993 g
[i
].id
= glGenLists (1);
994 glNewList (g
[i
].id
, GL_COMPILE
);
995 glColor3fv (g
[i
].color
);
996 glMaterialfv (GL_FRONT
, GL_SPECULAR
, g
[i
].color
);
997 gear (i
, g
[i
].type
, g
[i
].radius
, g
[i
].width
, g
[i
].teeth
, g
[i
].tooth_depth
);
1001 for (i
= 0; i
< number_of_axles
; i
++)
1003 a
[i
].id
= glGenLists (1);
1004 glNewList (a
[i
].id
, GL_COMPILE
);
1005 glColor3fv (a
[i
].color
);
1006 glMaterialfv (GL_FRONT
, GL_SPECULAR
, a
[i
].color
);
1007 axle (i
, a
[i
].radius
, a
[i
].length
);
1011 for (i
= 0; i
< number_of_belts
; i
++)
1013 b
[i
].id
= glGenLists (1);
1014 glNewList (b
[i
].id
, GL_COMPILE
);
1015 belt (g
[gear_find (b
[i
].gear1_name
)], g
[gear_find (b
[i
].gear2_name
)]);
1019 glEnable (GL_COLOR_MATERIAL
);
1025 main (int argc
, char *argv
[])
1030 file
= "geartrain.dat";
1034 glutInitWindowPosition (0, 0);
1035 glutInitWindowSize(640,480);
1036 glutInitDisplayMode (GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
1038 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE
)
1045 glutDisplayFunc (draw
);
1046 glutReshapeFunc (reshape
);
1047 glutKeyboardFunc (key
);
1048 glutIdleFunc (idle
);