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.
  • [get | view] (2009-03-04 09:32:24, 668.4 KB) [[attachment:light-shift.png]]
  • [get | view] (2009-10-19 16:53:01, 18.4 KB) [[attachment:light-shift1.png]]
  • [get | view] (2009-03-04 00:18:21, 809.8 KB) [[attachment:nav_eastwest.png]]
  • [get | view] (2009-03-10 06:01:57, 10.4 KB) [[attachment:reflect01.png]]
  • [get | view] (2009-03-10 06:08:37, 348.6 KB) [[attachment:reflection_thrust.png]]
  • [get | view] (2009-04-19 01:27:56, 11.8 KB) [[attachment:ss4.c]]
  • [get | view] (2009-04-19 01:28:29, 669.8 KB) [[attachment:ss4.gif]]
  • [get | view] (2009-04-20 19:17:20, 16.0 KB) [[attachment:ss5.c]]
  • [get | view] (2009-04-20 19:17:38, 211.8 KB) [[attachment:ss5.gif]]
  • [get | view] (2009-06-04 04:48:18, 16.5 KB) [[attachment:ss5a.c]]
  • [get | view] (2022-03-15 23:58:04, 223.3 KB) [[attachment:ss5a.png]]
  • [get | view] (2009-06-04 04:48:43, 3085.2 KB) [[attachment:ss5a.swf]]
  • [get | view] (2009-03-04 00:18:47, 549.4 KB) [[attachment:tidal1.png]]
  • [get | view] (2009-03-03 03:31:55, 902.0 KB) [[attachment:tidal1a.png]]
 All files | Selected Files: delete move to page

You are not allowed to attach a file to this page.