sphere.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:5k
源码类别:

GIS编程

开发平台:

Visual C++

  1. #include <stdlib.h>
  2. #include <GL/glut.h>
  3. #include <math.h>
  4. #ifndef __sgi
  5. /* Most math.h's do not define float versions of the math functions. */
  6. #define sqrtf(x) ((float)sqrt((x)))
  7. #endif
  8. /* sphere tessellation code based on code originally
  9.  * written by Jon Leech (leech@cs.unc.edu) 3/24/89
  10.  */
  11. typedef struct {
  12.     float x, y, z;
  13. } point;
  14. typedef struct {
  15.     point pt[3];
  16. } triangle;
  17. /* six equidistant points lying on the unit sphere */
  18. #define XPLUS {  1,  0,  0 } /*  X */
  19. #define XMIN  { -1,  0,  0 } /* -X */
  20. #define YPLUS {  0,  1,  0 } /*  Y */
  21. #define YMIN  {  0, -1,  0 } /* -Y */
  22. #define ZPLUS {  0,  0,  1 } /*  Z */
  23. #define ZMIN  {  0,  0, -1 } /* -Z */
  24. /* for icosahedron */
  25. #define CZ (0.866025403) /*  cos(30) */
  26. #define SZ (0.5) /*  sin(30) */
  27. #define C1 (0.951056516) /* cos(18),  */
  28. #define S1 (0.309016994) /* sin(18) */
  29. #define C2 (0.587785252) /* cos(54),  */
  30. #define S2 (0.809016994) /* sin(54) */
  31. #define X1 (C1*CZ)
  32. #define Y1 (S1*CZ)
  33. #define X2 (C2*CZ)
  34. #define Y2 (S2*CZ)
  35. #define Ip0  {0.,  0.,  1.}
  36. #define Ip1 {-X2,  -Y2,  SZ}
  37. #define Ip2 {X2,  -Y2,  SZ}
  38. #define Ip3 {X1,  Y1,  SZ}
  39. #define Ip4 {0,  CZ,  SZ}
  40. #define Ip5 {-X1,  Y1,  SZ}
  41. #define Im0 {-X1,  -Y1,  -SZ}
  42. #define Im1 {0,  -CZ,  -SZ}
  43. #define Im2 {X1,  -Y1,  -SZ}
  44. #define Im3 {X2,  Y2,  -SZ}
  45. #define Im4 {-X2,  Y2,  -SZ}
  46. #define Im5 {0.,  0.,  -1.}
  47. /* vertices of a unit icosahedron */
  48. static triangle icosahedron[20]= {
  49. /* front pole */
  50. { {Ip0, Ip1, Ip2}, },
  51. { {Ip0, Ip5, Ip1}, },
  52. { {Ip0, Ip4, Ip5}, },
  53. { {Ip0, Ip3, Ip4}, },
  54. { {Ip0, Ip2, Ip3}, },
  55. /* mid */
  56. { {Ip1, Im0, Im1}, },
  57. { {Im0, Ip1, Ip5}, },
  58. { {Ip5, Im4, Im0}, },
  59. { {Im4, Ip5, Ip4}, },
  60. { {Ip4, Im3, Im4}, },
  61. { {Im3, Ip4, Ip3}, },
  62. { {Ip3, Im2, Im3}, },
  63. { {Im2, Ip3, Ip2}, },
  64. { {Ip2, Im1, Im2}, },
  65. { {Im1, Ip2, Ip1}, },
  66. /* back pole */
  67. { {Im3, Im2, Im5}, },
  68. { {Im4, Im3, Im5}, },
  69. { {Im0, Im4, Im5}, },
  70. { {Im1, Im0, Im5}, },
  71. { {Im2, Im1, Im5}, },
  72. };
  73. /* normalize point r */
  74. static void
  75. normalize(point *r) {
  76.     float mag;
  77.     mag = r->x * r->x + r->y * r->y + r->z * r->z;
  78.     if (mag != 0.0f) {
  79. mag = 1.0f / sqrtf(mag);
  80. r->x *= mag;
  81. r->y *= mag;
  82. r->z *= mag;
  83.     }
  84. }
  85. /* linearly interpolate between a & b, by fraction f */
  86. static void
  87. lerp(point *a, point *b, float f, point *r) {
  88.     r->x = a->x + f*(b->x-a->x);
  89.     r->y = a->y + f*(b->y-a->y);
  90.     r->z = a->z + f*(b->z-a->z);
  91. }
  92. void
  93. sphere(int maxlevel) {
  94.     int nrows = 1 << maxlevel;
  95.     int s;
  96.     /* iterate over the 20 sides of the icosahedron */
  97.     for(s = 0; s < 20; s++) {
  98. int i;
  99. triangle *t = &icosahedron[s];
  100. for(i = 0; i < nrows; i++) {
  101.     /* create a tstrip for each row */
  102.     /* number of triangles in this row is number in previous +2 */
  103.     /* strip the ith trapezoid block */
  104.     point v0, v1, v2, v3, va, vb;
  105.     int j;
  106.     lerp(&t->pt[1], &t->pt[0], (float)(i+1)/nrows, &v0);
  107.     lerp(&t->pt[1], &t->pt[0], (float)i/nrows, &v1);
  108.     lerp(&t->pt[1], &t->pt[2], (float)(i+1)/nrows, &v2);
  109.     lerp(&t->pt[1], &t->pt[2], (float)i/nrows, &v3);
  110.     glBegin(GL_TRIANGLE_STRIP);
  111. #define V(v) { point x; x = v; normalize(&x); glNormal3fv(&x.x); glVertex3fv(&x.x); }
  112.     V(v0);
  113.     V(v1);
  114.     for(j = 0; j < i; j++) {
  115. /* calculate 2 more vertices at a time */
  116. lerp(&v0, &v2, (float)(j+1)/(i+1), &va);
  117. lerp(&v1, &v3, (float)(j+1)/i, &vb);
  118. V(va);
  119. V(vb);
  120.     }
  121.     V(v2);
  122. #undef V
  123.     glEnd();
  124. }
  125.     }
  126. }
  127. float *
  128. sphere_tris(int maxlevel) {
  129.     int nrows = 1 << maxlevel;
  130.     int s, n;
  131.     float *buf, *b;
  132.     n = 20*(1 << (maxlevel * 2));
  133.     b = buf = (float *)malloc(n*3*3*sizeof(float));
  134.     /* iterate over the 20 sides of the icosahedron */
  135.     for(s = 0; s < 20; s++) {
  136. int i;
  137. triangle *t = &icosahedron[s];
  138. for(i = 0; i < nrows; i++) {
  139.     /* create a tstrip for each row */
  140.     /* number of triangles in this row is number in previous +2 */
  141.     /* strip the ith trapezoid block */
  142.     point v0, v1, v2, v3, va, vb, x1, x2;
  143.     int j;
  144.     lerp(&t->pt[1], &t->pt[0], (float)(i+1)/nrows, &v0);
  145.     lerp(&t->pt[1], &t->pt[0], (float)i/nrows, &v1);
  146.     lerp(&t->pt[1], &t->pt[2], (float)(i+1)/nrows, &v2);
  147.     lerp(&t->pt[1], &t->pt[2], (float)i/nrows, &v3);
  148. #define V(a, c, v) { point x = v; normalize(&a); normalize(&c); normalize(&x); 
  149. b[0] = a.x; b[1] = a.y; b[2] = a.z; 
  150. b[3] = c.x; b[4] = c.y; b[5] = c.z; 
  151. b[6] = x.x; b[7] = x.y; b[8] = x.z; b+=9; }
  152.     x1 = v0;
  153.     x2 = v1;
  154.     for(j = 0; j < i; j++) {
  155. /* calculate 2 more vertices at a time */
  156. lerp(&v0, &v2, (float)(j+1)/(i+1), &va);
  157. lerp(&v1, &v3, (float)(j+1)/i, &vb);
  158. V(x1,x2,va); x1 = x2; x2 = va;
  159. V(vb,x2,x1); x1 = x2; x2 = vb;
  160.     }
  161.     V(x1, x2, v2);
  162. #undef V
  163. }
  164.     }
  165.     return buf;
  166. }