Attachment 'ss6a.c'
Download 1 // ss6a.c
2 // compile: gcc -o ss6a ss6a.c -lgd -lpng -lm
3 //
4 // The perspective sucks
5 // The light pressure of tilted thrusters is treated here as constant.
6 // The actual light pressure is proportional to cos^2( sun angle )
7 // This assumes a 4:3 ratio, with gauges down the right side
8
9 #define NAME "ss6a"
10 #define RATE 10
11
12 #define FNT "DejaVuMonoSans"
13 #define SCALE 0.7 // size of serversat relative to YSIZE
14
15 #define FSZ 26 // this scales the font and the whole drawing
16
17 #define Z0 24.0 // depth scaling for cheesy perspective
18 #define ACC 8.0 // acceleration in degrees/minute^2
19 #define TSTART -60.0 //
20 #define TIME1 150.0 // acceleration time in seconds
21 #define TIME2 (2.0*TIME1) // deceleration time
22 #define TEND 360.0 //
23 #define TDELTA 2.0 // display timestep
24 #define NSTARS 500 // background stars (this shows transparency)
25 #define MOVE 0.3 // how much the background stars move
26 #define THICK 5 // dummy thickness in pixels
27 #define FILTER 0.3 //
28
29 #define LINETHICK 1
30 #define XSIZE 1024
31 #define YSIZE 768
32 #define RIGHT (YSIZE-20)
33 #define MINUTE 60.0
34 #define HOUR 3600.0
35 #define MINUTES (TIME1/MINUTE)
36
37 #include "gd.h"
38 #include <math.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <sys/stat.h>
42 #include <sys/types.h>
43
44
45 #define PI 3.14159265359
46 #define DEG2RAD(x) ((x)*PI/180.)
47
48 // #define WIRING 1 // show solar cell wires
49
50 // ----------------------------------------------------
51 char rmmkdir[200] ;
52 char pngfmt[ 200] ;
53 char png2swf[200] ;
54
55 gdImagePtr im;
56 int black, white, gray ;
57 int lred, lgreen ;
58 int dgray, trans ;
59 int xgauge=(XSIZE+YSIZE)/2 ;// down the right edge
60 double scale ; // scale serversat in pixels
61
62 int spdcolor ;
63 int yellow[256] ; // Yellow color range
64 // starting values
65 int rate = RATE ;
66
67 double ang = 0.0 ; // angle in radians
68 double angc ; // cos(ang)
69 double angs ; // sin(ang)
70 double angt ; // tan(ang)
71
72 // | bottom | front | top | back |
73 // an2 -135 -45 +45 +135 -135
74 // an2a - + + -
75 // an2b + + - -
76
77 double an2 ; // double ang
78 double pi4 ; //
79 double pi ; //
80 double an2c ; // cos(an2)
81 double an2s ; // sin(an2)
82 double an2a ; // an2 test a
83 double an2b ; // an2 test b
84
85 double time = 0.0 ;
86 double angle_vel = 0.0 ;
87 double angle_acc = 0.0 ;
88 double angle = 0.0 ;
89
90 double min_vel = 0.0 ;
91 double max_vel = ACC*TIME1/MINUTE ;
92 double angle_min = 0.0 ;
93 double angle_max = ACC*TIME1*TIME1/(MINUTE*MINUTE);
94 double min_acc = -ACC ;
95 double max_acc = ACC ;
96
97 double thick = THICK ;
98
99 //--------------------------------------------------------------------
100 // fixed rectangle subroutines, swap order if needed
101 // gdImageRectangle silently fails unless it gets left, bottom, right, top
102
103 void RectE( gdImagePtr imm,
104 double rx1, double ry1, double rx2, double ry2, int rcolor ) {
105 if( rx1 < rx2 ) {
106 if( ry1 < ry2 ) {
107 gdImageRectangle( imm, rx1, ry1, rx2, ry2, rcolor );
108 } else {
109 gdImageRectangle( imm, rx1, ry2, rx2, ry1, rcolor );
110 }
111 } else {
112 if( ry1 < ry2 ) {
113 gdImageRectangle( imm, rx2, ry1, rx1, ry2, rcolor );
114 } else {
115 gdImageRectangle( imm, rx2, ry2, rx1, ry1, rcolor );
116 }
117 }
118 }
119
120
121 void RectF( gdImagePtr imm,
122 double rx1, double ry1, double rx2, double ry2, int rcolor ) {
123 if( rx1 < rx2 ) {
124 if( ry1 < ry2 ) {
125 gdImageFilledRectangle( imm, rx1, ry1, rx2, ry2, rcolor );
126 } else {
127 gdImageFilledRectangle( imm, rx1, ry2, rx2, ry1, rcolor );
128 }
129 } else {
130 if( ry1 < ry2 ) {
131 gdImageFilledRectangle( imm, rx2, ry1, rx1, ry2, rcolor );
132 } else {
133 gdImageFilledRectangle( imm, rx2, ry2, rx1, ry1, rcolor );
134 }
135 }
136 }
137
138 // draw gauges ---------------------------------
139 // uses globals
140
141 #define YCLOCK (4*FSZ)
142 #define YACC (10*FSZ)
143 #define YVEL (16*FSZ)
144 #define YANG (22*FSZ)
145 #define F2 (4*FSZ/5)
146 #define F4 (FSZ/4)
147
148 #define RCLOCK (3*FSZ+8)
149 #define SECHAND (3*FSZ)
150 #define MINHAND1 (2*FSZ)
151 #define MINHAND2 (2*FSZ+5)
152 #define MINWID 40
153
154 int gleft = YSIZE + 2*FSZ ;
155 int gright = XSIZE - 2*FSZ ;
156
157
158 int gscale( double gvar, double gmin, double gmax ) {
159 return ( (int) ( gleft + (gvar-gmin)
160 * ( (double)(gright-gleft))/(gmax-gmin) ) ) ;
161 }
162
163 void drawgauges() {
164
165 double wangle ; // working angle
166 int cx1, cy1, cx2, cy2 ;
167 char s[80];
168 int ic ;
169 double ltime = time ;
170 if( ltime < 0.0 ) { ltime = 0.0 ; }
171 if( ltime > TIME2 ) { ltime = TIME2 ; }
172
173 // clock at xgauge, 100 -----------------------------
174
175 gdImageArc( im, xgauge, YCLOCK, 2*RCLOCK, 2*RCLOCK, 0, 360, white );
176
177 // clock / 60
178 for( ic = 0; ic < 60 ; ic += 1 ) {
179 wangle = PI * ic / 30 ;
180 if ( ic%15 == 0 ) {
181 cx1 = xgauge + (int)(0.5 + (RCLOCK-6)*sin(wangle)) ;
182 cy1 = YCLOCK - (int)(0.5 + (RCLOCK-6)*cos(wangle)) ;
183 }
184 else if( ic%5 == 0 ) {
185 cx1 = xgauge + (int)(0.5 + (RCLOCK-4)*sin(wangle)) ;
186 cy1 = YCLOCK - (int)(0.5 + (RCLOCK-4)*cos(wangle)) ;
187 }
188 else {
189 cx1 = xgauge + (int)(0.5 + (RCLOCK-2)*sin(wangle)) ;
190 cy1 = YCLOCK - (int)(0.5 + (RCLOCK-2)*cos(wangle)) ;
191 }
192 cx2 = xgauge + (int)(0.5 + RCLOCK *sin(wangle) ) ;
193 cy2 = YCLOCK - (int)(0.5 + RCLOCK *cos(wangle) ) ;
194 gdImageLine( im, cx1, cy1, cx2, cy2, white ) ;
195 }
196
197 // second hand
198 wangle = 2.0 * PI * ltime / MINUTE ;
199 cx1 = xgauge+(int)(0.5 + SECHAND*sin(wangle) ) ;
200 cy1 = YCLOCK-(int)(0.5 + SECHAND*cos(wangle) ) ;
201 gdImageLine( im, xgauge, YCLOCK, cx1, cy1, white ) ;
202
203
204 // minute hand (two strokes )
205 wangle = 2.0 * PI * (ltime + MINWID) / HOUR ;
206 cx1 = xgauge+(int)(0.5 + MINHAND1*sin(wangle) ) ;
207 cy1 = YCLOCK-(int)(0.5 + MINHAND1*cos(wangle) ) ;
208
209 wangle = 2.0 * PI * (ltime ) / HOUR ;
210 cx2 = xgauge+(int)(0.5 + MINHAND2*sin(wangle) ) ;
211 cy2 = YCLOCK-(int)(0.5 + MINHAND2*cos(wangle) ) ;
212 gdImageLine( im, xgauge, YCLOCK, cx1, cy1, white ) ;
213 gdImageLine( im, cx2, cy2, cx1, cy1, white );
214
215 wangle = 2.0 * PI * (ltime - MINWID) / HOUR ;
216 cx1 = xgauge+(int)(0.5 + MINHAND1*sin(wangle) ) ;
217 cy1 = YCLOCK-(int)(0.5 + MINHAND1*cos(wangle) ) ;
218 gdImageLine( im, cx2, cy2, cx1, cy1, white );
219 gdImageLine( im, xgauge, YCLOCK, cx1, cy1, white ) ;
220
221 // text clock
222
223 sprintf( s, "%3.0f secs", ltime );
224 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0, xgauge-2*FSZ, 9*FSZ, s );
225
226 // angular acceleration gauge ----------------
227
228 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0,
229 YSIZE, YACC+2*FSZ-F4, "acceleration" );
230 gdImageStringFT( im, NULL, white, FNT, F2, 0.0,
231 YSIZE, YACC+5*FSZ, "degrees/min^2" );
232
233
234 sprintf( s, "%2.0f", min_acc );
235 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0, YSIZE, YACC+4*FSZ, s );
236
237 sprintf( s, "%2.0f", max_acc );
238 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0, gright+F4, YACC+4*FSZ, s );
239
240 cx1 = gscale( angle_acc, min_acc, max_acc ) ;
241 cx2 = gscale( 0, min_acc, max_acc ) ;
242 RectE( im, gleft, YACC+2*FSZ, gright, YACC+4*FSZ, white );
243 RectF( im, cx1, YACC+2*FSZ, cx2, YACC+4*FSZ, white );
244
245 // angular velocity gauge ---------------------
246
247 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0,
248 YSIZE, YVEL+2*FSZ-F4, "velocity" );
249 gdImageStringFT( im, NULL, white, FNT, F2, 0.0,
250 YSIZE, YVEL+5*FSZ, "degrees/min" );
251
252 sprintf( s, "%2.0f", min_vel );
253 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0, YSIZE, YVEL+4*FSZ, s );
254
255 sprintf( s, "%2.0f", max_vel );
256 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0, gright+F4, YVEL+4*FSZ, s );
257
258 cx1 = gscale( angle_vel, min_vel, max_vel ) ;
259 cx2 = gscale( 0, min_vel, max_vel ) ;
260 RectE( im, gleft, YVEL+2*FSZ, gright, YVEL+4*FSZ, white );
261 RectF( im, cx1, YVEL+2*FSZ, cx2, YVEL+4*FSZ, white );
262
263 // angle gauge -------------------------------
264
265 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0,
266 YSIZE, YANG+2*FSZ-F4, "angle" );
267 gdImageStringFT( im, NULL, white, FNT, F2, 0.0,
268 YSIZE, YANG+5*FSZ, "degrees" );
269
270 sprintf( s, "%2.0f", angle_min );
271 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0, YSIZE, YANG+4*FSZ, s );
272
273 sprintf( s, "%2.0f", angle_max );
274 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0, gright+F4, YANG+4*FSZ, s );
275
276 cx1 = gscale( angle, angle_min, angle_max ) ;
277 cx2 = gscale( 0, angle_min, angle_max ) ;
278 RectE( im, gleft, YANG+2*FSZ, gright, YANG+4*FSZ, white );
279 RectF( im, cx1, YANG+2*FSZ, cx2, YANG+4*FSZ, white );
280 }
281
282
283
284 //----------------------------------------
285 // this draws dots on the upper left edge, useful for scaling sizes in
286 // openoffice
287 void lineofdots() {
288 int ctr;
289 for( ctr=0; ctr < XSIZE; ctr +=4 ) {
290 gdImageSetPixel( im, ctr, 0, gray );
291 gdImageSetPixel( im, ctr, 1, gray );
292 gdImageSetPixel( im, 0, ctr, gray );
293 gdImageSetPixel( im, 1, ctr, gray );
294 }
295 }
296
297
298 // SERVERSAT drawing tools
299 //----------------------------------------
300 // serversat globals
301
302 int thx, thy ;
303 int x, y ;
304 gdPoint rbox[4] ;
305 int light[RIGHT][YSIZE] ;
306 double xcent, ycent ;
307 int ly[10] ; // levels
308 int back[10] ; // backside light level
309
310 //----------------------------------------
311 int y2x( int yy ) {
312 return (int)( xcent-angt*(((double)yy)-ycent) ) ;
313 }
314
315 //----------------------------------------
316 int f2y( double yy ) {
317 return (int)(ycent-angc*yy*scale) ;
318 }
319
320 //---------------------------------------
321 void chunk( int ya, int yb, int color ) {
322 if( ya != yb ) {
323 int xa = y2x(ya) ;
324 int xb = y2x(yb) ;
325
326 rbox[0].x = xa - thx ;
327 rbox[0].y = ya - thy ;
328 rbox[1].x = xa + thx ;
329 rbox[1].y = ya + thy ;
330 rbox[2].x = xb + thx ;
331 rbox[2].y = yb + thy ;
332 rbox[3].x = xb - thx ;
333 rbox[3].y = yb - thy ;
334 gdImageFilledPolygon( im, rbox, 4, color ) ;
335 } }
336
337 //---------------------------------------
338 //
339 gdPoint arotate( double rang, int xr, int yr, double rx, double ry ) {
340 gdPoint ret;
341 ret.x = xr + (int)( rx*cos(rang) - ry*sin(rang) ) ;
342 ret.y = yr + (int)( ry*cos(rang) + rx*sin(rang) ) ;
343
344 return ret ;
345 }
346
347 //---------------------------------------
348 // x y angle size
349
350 void arrow ( int acolor, int xa, int ya, double aang, double asize ) {
351 gdPoint apoly[7] ;
352 if( asize > thick ) { // point away
353 apoly[0]=arotate( aang, xa, ya, 3.0*thick + asize, 0.0 );
354 apoly[1]=arotate( aang, xa, ya, 2.0*thick + asize, -1.0*thick );
355 apoly[2]=arotate( aang, xa, ya, 2.0*thick + asize, -0.5*thick );
356 apoly[3]=arotate( aang, xa, ya, 2.0*thick , -0.5*thick );
357 apoly[4]=arotate( aang, xa, ya, 2.0*thick , 0.5*thick );
358 apoly[5]=arotate( aang, xa, ya, 2.0*thick + asize, 0.5*thick );
359 apoly[6]=arotate( aang, xa, ya, 2.0*thick + asize, 1.0*thick );
360 gdImageFilledPolygon( im, apoly, 7, acolor );
361 }
362 else if( asize < -thick ) { // point towards
363 apoly[0]=arotate( aang, xa, ya, 2.0*thick , 0.0 );
364 apoly[1]=arotate( aang, xa, ya, 3.0*thick , -1.0*thick );
365 apoly[2]=arotate( aang, xa, ya, 3.0*thick , -0.5*thick );
366 apoly[3]=arotate( aang, xa, ya, 3.0*thick - asize, -0.5*thick );
367 apoly[4]=arotate( aang, xa, ya, 3.0*thick - asize, 0.5*thick );
368 apoly[5]=arotate( aang, xa, ya, 3.0*thick , 0.5*thick );
369 apoly[6]=arotate( aang, xa, ya, 3.0*thick , 1.0*thick );
370 gdImageFilledPolygon( im, apoly, 7, acolor );
371 }
372 }
373
374 //----------------------------------------
375 // scale is Y/2
376 // drawn in RIGHT*YSIZE panel
377
378 void drawserversat( double t1, double t2 ) {
379
380 int cline = black ; // line color
381
382 scale = 0.5*SCALE*((double)YSIZE) ; // distance from center to top
383 ycent = 0.55*((double)YSIZE) ;
384 xcent = 0.5*((double)RIGHT) ;
385
386 int xline ; // serversat centerline x val
387 int i ;
388 int yellow[256] ;
389 int xx1, xx2 ;
390 int yy1, yy2 ;
391 int yyt, yyb ;
392 int xxl, xxr ;
393 int xxa ;
394 int xy ;
395
396 // fill color array -------
397
398 yellow[0] = gdImageColorAllocate( im, 0, 0, 0 );
399 yellow[1] = gdImageColorAllocate( im, 224, 192, 0 );
400 yellow[2] = gdImageColorAllocate( im, 255, 224, 0 );
401 yellow[3] = gdImageColorAllocate( im, 255, 255, 127 );
402 yellow[4] = gdImageColorAllocate( im, 255, 255, 192 );
403
404 // establish l levels ---------------------------
405 // The below are "pixel" lines
406 ly[0]=0 ; // top of drawing
407 back[0]=1 ;
408 ly[1]=f2y( 1.0 ) ; // top of top thruster
409 back[1]=1 ;
410 ly[2]=f2y( 0.75 +0.25*t2 ) ; // top of top thruster reflective
411 back[2]=0 ;
412 ly[3]=f2y( 0.75 -0.25*t2 ) ; // bot of top thruster reflective
413 back[3]=1 ;
414 ly[4]=f2y( 0.5 ) ; // top of solar cell
415 back[4]=0 ;
416 ly[5]=f2y( -0.5 ) ; // bot of solar cell
417 back[5]=1 ;
418 ly[6]=f2y( -0.75 +0.25*t1 ) ; // top of bot thruster reflective
419 back[6]=0 ;
420 ly[7]=f2y( -0.75 -0.25*t1 ) ; // bot of bot thruster reflective
421 back[7]=1 ;
422 ly[8]=f2y( -1.0 ) ; // bot of bot thruster
423 back[8]=1 ;
424 ly[9]=YSIZE ; // bottom of drawing
425 back[9]=1 ;
426
427 // printf( "%3.0f%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d\n",
428 // angle, thx, thy, ly[1],ly[2],ly[3],ly[4],ly[5],ly[6],ly[7],ly[8] );
429
430 // draw light ------------------------------
431
432 // work down through the levels
433 for( i = 0; i < 9 ; i++ ) {
434 yy1 = ly[ i ] ;
435 yy2 = ly[ i+1 ] ;
436
437 if( yy2 > yy1 ) {
438 if( back[ i ] == 1 ) {
439 for( y=yy1 ; y<yy2 ; y++ ) {
440 for( x=0 ; x<RIGHT ; x++ ) {
441 light[x][y] = 1 ;
442 } } }
443 else {
444 for( y=yy1 ; y<yy2 ; y++ ) {
445 xy = y2x( y ) ;
446 if( 0 < xy ) {
447 for( x=0 ; x < xy ; x++ ) {
448 light[x][y] = 1 ;
449 } }
450 if( xy < RIGHT ) {
451 for( x=xy ; x < RIGHT ; x++ ) {
452 light[x][y] = 0 ;
453 } }
454 } } } }
455
456 // add off axis reflections ---------------------
457
458 for( i = 2 ; i < 9 ; i += 4 ) { // 2 and 6, cheesy
459 if( ly[i] != ly[i+1] ) { // if beamwidth greater than 0
460
461 yy1 = ly[i] ;
462 yy2 = ly[i+1] ;
463 xx1 = y2x(yy1) ;
464 xx2 = y2x(yy2) ;
465
466 // | bottom | front | top | back |
467 // an2 -135 -45 +45 +135 -135
468 // an2a - + + -
469 // an2b + + - -
470
471 if( an2a > 0.0 ) { // front or top
472 if( an2b > 0.0 ) {
473
474 // front -----------------------------------
475 if( xx1 > xx2 ) { // front above
476 xxa = xx1 ;
477 } else { // front below
478 xxa = xx2 ;
479 }
480
481 for( x=0 ; x < xxa ; x++ ) {
482 yyt = yy1 - (int)( (an2s/an2c)*(xx1-x) ) ;
483 if( yyt < 0 ) { yyt = 0 ; }
484 yyb = yy2 - (int)( (an2s/an2c)*(xx2-x) ) ;
485 if( yyb > YSIZE-1 ) { yyb = YSIZE-1 ; }
486 if( ( yyb > 0 ) && ( yyt < YSIZE-1) ) {
487 for( y=yyt ; y <= yyb ; y++ ) {
488 if( x < y2x( y ) ) {
489 light[x][y]++ ;
490 } } } } } // end of front
491
492 else {
493
494 // top -----------------------------------
495 for( y=0 ; y < yy2 ; y++ ) { // yy2 is always back
496 xxl = xx2 - (int)( (an2c/an2s)*(yy2-y) ) ;
497 if( xxl < 0 ) { xxl = 0 ; }
498 xxr = xx1 - (int)( (an2c/an2s)*(yy1-y) ) ;
499 if( xxr > RIGHT ) { xxr = RIGHT ; }
500 if( (xxr>=0) && (xxl<=RIGHT) ) {
501 for( x=xxl; x <= xxr ; x++ ) {
502 if( x < y2x( y ) ) {
503 light[x][y]++ ;
504 } } } } } } // end of top
505
506 else { // back or bottom
507 if( an2b > 0.0 ) { // bottom
508
509 // top -----------------------------------
510 for( y=yy1 ; y < YSIZE ; y++ ) { // yy1 is always back
511 xxl = xx1 - (int)( (an2c/an2s)*(yy1-y) ) ;
512 if( xxl < 0 ) { xxl = 0 ; }
513 xxr = xx2 - (int)( (an2c/an2s)*(yy2-y) ) ;
514 if( xxr > RIGHT ) { xxr = RIGHT ; }
515 if( (xxr>=0) && (xxl<=RIGHT) ) {
516 for( x=xxl; x <= xxr ; x++ ) {
517 if( x < y2x( y ) ) {
518 light[x][y]++ ;
519 } } } } } // end of bottom
520
521 else { // back
522 // MORE LATER BACK
523 } } } }
524
525 // add front light -----------------------------
526 for( x=0 ; x<10 ; x++ ) {
527 for( y=0 ; y<YSIZE ; y++ ) {
528 light[x][y] += 2 ;
529 } }
530
531 // emit light -----------------------------------
532 for( x=0 ; x<RIGHT ; x++ ) {
533 for( y=0 ; y<YSIZE ; y++ ) {
534 gdImageSetPixel( im, x, y, yellow[light[x][y]] ) ;
535 } }
536
537 // draw serversat chunks ------------------------------
538
539 thick = THICK ;
540 thx=(int)(0.5*thick*angc) ;
541 thy=(int)(0.5*thick*angs) ;
542
543 chunk( ly[2], ly[3], white ) ; // draw upper reflector middle
544 chunk( ly[4], ly[5], dgray ) ; // draw solar cell
545 chunk( ly[6], ly[7], white ) ; // draw lower reflector middle
546
547 // draw serversat lines -------------------------------
548
549 rbox[0].x = y2x(ly[1])-thx ;
550 rbox[0].y = ly[1] -thy ;
551 rbox[1].x = y2x(ly[1])+thx ;
552 rbox[1].y = ly[1] +thy ;
553 rbox[2].x = y2x(ly[8])+thx ;
554 rbox[2].y = ly[8] +thy ;
555 rbox[3].x = y2x(ly[8])-thx ;
556 rbox[3].y = ly[8] -thy ;
557 gdImagePolygon( im, rbox, 4, cline );
558
559 // draw light and force arrows
560 // x y angle size
561 arrow( white, y2x(f2y( 0.73)), f2y( 0.73), pi, -0.3*scale*t2 ) ;
562 arrow( white, y2x(f2y( 0.77)), f2y( 0.77), pi+an2, 0.3*scale*t2 ) ;
563 arrow( white, y2x(f2y( 0.75)), f2y( 0.75), ang, 0.6*angc*scale*t2 ) ;
564
565 arrow( white, y2x(f2y(-0.77)), f2y(-0.77), pi, -0.3*scale*t1 ) ;
566 arrow( white, y2x(f2y(-0.73)), f2y(-0.73), pi+an2, 0.3*scale*t1 ) ;
567 arrow( white, y2x(f2y(-0.75)), f2y(-0.75), ang, 0.6*angc*scale*t1 ) ;
568
569 /*
570 // draw fixed pivot arrow
571
572 thick = 2*FSZ ;
573 yy1 = f2y(0.0) ;
574 xx1 = y2x(yy1) - (int)( 2.0*thick ) ;
575 arrow( dgray, xx1, yy1, 0, -8.0*FSZ ) ;
576 yy1 += (int)( 0.5* FSZ );
577 xx1 = y2x(yy1) + (int)( 0.5*thick ) ;
578 gdImageStringFT( im, NULL, white, FNT, FSZ, 0.0, xx1, yy1, "fixed pivot" );
579 thick = THICK ;
580 */
581
582 }
583
584 //=====================================================================
585
586 int main () {
587 FILE *pngout;
588 char comment[80] ;
589 char dirname[80] ;
590 char framename[80] ;
591 double timem ; // time in minutes
592 double t1p, t2p ;
593 double t1, t2 ; // thrust value for each cell
594 int frame ; // frame count
595 int npics ; // last frame count
596 int i ;
597
598 npics = (10*(TEND-TSTART)+1)/(10*TDELTA) ; // a bit extra for rounding err
599 pi4 = atan(1.0) ; // pi/4 , 45 degrees
600 pi = 4.0*pi4 ; // pi
601
602 // makestars();
603
604 sprintf( rmmkdir, "rm -rf %sdir ; mkdir %sdir", NAME, NAME );
605
606 // make directory
607 system( rmmkdir );
608
609 for( frame = 0 ; frame <= npics ; frame++ ) {
610
611 printf( "%04d/%04d\r", frame, npics );
612 fflush( stdout );
613
614 im = gdImageCreateTrueColor(XSIZE, YSIZE);
615 white = gdImageColorAllocate (im, 255, 255, 255);
616 black = gdImageColorAllocate (im, 0, 0, 0);
617 gray = gdImageColorAllocate (im, 127, 127, 127);
618 dgray = gdImageColorAllocate (im, 64, 64, 64);
619 lred = gdImageColorAllocate (im, 255, 208, 208);
620 lgreen =gdImageColorAllocate (im, 208, 255, 208);
621 trans = gdImageColorAllocate (im, 1, 1, 1);
622
623 thick = THICK ;
624
625 time = TDELTA*( (double) frame ) + TSTART ;
626 sprintf( framename, "%sdir/a%04d.png", NAME , frame );
627 pngout = fopen ( framename , "wb");
628
629 // start out stopped, display for a while
630 if( time <= 0.0 ) {
631 angle_acc = 0.0 ;
632 angle_vel = 0.0 ;
633 angle = 0.0 ;
634 t1p = 0.5 ;
635 t2p = 0.5 ;
636 t1 = 0.5 ;
637 t2 = 0.5 ;
638 spdcolor = white ;
639 strcpy( comment, "stopped" );
640 }
641
642 // accelerate between 0 seconds and TIME1 seconds
643 else if( time < 1.0*TIME1 ) {
644 timem = time/ MINUTE ;
645 angle_acc = ACC ;
646 angle_vel = ACC * timem ;
647 angle = ACC * 0.5 * timem * timem ;
648 t1p = 0.05 ;
649 t2p = 0.95 ;
650 spdcolor = lgreen ;
651 strcpy( comment, "speed up" );
652 }
653
654 // decelerate between TIME1 seconds and 2*TIME1 seconds
655 else if( time < 2.0*TIME1 ) {
656 timem = (2.0*TIME1-time)/ MINUTE ;
657 angle_acc = -ACC ;
658 angle_vel = ACC * timem ;
659 angle = angle_max - (0.5*ACC*timem*timem );
660 t1p = 0.95 ;
661 t2p = 0.05 ;
662 spdcolor = lred ;
663 strcpy( comment, "slow down" );
664 }
665 // end up stopped, display for a while
666 else {
667 angle_acc = 0.0 ;
668 angle_vel = 0.0 ;
669 angle = angle_max;
670 t1p = 0.5 ;
671 t2p = 0.5 ;
672 spdcolor = white ;
673 strcpy( comment, "stopped" );
674 }
675
676 t1 += FILTER*(t1p-t1 );
677 t2 += FILTER*(t2p-t2 );
678
679 ang = DEG2RAD( angle ) ; //
680 angc = cos(ang) ; //
681 angs = sin(ang) ; //
682 angt = tan(ang) ; //
683 an2 = 2.0*ang ; // double angle for reflection
684
685 // | bottom | front | top | back |
686 // an2 -135 -45 +45 +135 -135
687 // an2a - + + -
688 // an2b + + - -
689
690 an2c = cos(an2) ; //
691 an2s = sin(an2) ; //
692 an2a = cos(an2-pi4) ; // +if -45 < a2 < 135
693 an2b = cos(an2+pi4) ; // +if -135 < a2 < 45
694
695 // draw serversat -----------------------------------------------
696
697 drawserversat( t1, t2 );
698
699 // draw panel and other things ---------------------------------
700
701 lineofdots(); // calibration strips
702 drawgauges(); // draw gauges
703
704 // status text -------------------------------------------------
705
706 /*
707 gdImageStringFT( im, NULL, spdcolor,FNT, 2*FSZ, 0.0,
708 FSZ, (int)(2.5*FSZ), comment );
709 */
710
711 // output frame to directory in PNG format
712
713 gdImagePngEx( im, pngout, 1 );
714 gdImageDestroy (im);
715 fclose (pngout);
716 }
717
718 sprintf( png2swf, "png2swf -o %s.swf -r%3d %sdir/*.png", NAME, rate, NAME );
719 system( png2swf );
720 }
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.