Clone of mesa.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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