Attachment 'ss4.c'
Download 1 // ss4.c
2 // gcc -o ss4 ss4.c -lm -lgd
3
4 #define GIFOUT "ss4.gif"
5 #define FNT "DejaVuMonoSans"
6 #define SCALE 0.09
7
8 #define XSIZE 800
9 #define YSIZE 600
10 #define ACC 8
11 #define MINUTE 60
12 #define HOUR 3600
13 #define TIME1 150
14 #define TSTART 0
15 #define TEND 300
16 #define TDELTA 5
17 #define ASTEP0 400
18 #define ASTEP1 25
19 #define LINETHICK 1
20 #define Z0 25.0
21 #define NSTARS 2000
22 #define MOVE 0.3
23
24 #include "gd.h"
25 #include <math.h>
26 #include <string.h>
27 #include <stdlib.h>
28
29 #define PI 3.1415926535897932
30 #define DEG2RAD(x) ((x)*PI/180.)
31
32 gdImagePtr im0, im1, im;
33 int black, white, gray, dgray, trans ;
34 int xgauge = ( XSIZE + YSIZE ) / 2 ; // down the right edge
35 double scale = SCALE * YSIZE ;
36 double anglerad = 0.0 ;
37 double time = 0.0 ;
38 double angle_min = 0.0 ;
39 double angle_max = ACC * TIME1 * TIME1 / ( MINUTE * MINUTE ) ;
40 double min_vel = 0.0 ;
41 double max_vel = ACC * TIME1 / MINUTE ;
42 double min_acc = -ACC ;
43 double max_acc = ACC ;
44 double angle_vel = 0.0 ;
45 double angle_acc = 0.0 ;
46 double angle = 0.0 ;
47
48 //--------------------------------------------------------------------
49 // fixed rectangle subroutines, swap order if needed
50 void RectE( gdImagePtr imm,
51 double rx1, double ry1, double rx2, double ry2, int rcolor ) {
52 if( rx1 < rx2 ) {
53 if( ry1 < ry2 ) {
54 gdImageRectangle( imm, rx1, ry1, rx2, ry2, rcolor );
55 } else {
56 gdImageRectangle( imm, rx1, ry2, rx2, ry1, rcolor );
57 }
58 } else {
59 if( ry1 < ry2 ) {
60 gdImageRectangle( imm, rx2, ry1, rx1, ry2, rcolor );
61 } else {
62 gdImageRectangle( imm, rx2, ry2, rx1, ry1, rcolor );
63 }
64 }
65 }
66
67
68 void RectF( gdImagePtr imm,
69 double rx1, double ry1, double rx2, double ry2, int rcolor ) {
70 if( rx1 < rx2 ) {
71 if( ry1 < ry2 ) {
72 gdImageFilledRectangle( imm, rx1, ry1, rx2, ry2, rcolor );
73 } else {
74 gdImageFilledRectangle( imm, rx1, ry2, rx2, ry1, rcolor );
75 }
76 } else {
77 if( ry1 < ry2 ) {
78 gdImageFilledRectangle( imm, rx2, ry1, rx1, ry2, rcolor );
79 } else {
80 gdImageFilledRectangle( imm, rx2, ry2, rx1, ry1, rcolor );
81 }
82 }
83 }
84
85
86 //--------------------------------------------------------------------
87 // rotation, transformation, scaling --------
88
89 gdPoint sr( double inx, double iny ) {
90 gdPoint retvar ;
91
92 // rotate
93 double rx = inx ;
94 double ry = iny * cos( anglerad );
95 double rz = iny * sin( anglerad ); // into the plane
96
97 // depth transform
98 double trx = rx*(1.0+rz/Z0 ) ;
99 double try = ry*(1.0+rz/Z0) ;
100
101 retvar.x = (int) ( 0.5*YSIZE + scale * trx ) ;
102 retvar.y = (int) ( 0.5*YSIZE - scale * try ) ;
103
104 return retvar;
105 }
106
107 // draw stars ----------------------------------
108 // uses all globals
109
110 // star array, overlaps right edge, unscaled
111 double starx[NSTARS], stary[NSTARS];
112
113 void
114 makestars() {
115 int nstar ;
116 for( nstar = 0 ; nstar < NSTARS ; nstar++ ) {
117 starx[nstar] = drand48() * ( XSIZE + MOVE*TEND ) ;
118 stary[nstar] = drand48() * YSIZE ;
119 }
120 }
121
122
123 void
124 drawstars() {
125 int nstar, xs, ys ;
126 for( nstar = 0 ; nstar < NSTARS ; nstar++ ) {
127 xs = (int) ( starx[nstar] - MOVE*time ) ;
128 ys = (int) stary[nstar] ;
129 if ( xs < YSIZE ) {
130 gdImageSetPixel( im, xs, ys, white);
131 }
132 }
133 }
134
135 // draw gauges ---------------------------------
136 // uses globals
137
138 #define YCLOCK 70
139 #define YACC 180
140 #define YVEL 310
141 #define YANG 440
142
143 #define RCLOCK 68
144 #define SECHAND 60
145 #define MINHAND1 40
146 #define MINHAND2 45
147 #define MINWID 40
148
149 int gleft = YSIZE + 40 ;
150 int gright = XSIZE - 40 ;
151
152
153 int gscale( double gvar, double gmin, double gmax ) {
154 return ( (int) ( gleft + (gvar-gmin)
155 * ( (double)(gright-gleft))/(gmax-gmin) ) ) ;
156 }
157
158 void drawgauges() {
159
160 double wangle ; // working angle
161 double cx1, cy1, cx2, cy2 ;
162 char s[80];
163 int ic ;
164
165 // clock at xgauge, 100 -----------------------------
166
167 gdImageArc( im, xgauge, YCLOCK, 2*RCLOCK, 2*RCLOCK, 0, 360, white );
168
169 // clock / 60
170 for( ic = 0; ic < 60 ; ic += 1 ) {
171 wangle = PI * ic / 30 ;
172 if ( ic%15 == 0 ) {
173 cx1 = xgauge + (RCLOCK-6)*sin(wangle) ;
174 cy1 = YCLOCK - (RCLOCK-6)*cos(wangle) ;
175 }
176 else if( ic%5 == 0 ) {
177 cx1 = xgauge + (RCLOCK-4)*sin(wangle) ;
178 cy1 = YCLOCK - (RCLOCK-4)*cos(wangle) ;
179 }
180 else {
181 cx1 = xgauge + (RCLOCK-2)*sin(wangle) ;
182 cy1 = YCLOCK - (RCLOCK-2)*cos(wangle) ;
183 }
184 cx2 = xgauge + RCLOCK *sin(wangle) ;
185 cy2 = YCLOCK - RCLOCK *cos(wangle) ;
186 gdImageLine( im, cx1, cy1, cx2, cy2, white ) ;
187 }
188
189 // second hand
190 wangle = 2.0 * PI * time / MINUTE ;
191 cx1 = xgauge+SECHAND*sin(wangle) ;
192 cy1 = YCLOCK-SECHAND*cos(wangle) ;
193 gdImageLine( im, xgauge, YCLOCK, cx1, cy1, white ) ;
194
195
196 // minute hand (two strokes )
197 wangle = 2.0 * PI * (time + MINWID) / HOUR ;
198 cx1 = xgauge+MINHAND1*sin(wangle) ;
199 cy1 = YCLOCK-MINHAND1*cos(wangle) ;
200
201 wangle = 2.0 * PI * (time ) / HOUR ;
202 cx2 = xgauge+MINHAND2*sin(wangle) ;
203 cy2 = YCLOCK-MINHAND2*cos(wangle) ;
204 gdImageLine( im, xgauge, YCLOCK, cx1, cy1, white ) ;
205 gdImageLine( im, cx2, cy2, cx1, cy1, white );
206
207 wangle = 2.0 * PI * (time - MINWID) / HOUR ;
208 cx1 = xgauge+MINHAND1*sin(wangle) ;
209 cy1 = YCLOCK-MINHAND1*cos(wangle) ;
210 gdImageLine( im, cx2, cy2, cx1, cy1, white );
211 gdImageLine( im, xgauge, YCLOCK, cx1, cy1, white ) ;
212
213 // text clock
214
215 sprintf( s, "%3.0f secs", time );
216 gdImageStringFT( im, NULL, white, FNT, 20, 0.0, xgauge-40, 180, s );
217
218 // angular acceleration gauge ----------------
219
220 gdImageStringFT( im, NULL, white, FNT, 20, 0.0,
221 YSIZE, YACC+40, "acceleration" );
222 gdImageStringFT( im, NULL, white, FNT, 16, 0.0,
223 YSIZE, YACC+110, "degrees/min^2" );
224
225
226 sprintf( s, "%2.0f", min_acc );
227 gdImageStringFT( im, NULL, white, FNT, 20, 0.0, YSIZE, YACC+80, s );
228
229 sprintf( s, "%2.0f", max_acc );
230 gdImageStringFT( im, NULL, white, FNT, 20, 0.0, gright+5, YACC+80, s );
231
232 cx1 = gscale( angle_acc, min_acc, max_acc ) ;
233 cx2 = gscale( 0, min_acc, max_acc ) ;
234 RectE( im, gleft, YACC+50, gright, YACC+80, white );
235 RectF( im, cx1, YACC+50, cx2, YACC+80, white );
236
237 // angular velocity gauge ---------------------
238
239 gdImageStringFT( im, NULL, white, FNT, 20, 0.0,
240 YSIZE, YVEL+40, "velocity" );
241 gdImageStringFT( im, NULL, white, FNT, 16, 0.0,
242 YSIZE, YVEL+110, "degrees/min" );
243
244 sprintf( s, "%2.0f", min_vel );
245 gdImageStringFT( im, NULL, white, FNT, 20, 0.0, YSIZE, YVEL+80, s );
246
247 sprintf( s, "%2.0f", max_vel );
248 gdImageStringFT( im, NULL, white, FNT, 20, 0.0, gright+5, YVEL+80, s );
249
250 cx1 = gscale( angle_vel, min_vel, max_vel ) ;
251 cx2 = gscale( 0, min_vel, max_vel ) ;
252 RectE( im, gleft, YVEL+50, gright, YVEL+80, white );
253 RectF( im, cx1, YVEL+50, cx2, YVEL+80, white );
254
255 // angle gauge -------------------------------
256
257 gdImageStringFT( im, NULL, white, FNT, 20, 0.0,
258 YSIZE, YANG+40, "angle" );
259 gdImageStringFT( im, NULL, white, FNT, 16, 0.0,
260 YSIZE, YANG+110, "degrees" );
261
262 sprintf( s, "%2.0f", angle_min );
263 gdImageStringFT( im, NULL, white, FNT, 20, 0.0, YSIZE, YANG+80, s );
264
265 sprintf( s, "%2.0f", angle_max );
266 gdImageStringFT( im, NULL, white, FNT, 20, 0.0, gright+5, YANG+80, s );
267
268 cx1 = gscale( angle, angle_min, angle_max ) ;
269 cx2 = gscale( 0, angle_min, angle_max ) ;
270 RectE( im, gleft, YANG+50, gright, YANG+80, white );
271 RectF( im, cx1, YANG+50, cx2, YANG+80, white );
272 }
273
274
275 // draw circle ---------------------------------
276 // uses some globals
277 // fill inner circle with area factor "fill"
278 // draw outer circle with rull radius
279
280 #define NPTS 100
281 gdPoint pointsf[NPTS]; // filled circle points
282 gdPoint pointse[NPTS]; // edge circle points
283
284 void drawcircle( int color, double fill,
285 double centerx, double centery, double radius ) {
286
287 int cntr ;
288 double dangle = (2.0 * PI)/( NPTS-1 );
289 double sradius = radius*sqrt(fill) ;
290 double c, s;
291
292 for( cntr=0 ; cntr < NPTS ; cntr++ ) {
293 c = cos( dangle * cntr ) ;
294 s = sin( dangle * cntr ) ;
295
296 pointsf[cntr] = sr( centerx + sradius*c , centery + sradius*s ) ;
297 pointse[cntr] = sr( centerx + radius*c , centery + radius*s ) ;
298 }
299
300 gdImageFilledPolygon( im, pointsf, NPTS, color );
301 gdImagePolygon( im, pointse, NPTS, color );
302 }
303
304 //=====================================================================
305
306 int main () {
307 FILE *gifout;
308 char comment[80];
309 double timem = 0.0 ;
310 double t1, t2, t3 ;
311 int astep = ASTEP0 ;
312 int y ;
313
314 im1 = gdImageCreate (XSIZE, YSIZE);
315 white = gdImageColorAllocate (im1, 255, 255, 255);
316 black = gdImageColorAllocate (im1, 0, 0, 0);
317 gray = gdImageColorAllocate (im1, 127, 127, 127);
318 dgray = gdImageColorAllocate (im1, 64, 64, 64);
319 trans = gdImageColorAllocate (im1, 1, 1, 1);
320
321 makestars();
322
323 gifout = fopen ( GIFOUT , "wb");
324 // gdImageGifAnimBegin( im1, gifout, 1, -1 ) ; // no repeat
325 // gdImageGifAnimBegin( im1, gifout, 1, 4 ) ; // repeat 4 times
326 gdImageGifAnimBegin( im1, gifout, 1, 0 ) ; // continuous repeat
327
328 for( time = TSTART ; time <= TEND+0.1 ; time += TDELTA ) {
329
330 // accelerate between 0 seconds and 150 seconds
331 // decelerate between 150 seconds and 300 seconds
332 if( time <= 0.0 ) {
333 angle_acc = 0.0 ;
334 angle_vel = 0.0 ;
335 angle = 0.0 ;
336 t1 = 0.5 ;
337 t2 = 0.5 ;
338 t3 = 0.5 ;
339 astep = ASTEP0 ;
340 strcpy( comment, "stopped" );
341 }
342 else if( time < 1.0*TIME1 ) {
343 timem = time/ MINUTE ;
344 angle_acc = ACC ;
345 angle_vel = ACC * timem ;
346 angle = ACC * 0.5 * timem * timem ;
347 t1 = 0.0 ;
348 t2 = 0.0 ;
349 t3 = 1.0 ;
350 astep = ASTEP1 ;
351 strcpy( comment, "accelerating" );
352 }
353 else if( time < 2.0*TIME1 ) {
354 timem = (2.0*TIME1-time)/ MINUTE ;
355 angle_acc = -ACC ;
356 angle_vel = ACC * timem ;
357 angle = angle_max - ( 0.5 * ACC * timem * timem );
358 t1 = 1.0 ;
359 t2 = 1.0 ;
360 t3 = 0.0 ;
361 astep = ASTEP1 ;
362 strcpy( comment, "decelerating" );
363
364 } else {
365 angle_acc = 0.0 ;
366 angle_vel = 0.0 ;
367 angle = angle_max;
368 t1 = 0.5 ;
369 t2 = 0.5 ;
370 t3 = 0.5 ;
371 astep = ASTEP0 ;
372 strcpy( comment, "stopped" );
373 }
374
375 anglerad = DEG2RAD( angle );
376
377 im = gdImageCreate( XSIZE, YSIZE ) ;
378 gdImagePaletteCopy ( im, im1 ) ;
379
380 drawstars(); // draw stars
381 drawgauges(); // draw gauges
382
383 // draw serversat -----------------------------------------------
384
385 gdImageSetThickness( im, LINETHICK );
386
387 drawcircle( dgray, 1.0, 0.0000, 0.0000, 3.0000 );
388 drawcircle( white, t1, -3.4641, 2.0000, 1.0000 );
389 drawcircle( white, t2, 3.4641, 2.0000, 1.0000 );
390 drawcircle( white, t3, 0.0000, -4.0000, 1.0000 );
391
392 gdImageStringFT( im, NULL, white, FNT, 50.0, 0.0, 10, 90, comment );
393
394 // add frame to animation -------------------------------------
395
396 gdImageGifAnimAdd ( im, gifout, 0, 0, 2, astep,
397 gdDisposalRestoreBackground, im1 );
398
399 im0 = im1 ;
400 im1 = im ;
401 gdImageDestroy (im0);
402 }
403
404 gdImageGifAnimEnd(gifout);
405 fclose (gifout);
406 gdImageDestroy (im1);
407 return 0;
408 }
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.