8cf51cae5ae016dc44b7a391117e08daa55d2625
[xscreensaver] / hacks / glx / extrusion-taper.c
1 /* 
2  * taper.c
3  * 
4  * FUNCTION:
5  * Draws a tapered screw shape.
6  *
7  * HISTORY:
8  * -- created by Linas Vepstas October 1991
9  * -- heavily modified to draw more texas shapes, Feb 1993, Linas
10  * -- converted to use GLUT -- December 1995, Linas
11  *
12  */
13
14 /* required include files */
15 #include <math.h>
16 #include <stdlib.h>
17 #include <GL/gl.h>
18 #include <GL/glut.h>
19 #include <GL/tube.h>
20
21 #ifndef NULL
22 #define NULL ((void *) 0x0)
23 #endif /* NULL */
24
25 /* Some <math.h> files do not define M_PI... */
26 #ifndef M_PI
27 #define M_PI 3.14159265358979323846
28 #endif
29
30 /* =========================================================== */
31
32 #define SCALE 3.33333
33 #define CONTOUR(x,y) {                                  \
34    double ax, ay, alen;                                 \
35    contour[i][0] = SCALE * (x);                         \
36    contour[i][1] = SCALE * (y);                         \
37    if (i!=0) {                                          \
38       ax = contour[i][0] - contour[i-1][0];             \
39       ay = contour[i][1] - contour[i-1][1];             \
40       alen = 1.0 / sqrt (ax*ax + ay*ay);                \
41       ax *= alen;   ay *= alen;                         \
42       norms [i-1][0] = ay;                              \
43       norms [i-1][1] = -ax;                             \
44    }                                                    \
45    i++;                                                 \
46 }
47
48 #define NUM_PTS (25)
49
50 double contour [NUM_PTS][2];
51 double norms [NUM_PTS][2];
52
53 static void init_contour (void)
54 {
55    int i;
56
57    /* outline of extrusion */
58    i=0;
59    CONTOUR (1.0, 1.0);
60    CONTOUR (1.0, 2.9);
61    CONTOUR (0.9, 3.0);
62    CONTOUR (-0.9, 3.0);
63    CONTOUR (-1.0, 2.9);
64
65    CONTOUR (-1.0, 1.0);
66    CONTOUR (-2.9, 1.0);
67    CONTOUR (-3.0, 0.9);
68    CONTOUR (-3.0, -0.9);
69    CONTOUR (-2.9, -1.0);
70
71    CONTOUR (-1.0, -1.0);
72    CONTOUR (-1.0, -2.9);
73    CONTOUR (-0.9, -3.0);
74    CONTOUR (0.9, -3.0);
75    CONTOUR (1.0, -2.9);
76
77    CONTOUR (1.0, -1.0);
78    CONTOUR (2.9, -1.0);
79    CONTOUR (3.0, -0.9);
80    CONTOUR (3.0, 0.9);
81    CONTOUR (2.9, 1.0);
82
83    CONTOUR (1.0, 1.0);   /* repeat so that last normal is computed */
84 }
85    
86 /* =========================================================== */
87
88 #define PSIZE 40
89 double path[PSIZE][3];
90 double twist[PSIZE];
91 double taper[PSIZE];
92
93 void init_taper (void) {
94    int j;
95    double z, deltaz;
96    double ang, dang;
97
98    z = -10.0;
99    deltaz = 0.5;
100
101    ang = 0.0;
102    dang = 20.0;
103    for (j=0; j<40; j++) {
104       path[j][0] = 0x0;
105       path[j][1] = 0x0;
106       path[j][2] = z;
107
108       twist[j] = ang;
109       ang += dang;
110
111       taper[j] = 0.1 * sqrt (9.51*9.51 - z*z);
112
113       z += deltaz;
114    }
115
116    taper[0] = taper[1];
117    taper[39] = taper[38];
118
119 }
120
121 /* =========================================================== */
122
123 extern float lastx;
124 extern float lasty;
125 extern float rot_x;
126 extern float rot_y;
127 extern float rot_z;
128
129 void InitStuff_taper (void)
130 {
131    int style;
132
133    /* configure the pipeline */
134    style = TUBE_JN_CAP;
135    style |= TUBE_CONTOUR_CLOSED;
136    style |= TUBE_NORM_FACET;
137    style |= TUBE_JN_ANGLE;
138    gleSetJoinStyle (style);
139
140    init_contour();
141    init_taper();
142 }
143
144 /* =========================================================== */
145
146 void gleTaper (int ncp, 
147                gleDouble contour[][2], 
148                gleDouble cont_normal[][2], 
149                gleDouble up[3],
150                int npoints,
151                gleDouble point_array[][3],
152                float color_array[][3],
153                gleDouble taper[],
154                gleDouble twist[])
155 {
156    int j;
157    gleAffine *xforms;
158    double co, si, angle;
159
160    /* malloc the extrusion array and the twist array */
161    xforms = (gleAffine *) malloc (npoints * sizeof(gleAffine));
162
163    for (j=0; j<npoints; j++) {
164       angle = (M_PI/180.0) * twist[j];
165       si = sin (angle);
166       co = cos (angle);
167       xforms[j][0][0] = taper[j] * co;
168       xforms[j][0][1] = - taper[j] * si;
169       xforms[j][0][2] = 0.0;
170       xforms[j][1][0] = taper[j] * si;
171       xforms[j][1][1] = taper[j] * co;
172       xforms[j][1][2] = 0.0;
173    }
174
175    gleSuperExtrusion (ncp,               /* number of contour points */
176                 contour,    /* 2D contour */
177                 cont_normal, /* 2D contour normals */
178                 up,           /* up vector for contour */
179                 npoints,           /* numpoints in poly-line */
180                 point_array,        /* polyline */
181                 color_array,        /* color of polyline */
182                 xforms);
183
184    free (xforms);
185 }
186
187 /* =========================================================== */
188
189 void DrawStuff_taper (void) {
190    int j;
191    double ang, dang;
192    double z, deltaz;
193    double ponent;
194    z=-1.0;
195    deltaz = 1.999/38;
196    ang = 0.0;
197    dang = lasty/40.0;
198    ponent = fabs (lastx/540.0);
199    for (j=1; j<39; j++) {
200       twist[j] = ang;
201       ang += dang;
202
203       taper[j] = pow ((1.0 - pow (fabs(z), 1.0/ponent)), ponent);
204       z += deltaz;
205    }
206
207    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
208    glColor3f (0.5, 0.6, 0.6);
209
210    /* set up some matrices so that the object spins with the mouse */
211    glPushMatrix ();
212    glTranslatef (0.0, 0.0, -80.0);
213    glRotatef(rot_x, 1, 0, 0);
214    glRotatef(rot_y, 0, 1, 0);
215    glRotatef(rot_z, 0, 0, 1);
216
217 /*     glRotatef (130.0, 0.0, 1.0, 0.0); */
218 /*     glRotatef (65.0, 1.0, 0.0, 0.0); */
219
220    /* draw the brand and the handle */
221    gleTaper (20, contour, norms,  NULL, 40, path, NULL, taper, twist);
222
223    glPopMatrix ();
224 }
225
226 /* ===================== END OF FILE ================== */