Attachment 'echrome04.c'
Download 1 // echrome04.c
2 // compile: gcc -o echrome04 echrome04.c -lgd -lpng -lm
3 //
4 // Plating and unplating an electrochromic thruster
5
6 #define NAME "echrome04"
7 #define RATE 10
8
9 #define FNT "DejaVuMonoSans"
10
11 #define FSZ 20 // this scales the font and the whole drawing
12 #define NPICS 50 //
13
14 #define LINETHICK 1
15 #define XSIZE (60*FSZ)
16 #define YSIZE (32*FSZ)
17 #define WIDE ( 2*FSZ)
18 #define TALL (16*FSZ)
19 #define XCENT (30*FSZ)
20 #define YCENT (16*FSZ)
21 #define ITILT 0.18
22
23 #define ASIZE 2
24
25 #include <gd.h>
26 #include <math.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31
32 #define PI 3.14159265359
33 #define DEG2RAD(x) ((x)*PI/180.)
34
35 // ----------------------------------------------------
36 char rmmkdir[200] ;
37 char pngfmt[ 200] ;
38 double ffrac ; // frame fraction
39 int sign ; // sign of battery
40
41 gdImagePtr im;
42
43 int ytop= YCENT - TALL/2 ;
44 int ybot= YCENT + TALL/2 ;
45 int deltay = (int)( ((double)ITILT)*((double)XCENT) ) ;
46 int black, white, gray ;
47 int red, lred ;
48 int green, lgreen ;
49 int sun1, dgray, trans ;
50 int light[256] ; // Yellow color range
51 int light1 ;
52 double pi2 ; //
53 double atom[1000] ;
54
55 //======================================================================
56
57 //----------------------------------------
58 void atom_init() {
59 int y ;
60 for( y=ytop ; y<= ybot ; y += ASIZE ) {
61 atom[y]=drand48() ;
62 } }
63
64 //----------------------------------------
65 void frame_init() {
66 im = gdImageCreateTrueColor(XSIZE, YSIZE);
67
68 white = gdImageColorAllocate (im, 255, 255, 255);
69 black = gdImageColorAllocate (im, 0, 0, 0);
70 gray = gdImageColorAllocate (im, 127, 127, 127);
71 dgray = gdImageColorAllocate (im, 64, 64, 64);
72 red = gdImageColorAllocate (im, 255, 0, 0);
73 green = gdImageColorAllocate (im, 0, 255, 0);
74 lred = gdImageColorAllocate (im, 255, 224, 224);
75 lgreen = gdImageColorAllocate (im, 224, 255, 224);
76 sun1 = gdImageColorAllocate (im, 0, 51, 102);
77 trans = gdImageColorAllocate (im, 1, 1, 1);
78 }
79
80 //----------------------------------------
81 void light_init() {
82 int i ;
83 int rx, gx, bx ;
84 double di ;
85
86 for( i=0 ; i < 256 ; i++ ) {
87 di = (double) i ;
88 int rx = (double)( di ) ;
89 int gx = (double)( 51.0 + (204.0/256.0) * di ) ;
90 int bx = (double)( 102.0 - (102.0/256.0) * di ) ;
91
92 // printf( "%3d%4d%4d%4d\n", i, rx, gx, bx );
93
94 light[i] = gdImageColorAllocate( im, rx, gx, bx ) ;
95 }
96 sun1 = light[0] ;
97 light1 = light[255] ;
98 }
99
100 //----------------------------------------
101 void draw_background() {
102 gdImageFilledRectangle( im, 0, 0, XSIZE-1, YSIZE-1, sun1 );
103 }
104
105 //----------------------------------------
106 void draw_light() {
107
108 int light01 = light[ 127 ] ;
109
110 // gamma is funny, so this corrects additive light
111 int light02 = light[ ((int)(127.0 * (1.0+0.3*sqrt(ffrac)))) ] ;
112
113 int light03 = light[ ((int)(127.0 * ffrac )) ] ;
114 int light04 = light[ ((int)(127.0 * (1.0-ffrac))) ] ;
115
116 gdPoint alight[8] ;
117
118 // incoming triangle
119 alight[0].x = 0 ;
120 alight[0].y = ytop - deltay ;
121 alight[1].x = 0 ;
122 alight[1].y = ytop + deltay ;
123 alight[2].x = XCENT ;
124 alight[2].y = ytop ;
125 gdImageFilledPolygon( im , alight, 3 , light01 ) ;
126
127 // reflected addition
128 alight[0].x = 0 ;
129 alight[0].y = ytop + deltay ;
130 alight[1].x = 0 ;
131 alight[1].y = ybot - deltay ;
132 alight[2].x = XCENT ;
133 alight[2].y = ybot ;
134 alight[3].x = XCENT ;
135 alight[3].y = ytop ;
136 gdImageFilledPolygon( im , alight, 4 , light02 ) ;
137
138 // reflected triangle
139 alight[0].x = 0 ;
140 alight[0].y = ybot + deltay ;
141 alight[1].x = 0 ;
142 alight[1].y = ybot - deltay ;
143 alight[2].x = XCENT ;
144 alight[2].y = ybot ;
145 gdImageFilledPolygon( im , alight, 3 , light03 ) ;
146
147 // passthrough
148 alight[0].x = XSIZE-1 ;
149 alight[0].y = ytop + deltay ;
150 alight[1].x = XSIZE-1 ;
151 alight[1].y = ybot + deltay ;
152 alight[2].x = XCENT ;
153 alight[2].y = ybot ;
154 alight[3].x = XCENT ;
155 alight[3].y = ytop ;
156 gdImageFilledPolygon( im , alight, 4 , light04 ) ;
157 }
158
159 //----------------------------------------
160 void draw_sun() {
161 gdImageFilledRectangle( im, 0, ytop-deltay, 10, ybot-deltay , light1 );
162 }
163
164 //----------------------------------------
165 void draw_atoms() {
166 int y ;
167 double a = 0.5+(double) XCENT ;
168 double f = ((double)(WIDE-ASIZE))*(1.0-ffrac) ;
169 for( y=ytop ; y< ybot ; y += ASIZE ) {
170 int x = (int)(a+f*atom[y]) ;
171 gdImageFilledRectangle( im, x, y, x+ASIZE, y+ASIZE, white );
172 } }
173
174
175 //----------------------------------------
176 void draw_frame() {
177
178 int ffx, fx1, fx2, ffy, fww, fw2, xcc ;
179 int yb1, yb2, yb3, yb4, yb5 ;
180 int xb0, xb1, xb2, xb3, xb4, xb5 ;
181 int xc0, xc1, xc2, xc3, xc4, xc5 ;
182 int yc1, yc2 ;
183
184 ffx = (int) FSZ ;
185 fx1 = (int) (0.7*FSZ) ;
186 fx2 = (int) (0.5*FSZ) ;
187 ffy = (int) (0.7*FSZ) ;
188 fww = (int) (WIDE) ;
189 fw2 = (int) (WIDE/2) ;
190 xcc = (int) (XCENT) ;
191
192 // printf( "%5d %5d %5d %5d %5d %5d\n", ybot, xcc, ffx, ffy, fx2, fw2 );
193
194 yb1 = ybot + ffy ;
195 yb2 = ybot + 2 * ffy ;
196 yb3 = ybot + 3 * ffy ; // center
197 yb4 = ybot + 4 * ffy ;
198 yb5 = ybot + 5 * ffy ;
199
200 xb0 = xcc - fw2 ;
201 xb1 = xcc + fw2 - fx1 ;
202 xb2 = xb1 + fx2 ;
203 xb3 = xb2 + fx2 ;
204 xb4 = xb3 + fx2 ;
205 xb5 = xcc + fw2 * 3 ;
206
207 xc0 = xcc - 2*fww ;
208 xc1 = xc0 + ffx ;
209 xc2 = xc1 + ffx ;
210 xc3 = xcc + 3*fww ;
211 xc4 = xc3 - ffx ;
212 xc5 = xc4 - ffx ;
213 yc1 = yb3 - ffx ;
214 yc2 = yb3 + ffx ;
215
216 // printf( "%5d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n",
217 // xb0,xb1,xb2,xb3,xb4,xb5, yb1,yb2,yb3,yb4,yb5 );
218
219 gdImageSetThickness( im, 3 );
220 gdImageRectangle( im, xcc-fww, ybot, xcc , ytop, white );
221 gdImageRectangle( im, xcc+fww, ybot, xcc+2*fww, ytop, white );
222
223 // battery
224 gdImageSetThickness( im, 5 );
225
226 gdImageLine( im, xb0, ybot, xb0, yb3, white );
227 gdImageLine( im, xb0, yb3, xb1, yb3, white );
228 gdImageLine( im, xb1, yb1, xb1, yb5, white );
229 gdImageLine( im, xb2, yb2, xb2, yb4, white );
230 gdImageLine( im, xb3, yb1, xb3, yb5, white );
231 gdImageLine( im, xb4, yb2, xb4, yb4, white );
232 gdImageLine( im, xb5, yb3, xb4, yb3, white );
233 gdImageLine( im, xb5, ybot, xb5, yb3, white );
234
235 gdImageSetThickness( im, 7 );
236
237 if( sign == 0 ) {
238 gdImageLine( im, xc0, yb3, xc2, yb3, green );
239 gdImageLine( im, xc1, yc1, xc1, yc2, green );
240 gdImageLine( im, xc3, yb3, xc5, yb3, red );
241 }
242 else if( sign == 1 ) {
243 gdImageLine( im, xc0, yb3, xc2, yb3, red );
244 gdImageLine( im, xc4, yc1, xc4, yc2, green );
245 gdImageLine( im, xc3, yb3, xc5, yb3, green );
246 }
247 gdImageSetThickness( im, 1 );
248 }
249
250 //=====================================================================
251
252 int main () {
253 FILE *pngout ;
254 char comment[80] ;
255 char dirname[80] ;
256 char framename[80] ;
257 int frame ; // frame count
258 int npics ; // last frame count
259 int i ;
260 pi2 = 8.0*atan(1.0) ; // pi
261
262 npics = (double)NPICS ;
263
264 sprintf( rmmkdir, "rm -rf %sdir ; mkdir %sdir", NAME, NAME );
265
266 system( rmmkdir ) ; // make directory
267 atom_init() ; // set up atom points
268
269 for( frame = 0 ; frame <= npics ; frame++ ) {
270
271 printf( "%04d/%04d\r", frame, npics ); fflush( stdout );
272
273 frame_init() ; // set up colors
274 light_init() ;
275
276 // sinusoidal fraction variation
277 ffrac = 0.6*(0.8333-cos( pi2*((double)frame)/npics ));
278
279 if( ffrac < 0.0 ) { sign=-1 ; ffrac=0.0 ; }
280 else if( ffrac > 1.0 ) { sign=-1 ; ffrac=1.0 ; }
281 else if( frame < NPICS/2 ) { sign= 1 ; }
282 else { sign= 0 ; }
283
284 draw_background() ; // draw sunw background
285 draw_light() ; // draw light
286 draw_sun() ; // draw sun
287 draw_atoms() ; // draw atoms
288 draw_frame() ; // draw frame and battery
289
290 /*
291 gdImageStringFT( im, NULL, white, FNT, 1.5*FSZ, 0.0, // TITLE
292 (int)(2.0*FSZ), (int)(2.0*FSZ),
293 "Electrochromic Light Shutter" );
294
295 gdImageStringFT( im, NULL, black, FNT, 0.7*FSZ, 0.0, // TITLE
296 (int)(XCENT+3*WIDE),
297 YSIZE-(int)( 0.5*FSZ),
298 "Polarity(?)" );
299 */
300
301 sprintf( framename, "%sdir/a%04d.png", NAME , frame );
302 pngout = fopen ( framename , "wb");
303 gdImagePngEx( im, pngout, 1 );
304 gdImageDestroy (im);
305 fclose (pngout);
306 } // end of frame loop
307 }
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.