Clone of mesa.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

geartrain.c 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. /*
  2. * GearTrain Simulator * Version: 1.00
  3. *
  4. * Copyright (C) 1999 Shobhan Kumar Dutta All Rights Reserved.
  5. * <skdutta@del3.vsnl.net.in>
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * SHOBHAN KUMAR DUTTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
  22. * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. */
  25. #include <math.h>
  26. #include <stdlib.h>
  27. #include <GL/glut.h>
  28. #include <string.h>
  29. #include <stdio.h>
  30. #ifndef min
  31. #define min(x, y) ( x < y ? x : y )
  32. #endif
  33. #ifndef M_PI
  34. #define M_PI 3.14159265
  35. #endif /* */
  36. typedef GLfloat TDA[4];
  37. TDA background;
  38. struct AXLE
  39. {
  40. char name[20];
  41. GLint id;
  42. GLfloat radius;
  43. GLint axis;
  44. TDA color;
  45. TDA position;
  46. GLfloat length;
  47. GLint motored;
  48. GLfloat angular_velocity;
  49. GLint direction;
  50. };
  51. struct GEAR
  52. {
  53. char name[20];
  54. char type[7];
  55. GLint face;
  56. GLint id;
  57. GLfloat radius;
  58. GLfloat width;
  59. GLint teeth;
  60. GLfloat tooth_depth;
  61. GLfloat angle;
  62. GLfloat angular_velocity;
  63. TDA color;
  64. GLint relative_position;
  65. TDA position;
  66. char axle_name[20];
  67. GLint axis;
  68. GLint direction;
  69. GLint motored;
  70. };
  71. struct BELT
  72. {
  73. char name[20];
  74. GLint id;
  75. char gear1_name[20];
  76. char gear2_name[20];
  77. };
  78. FILE * mainfile;
  79. struct GEAR g[10];
  80. struct AXLE a[10];
  81. struct BELT b[10];
  82. int number_of_gears;
  83. int number_of_axles;
  84. int number_of_belts;
  85. char Buf1[256], Buf2[256], Buf3[256], Buf4[256], Buf5[256];
  86. static GLint T0 = 0;
  87. static GLint Frames = 0;
  88. #ifndef _WIN32
  89. static void
  90. strset (char buf[], char ch)
  91. {
  92. int i;
  93. for (i = 0; i < strlen (buf); i++)
  94. buf[i] = ch;
  95. }
  96. #endif
  97. static void
  98. Clear_Buffers ()
  99. {
  100. strset (Buf1, 0);
  101. strset (Buf2, 0);
  102. strset (Buf3, 0);
  103. strset (Buf4, 0);
  104. strset (Buf5, 0);
  105. }
  106. static void
  107. LoadTriplet (TDA A)
  108. {
  109. Clear_Buffers ();
  110. fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
  111. A[0] = atof (Buf2);
  112. A[1] = atof (Buf3);
  113. A[2] = atof (Buf4);
  114. }
  115. static void
  116. LoadReal (float *a)
  117. {
  118. Clear_Buffers ();
  119. fscanf (mainfile, "%s %s", Buf1, Buf2);
  120. *a = atof (Buf2);
  121. }
  122. static void
  123. LoadInteger (int *a)
  124. {
  125. Clear_Buffers ();
  126. fscanf (mainfile, "%s %s", Buf1, Buf2);
  127. *a = atoi (Buf2);
  128. }
  129. static void
  130. LoadText (char *a)
  131. {
  132. Clear_Buffers ();
  133. fscanf (mainfile, "%s %s", Buf1, Buf2);
  134. strcpy (a, Buf2);
  135. }
  136. static void
  137. getdata (char filename[])
  138. {
  139. int gear_count = 0, axle_count = 0, belt_count = 0, i;
  140. mainfile = fopen (filename, "r");
  141. if (!mainfile) {
  142. printf("Error: couldn't open %s\n", filename);
  143. exit(-1);
  144. }
  145. do
  146. {
  147. Clear_Buffers ();
  148. fscanf (mainfile, "%s", Buf1);
  149. if (ferror (mainfile))
  150. {
  151. printf ("\nError opening file !\n");
  152. exit (1);
  153. }
  154. if (!(strcmp (Buf1, "BACKGROUND")))
  155. LoadTriplet (background);
  156. if (!(strcmp (Buf1, "ANAME")))
  157. {
  158. LoadText (a[axle_count].name);
  159. axle_count++;
  160. }
  161. if (!(strcmp (Buf1, "ARADIUS")))
  162. LoadReal (&a[axle_count - 1].radius);
  163. if (!(strcmp (Buf1, "AAXIS")))
  164. LoadInteger (&a[axle_count - 1].axis);
  165. if (!(strcmp (Buf1, "ACOLOR")))
  166. LoadTriplet (a[axle_count - 1].color);
  167. if (!(strcmp (Buf1, "APOSITION")))
  168. LoadTriplet (a[axle_count - 1].position);
  169. if (!(strcmp (Buf1, "ALENGTH")))
  170. LoadReal (&a[axle_count - 1].length);
  171. if (!(strcmp (Buf1, "AMOTORED")))
  172. LoadInteger (&a[axle_count - 1].motored);
  173. if (!(strcmp (Buf1, "AANGULARVELOCITY")))
  174. LoadReal (&a[axle_count - 1].angular_velocity);
  175. if (!(strcmp (Buf1, "ADIRECTION")))
  176. LoadInteger (&a[axle_count - 1].direction);
  177. if (!(strcmp (Buf1, "GNAME")))
  178. {
  179. LoadText (g[gear_count].name);
  180. gear_count++;
  181. }
  182. if (!(strcmp (Buf1, "GTYPE")))
  183. LoadText (g[gear_count - 1].type);
  184. if (!(strcmp (Buf1, "GFACE")))
  185. LoadInteger (&g[gear_count - 1].face);
  186. if (!(strcmp (Buf1, "GRADIUS")))
  187. LoadReal (&g[gear_count - 1].radius);
  188. if (!(strcmp (Buf1, "GWIDTH")))
  189. LoadReal (&g[gear_count - 1].width);
  190. if (!(strcmp (Buf1, "GTEETH")))
  191. LoadInteger (&g[gear_count - 1].teeth);
  192. if (!(strcmp (Buf1, "GTOOTHDEPTH")))
  193. LoadReal (&g[gear_count - 1].tooth_depth);
  194. if (!(strcmp (Buf1, "GCOLOR")))
  195. LoadTriplet (g[gear_count - 1].color);
  196. if (!(strcmp (Buf1, "GAXLE")))
  197. LoadText (g[gear_count - 1].axle_name);
  198. if (!(strcmp (Buf1, "GPOSITION")))
  199. LoadInteger (&g[gear_count - 1].relative_position);
  200. if (!(strcmp (Buf1, "BELTNAME")))
  201. {
  202. LoadText (b[belt_count].name);
  203. belt_count++;
  204. }
  205. if (!(strcmp (Buf1, "GEAR1NAME")))
  206. LoadText (b[belt_count - 1].gear1_name);
  207. if (!(strcmp (Buf1, "GEAR2NAME")))
  208. LoadText (b[belt_count - 1].gear2_name);
  209. }
  210. while (Buf1[0] != 0);
  211. for (i = 0; i < number_of_gears; i++)
  212. {
  213. g[i].axis = -1;
  214. g[i].direction = 0;
  215. g[i].angular_velocity = 0.0;
  216. }
  217. number_of_gears = gear_count;
  218. number_of_axles = axle_count;
  219. number_of_belts = belt_count;
  220. fclose (mainfile);
  221. }
  222. static void
  223. axle (GLint j, GLfloat radius, GLfloat length)
  224. {
  225. GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
  226. /* draw main cylinder */
  227. glBegin (GL_QUADS);
  228. for (angle = 0.0; angle < 360.0; angle += 5.0)
  229. {
  230. rad = angle * M_PI / 180.0;
  231. glNormal3f (cos (rad), sin (rad), 0.0);
  232. glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
  233. glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
  234. glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
  235. glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
  236. }
  237. glEnd ();
  238. /* draw front face */
  239. glNormal3f (0.0, 0.0, 1.0);
  240. glBegin (GL_TRIANGLES);
  241. for (angle = 0.0; angle < 360.0; angle += 5.0)
  242. {
  243. rad = angle * M_PI / 180.0;
  244. glVertex3f (0.0, 0.0, length / 2);
  245. glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
  246. glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
  247. glVertex3f (0.0, 0.0, length / 2);
  248. }
  249. glEnd ();
  250. /* draw back face */
  251. glNormal3f (0.0, 0.0, -1.0);
  252. glBegin (GL_TRIANGLES);
  253. for (angle = 0.0; angle <= 360.0; angle += 5.0)
  254. {
  255. rad = angle * M_PI / 180.0;
  256. glVertex3f (0.0, 0.0, -length / 2);
  257. glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
  258. glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
  259. glVertex3f (0.0, 0.0, -length / 2);
  260. }
  261. glEnd ();
  262. }
  263. static void
  264. gear (GLint j, char type[], GLfloat radius, GLfloat width,
  265. GLint teeth, GLfloat tooth_depth)
  266. {
  267. GLint i;
  268. GLfloat r1, r2;
  269. GLfloat angle, da;
  270. GLfloat u, v, len, fraction = 0.5;
  271. GLfloat n = 1.0;
  272. r1 = radius - tooth_depth;
  273. r2 = radius;
  274. da = 2.0 * M_PI / teeth / 4.0;
  275. if (!g[j].face)
  276. {
  277. fraction = -0.5;
  278. n = -1.0;
  279. }
  280. if (!(strcmp (type, "NORMAL")))
  281. {
  282. fraction = 0.5;
  283. n = 1.0;
  284. }
  285. /* draw front face */
  286. if (!(strcmp (type, "NORMAL")))
  287. {
  288. glNormal3f (0.0, 0.0, 1.0 * n);
  289. glBegin (GL_QUAD_STRIP);
  290. for (i = 0; i <= teeth; i++)
  291. {
  292. angle = i * 2.0 * M_PI / teeth;
  293. glVertex3f (0.0, 0.0, width * fraction);
  294. glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
  295. glVertex3f (0.0, 0.0, width * fraction);
  296. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
  297. }
  298. glEnd ();
  299. }
  300. else
  301. {
  302. glNormal3f (0.0, 0.0, 1.0 * n);
  303. glBegin (GL_QUAD_STRIP);
  304. for (i = 0; i <= teeth; i++)
  305. {
  306. angle = i * 2.0 * M_PI / teeth;
  307. glVertex3f (0.0, 0.0, width * fraction);
  308. glVertex3f ((r2 - width) * cos (angle), (r2 - width) * sin (angle), width * fraction);
  309. glVertex3f (0.0, 0.0, width * fraction);
  310. glVertex3f ((r2 - width) * cos (angle + 3 * da), (r2 - width) * sin (angle + 3 * da), width * fraction);
  311. }
  312. glEnd ();
  313. }
  314. /* draw front sides of teeth */
  315. if (!(strcmp (type, "NORMAL")))
  316. {
  317. glNormal3f (0.0, 0.0, 1.0 * n);
  318. glBegin (GL_QUADS);
  319. da = 2.0 * M_PI / teeth / 4.0;
  320. for (i = 0; i < teeth; i++)
  321. {
  322. angle = i * 2.0 * M_PI / teeth;
  323. glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
  324. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
  325. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
  326. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
  327. }
  328. glEnd ();
  329. }
  330. glNormal3f (0.0, 0.0, -1.0 * n);
  331. /* draw back face */
  332. glBegin (GL_QUAD_STRIP);
  333. for (i = 0; i <= teeth; i++)
  334. {
  335. angle = i * 2.0 * M_PI / teeth;
  336. glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
  337. glVertex3f (0.0, 0.0, -width * fraction);
  338. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
  339. glVertex3f (0.0, 0.0, -width * fraction);
  340. }
  341. glEnd ();
  342. /* draw back sides of teeth */
  343. glNormal3f (0.0, 0.0, -1.0 * n);
  344. glBegin (GL_QUADS);
  345. da = 2.0 * M_PI / teeth / 4.0;
  346. for (i = 0; i < teeth; i++)
  347. {
  348. angle = i * 2.0 * M_PI / teeth;
  349. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
  350. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
  351. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
  352. glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
  353. }
  354. glEnd ();
  355. /* draw outward faces of teeth */
  356. if (!(strcmp (type, "NORMAL")))
  357. {
  358. glBegin (GL_QUAD_STRIP);
  359. for (i = 0; i < teeth; i++)
  360. {
  361. angle = i * 2.0 * M_PI / teeth;
  362. glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
  363. glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
  364. u = r2 * cos (angle + da) - r1 * cos (angle);
  365. v = r2 * sin (angle + da) - r1 * sin (angle);
  366. len = sqrt (u * u + v * v);
  367. u /= len;
  368. v /= len;
  369. glNormal3f (v, -u, 0.0);
  370. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
  371. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
  372. glNormal3f (cos (angle), sin (angle), 0.0);
  373. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
  374. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
  375. u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
  376. v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
  377. glNormal3f (v, -u, 0.0);
  378. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
  379. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
  380. glNormal3f (cos (angle), sin (angle), 0.0);
  381. }
  382. }
  383. else
  384. {
  385. glBegin (GL_QUAD_STRIP);
  386. for (i = 0; i < teeth; i++)
  387. {
  388. angle = i * 2.0 * M_PI / teeth;
  389. glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
  390. glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
  391. u = r2 * cos (angle + da) - r1 * cos (angle);
  392. v = r2 * sin (angle + da) - r1 * sin (angle);
  393. len = sqrt (u * u + v * v);
  394. u /= len;
  395. v /= len;
  396. glNormal3f (v, -u, 0.0);
  397. glVertex3f ((r2 - width) * cos (angle + da), (r2 - width) * sin (angle + da), width * fraction);
  398. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
  399. glNormal3f (cos (angle), sin (angle), n);
  400. glVertex3f ((r2 - width) * cos (angle + 2 * da), (r2 - width) * sin (angle + 2 * da), width * fraction);
  401. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
  402. u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
  403. v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
  404. glNormal3f (v, -u, 0.0);
  405. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
  406. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
  407. glNormal3f (cos (angle), sin (angle), n);
  408. }
  409. }
  410. glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction);
  411. glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction);
  412. glEnd ();
  413. }
  414. static void
  415. belt (struct GEAR g1, struct GEAR g2)
  416. {
  417. GLfloat D, alpha, phi, angle, incr, width;
  418. GLint indexes[3] =
  419. {
  420. 0, 0, 0
  421. };
  422. GLfloat col[3] =
  423. {
  424. 0.0, 0.0, 0.0
  425. };
  426. width = min (g1.width, g2.width);
  427. 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));
  428. alpha = acos ((g2.position[0] - g1.position[0]) / D);
  429. phi = acos ((g1.radius - g2.radius) / D);
  430. glBegin (GL_QUADS);
  431. glColor3fv (col);
  432. glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
  433. incr = 1.2 * 360.0 / g1.teeth * M_PI / 180.00;
  434. for (angle = alpha + phi; angle <= 2 * M_PI - phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.00)
  435. {
  436. glNormal3f (cos (angle), sin (angle), 0.0);
  437. glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), width * 0.5);
  438. glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), -width * 0.5);
  439. glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), -width * 0.5);
  440. glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), width * 0.5);
  441. }
  442. glEnd ();
  443. glBegin (GL_QUADS);
  444. glColor3fv (col);
  445. glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
  446. incr = 1.2 * 360.0 / g2.teeth * M_PI / 180.00;
  447. for (angle = -phi + alpha; angle <= phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.0)
  448. {
  449. glNormal3f (cos (angle), sin (angle), 0.0);
  450. glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * 0.5);
  451. glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * -0.5);
  452. 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);
  453. 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);
  454. }
  455. glEnd ();
  456. glBegin (GL_QUADS);
  457. glColor3fv (col);
  458. glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
  459. glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * 0.5);
  460. glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * -0.5);
  461. 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);
  462. 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);
  463. glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * 0.5);
  464. glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * -0.5);
  465. 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);
  466. 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);
  467. glEnd ();
  468. }
  469. static int
  470. axle_find (char axle_name[])
  471. {
  472. int i;
  473. for (i = 0; i < number_of_axles; i++)
  474. {
  475. if (!(strcmp (axle_name, a[i].name)))
  476. break;
  477. }
  478. return i;
  479. }
  480. static int
  481. gear_find (char gear_name[])
  482. {
  483. int i;
  484. for (i = 0; i < number_of_gears; i++)
  485. {
  486. if (!(strcmp (gear_name, g[i].name)))
  487. break;
  488. }
  489. return i;
  490. }
  491. static void
  492. process ()
  493. {
  494. GLfloat x, y, z, D, dist;
  495. GLint axle_index, i, j, g1, g2, k;
  496. char error[80];
  497. for (i = 0; i < number_of_gears; i++)
  498. {
  499. x = 0.0;
  500. y = 0.0;
  501. z = 0.0;
  502. axle_index = axle_find (g[i].axle_name);
  503. g[i].axis = a[axle_index].axis;
  504. g[i].motored = a[axle_index].motored;
  505. if (a[axle_index].motored)
  506. {
  507. g[i].direction = a[axle_index].direction;
  508. g[i].angular_velocity = a[axle_index].angular_velocity;
  509. }
  510. if (g[i].axis == 0)
  511. x = 1.0;
  512. else if (g[i].axis == 1)
  513. y = 1.0;
  514. else
  515. z = 1.0;
  516. g[i].position[0] = a[axle_index].position[0] + x * g[i].relative_position;
  517. g[i].position[1] = a[axle_index].position[1] + y * g[i].relative_position;
  518. g[i].position[2] = a[axle_index].position[2] + z * g[i].relative_position;
  519. }
  520. for (k = 0; k < number_of_axles; k++)
  521. {
  522. for (i = 0; i < number_of_gears - 1; i++)
  523. {
  524. for (j = 0; j < number_of_gears; j++)
  525. {
  526. 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))
  527. {
  528. 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));
  529. if (D < 1.1 * (g[i].radius - g[i].tooth_depth + g[j].radius - g[j].tooth_depth))
  530. {
  531. printf (error, "Gear %s and %s are too close to each other.", g[i].name, g[j].name);
  532. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  533. exit (1);
  534. }
  535. if (g[i].axis == 0)
  536. {
  537. dist = g[i].position[0] - g[j].position[0];
  538. }
  539. else if (g[i].axis == 1)
  540. {
  541. dist = g[i].position[1] - g[j].position[1];
  542. }
  543. else
  544. dist = g[i].position[2] - g[j].position[2];
  545. dist = fabs (dist);
  546. if (dist < (g[i].width / 2 + g[j].width / 2))
  547. {
  548. if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius)))
  549. {
  550. axle_index = axle_find (g[j].axle_name);
  551. 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))
  552. {
  553. printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
  554. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  555. exit (1);
  556. }
  557. g[j].motored = (a[axle_index].motored = 1);
  558. g[j].direction = (a[axle_index].direction = -g[i].direction);
  559. a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
  560. g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
  561. }
  562. if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius)))
  563. {
  564. axle_index = axle_find (g[i].axle_name);
  565. 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))
  566. {
  567. printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
  568. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  569. exit (1);
  570. }
  571. g[i].motored = (a[axle_index].motored = 1);
  572. g[i].direction = (a[axle_index].direction = -g[j].direction);
  573. a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
  574. g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
  575. }
  576. }
  577. }
  578. 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))
  579. {
  580. 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));
  581. if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
  582. {
  583. axle_index = axle_find (g[j].axle_name);
  584. 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))
  585. {
  586. printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
  587. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  588. exit (1);
  589. }
  590. g[j].motored = (a[axle_index].motored = 1);
  591. g[j].direction = (a[axle_index].direction = -g[i].direction);
  592. a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
  593. g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
  594. }
  595. if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
  596. {
  597. axle_index = axle_find (g[i].axle_name);
  598. 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))
  599. {
  600. printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
  601. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  602. exit (1);
  603. }
  604. g[i].motored = (a[axle_index].motored = 1);
  605. g[i].direction = (a[axle_index].direction = -g[j].direction);
  606. a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
  607. g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
  608. }
  609. }
  610. }
  611. }
  612. for (i = 0; i < number_of_gears; i++)
  613. {
  614. axle_index = axle_find (g[i].axle_name);
  615. g[i].motored = a[axle_index].motored;
  616. if (a[axle_index].motored)
  617. {
  618. g[i].direction = a[axle_index].direction;
  619. g[i].angular_velocity = a[axle_index].angular_velocity;
  620. }
  621. }
  622. for (i = 0; i < number_of_belts; i++)
  623. {
  624. g1 = gear_find (b[i].gear1_name);
  625. g2 = gear_find (b[i].gear2_name);
  626. 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));
  627. if (!((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL"))))
  628. {
  629. printf (error, "Belt %s invalid.", b[i].name);
  630. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  631. exit (1);
  632. }
  633. if ((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))
  634. {
  635. /*
  636. if((g[g1].motored)&&(g[g2].motored))
  637. if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
  638. {
  639. printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
  640. MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
  641. exit(1);
  642. }
  643. */
  644. if (g[g1].axis == 0)
  645. {
  646. dist = g[g1].position[0] - g[g2].position[0];
  647. }
  648. else if (g[i].axis == 1)
  649. {
  650. dist = g[g1].position[1] - g[g2].position[1];
  651. }
  652. else
  653. dist = g[g1].position[2] - g[g2].position[2];
  654. dist = fabs (dist);
  655. if (dist > (g[g1].width / 2 + g[g2].width / 2))
  656. {
  657. printf (error, "Belt %s invalid.", b[i].name);
  658. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  659. exit (1);
  660. }
  661. if (dist < (g[g1].width / 2 + g[g2].width / 2))
  662. {
  663. if (D < g[g1].radius + g[g2].radius)
  664. {
  665. printf (error, "Gears %s and %s too close to be linked with belts", g[g1].name, g[g2].name);
  666. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  667. exit (1);
  668. }
  669. if ((g[g1].motored) && (!(g[g2].motored)))
  670. {
  671. axle_index = axle_find (g[g2].axle_name);
  672. g[g2].motored = (a[axle_index].motored = 1);
  673. g[g2].direction = (a[axle_index].direction = g[g1].direction);
  674. g[g2].angular_velocity = (a[axle_index].angular_velocity = g[g1].angular_velocity * g[g1].radius / g[g2].radius);
  675. }
  676. if ((!(g[g1].motored)) && (g[g2].motored))
  677. {
  678. axle_index = axle_find (g[g1].axle_name);
  679. g[g1].motored = (a[axle_index].motored = 1);
  680. g[g1].direction = (a[axle_index].direction = g[g2].direction);
  681. g[g1].angular_velocity = (a[axle_index].angular_velocity = g[g2].angular_velocity * g[g2].radius / g[g1].radius);
  682. }
  683. }
  684. }
  685. }
  686. for (i = 0; i < number_of_gears; i++)
  687. {
  688. axle_index = axle_find (g[i].axle_name);
  689. g[i].motored = a[axle_index].motored;
  690. if (a[axle_index].motored)
  691. {
  692. g[i].direction = a[axle_index].direction;
  693. g[i].angular_velocity = a[axle_index].angular_velocity;
  694. }
  695. }
  696. }
  697. }
  698. GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
  699. static void
  700. draw (void)
  701. {
  702. int i;
  703. GLfloat x, y, z;
  704. int index;
  705. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  706. glPushMatrix ();
  707. glRotatef (view_rotx, 1.0, 0.0, 0.0);
  708. glRotatef (view_roty, 0.0, 1.0, 0.0);
  709. glRotatef (view_rotz, 0.0, 0.0, 1.0);
  710. for (i = 0; i < number_of_gears; i++)
  711. {
  712. x = 0.0;
  713. y = 0.0;
  714. z = 0.0;
  715. glPushMatrix ();
  716. /*glTranslatef( -3.0, -2.0, 0.0 );*/
  717. glTranslatef (g[i].position[0], g[i].position[1], g[i].position[2]);
  718. if (g[i].axis == 0)
  719. y = 1.0;
  720. else if (g[i].axis == 1)
  721. x = 1.0;
  722. else
  723. z = 1.0;
  724. if (z != 1.0)
  725. glRotatef (90.0, x, y, z);
  726. glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0);
  727. glCallList (g[i].id);
  728. glPopMatrix ();
  729. }
  730. for (i = 0; i < number_of_axles; i++)
  731. {
  732. x = 0.0;
  733. y = 0.0;
  734. z = 0.0;
  735. glPushMatrix ();
  736. glTranslatef (a[i].position[0], a[i].position[1], a[i].position[2]);
  737. if (a[i].axis == 0)
  738. y = 1.0;
  739. else if (a[i].axis == 1)
  740. x = 1.0;
  741. else
  742. z = 1.0;
  743. if (z != 1.0)
  744. glRotatef (90.0, x, y, z);
  745. glCallList (a[i].id);
  746. glPopMatrix ();
  747. }
  748. for (i = 0; i < number_of_belts; i++)
  749. {
  750. x = 0.0;
  751. y = 0.0;
  752. z = 0.0;
  753. glPushMatrix ();
  754. index = gear_find (b[i].gear1_name);
  755. glTranslatef (g[index].position[0], g[index].position[1], g[index].position[2]);
  756. if (g[index].axis == 0)
  757. y = 1.0;
  758. else if (g[index].axis == 1)
  759. x = 1.0;
  760. else
  761. z = 1.0;
  762. if (z != 1.0)
  763. glRotatef (90.0, x, y, z);
  764. glCallList (b[i].id);
  765. glPopMatrix ();
  766. }
  767. glPopMatrix ();
  768. glutSwapBuffers ();
  769. {
  770. GLint t = glutGet(GLUT_ELAPSED_TIME);
  771. Frames++;
  772. if (t - T0 >= 5000) {
  773. GLfloat seconds = (t - T0) / 1000.0;
  774. GLfloat fps = Frames / seconds;
  775. printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
  776. T0 = t;
  777. Frames = 0;
  778. }
  779. }
  780. }
  781. static void
  782. idle (void)
  783. {
  784. int i;
  785. static double t0 = -1.;
  786. double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
  787. if (t0 < 0.0)
  788. t0 = t;
  789. dt = t - t0;
  790. t0 = t;
  791. for (i = 0; i < number_of_gears; i++)
  792. g[i].angle += g[i].angular_velocity * dt;
  793. glutPostRedisplay();
  794. }
  795. /* change view angle, exit upon ESC */
  796. static void
  797. key (unsigned char k, int x, int y)
  798. {
  799. switch (k)
  800. {
  801. case 'x':
  802. view_rotx += 5.0;
  803. break;
  804. case 'X':
  805. view_rotx -= 5.0;
  806. break;
  807. case 'y':
  808. view_roty += 5.0;
  809. break;
  810. case 'Y':
  811. view_roty -= 5.0;
  812. break;
  813. case 'z':
  814. view_rotz += 5.0;
  815. break;
  816. case 'Z':
  817. view_rotz -= 5.0;
  818. break;
  819. case 0x1B:
  820. exit(0);
  821. }
  822. }
  823. /* new window size or exposure */
  824. static void
  825. reshape (int width, int height)
  826. {
  827. glViewport (0, 0, (GLint) width, (GLint) height);
  828. glMatrixMode (GL_PROJECTION);
  829. glLoadIdentity ();
  830. if (width > height)
  831. {
  832. GLfloat w = (GLfloat) width / (GLfloat) height;
  833. glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
  834. }
  835. else
  836. {
  837. GLfloat h = (GLfloat) height / (GLfloat) width;
  838. glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
  839. }
  840. glMatrixMode (GL_MODELVIEW);
  841. glLoadIdentity ();
  842. glTranslatef (0.0, 0.0, -40.0);
  843. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  844. }
  845. static void
  846. init (void)
  847. {
  848. GLfloat matShine = 20.00F;
  849. GLfloat light0Pos[4] =
  850. {
  851. 0.70F, 0.70F, 1.25F, 0.50F
  852. };
  853. int i;
  854. glClearColor (background[0], background[1], background[2], 1.0F);
  855. glClearIndex ((GLfloat) 0.0);
  856. glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine);
  857. glLightfv (GL_LIGHT0, GL_POSITION, light0Pos);
  858. glEnable (GL_LIGHT0);
  859. glEnable (GL_LIGHTING);
  860. glEnable (GL_DEPTH_TEST);
  861. for (i = 0; i < number_of_gears; i++)
  862. g[i].angle = 0.0;
  863. for (i = 0; i < number_of_gears; i++)
  864. {
  865. g[i].id = glGenLists (1);
  866. glNewList (g[i].id, GL_COMPILE);
  867. glColor3fv (g[i].color);
  868. glMaterialfv (GL_FRONT, GL_SPECULAR, g[i].color);
  869. gear (i, g[i].type, g[i].radius, g[i].width, g[i].teeth, g[i].tooth_depth);
  870. glEndList ();
  871. }
  872. for (i = 0; i < number_of_axles; i++)
  873. {
  874. a[i].id = glGenLists (1);
  875. glNewList (a[i].id, GL_COMPILE);
  876. glColor3fv (a[i].color);
  877. glMaterialfv (GL_FRONT, GL_SPECULAR, a[i].color);
  878. axle (i, a[i].radius, a[i].length);
  879. glEndList ();
  880. }
  881. for (i = 0; i < number_of_belts; i++)
  882. {
  883. b[i].id = glGenLists (1);
  884. glNewList (b[i].id, GL_COMPILE);
  885. belt (g[gear_find (b[i].gear1_name)], g[gear_find (b[i].gear2_name)]);
  886. glEndList ();
  887. }
  888. glEnable (GL_COLOR_MATERIAL);
  889. }
  890. int
  891. main (int argc, char *argv[])
  892. {
  893. char *file;
  894. if (argc < 2)
  895. file = "geartrain.dat";
  896. else
  897. file = argv[1];
  898. glutInit(&argc, argv);
  899. glutInitWindowPosition (0, 0);
  900. glutInitWindowSize(640,480);
  901. glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
  902. if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
  903. exit (1);
  904. getdata (file);
  905. process ();
  906. init ();
  907. glutDisplayFunc (draw);
  908. glutReshapeFunc (reshape);
  909. glutKeyboardFunc (key);
  910. glutIdleFunc (idle);
  911. glutMainLoop ();
  912. return 0;
  913. }