Attachment 'ap02.c'
Download 1 // ap02.c
2 // cc -o ap02 ap02.c -lgd -lpng -lm
3 //
4 // Apogee skew Keith Lofstrom May 12, 2009
5 //
6 // FIXED ... apogee skew
7 // at the semiminor points TOWARDS apogee
8 //
9 // Uses the libgd library. For documentation see the file:
10 // /usr/share/doc/gd-*/index.html
11 // or the website:
12 // http://www.libgd.org/Reference
13
14 #define RMMKDIR "rm -rf ap02dir ; mkdir ap02dir"
15 #define PNGFMT "ap02dir/a%04d.png"
16 #define PNG2SWF "png2swf -o ap02.swf -r 20 ap02dir/*.png"
17 #define XSIZE 1000
18 #define YSIZE 600
19 #define YCENTER 360
20 #define SPACE 60
21 #define SIZE 20
22 #define NUM 25
23 #define NUMX 5
24 #define NPICS 200
25 #define ESIZE 90
26 #define ORBSIZE 90
27 #define SSIZE 20
28 #define ZFACTR 0.1
29 #define LAYER 0.8
30 #define PSIZE 6
31 #define TOP 100
32 #define FNT "DejaVuMonoSans"
33 #define FSZ 40
34 #define ASCALE 2.0
35
36 #include <gd.h>
37 #include <math.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40
41 int sun1, white, red, green, blue ; // color indexes
42 int dred, gray, trans, lgray, cyan ;
43 int dgray, yellow, magenta, black ;
44 int dcyan ;
45 int carr[2*NUM];
46 double xarr[NUM];
47 double yarr[NUM];
48 double zarr[NUM];
49 double xdis[NUM]; // scaled and translated x
50 double wdis[NUM]; // unscaled y
51 double ydis[NUM]; // scaled and translated y
52 double zdis[NUM]; // unscaled z
53 double xcenter = XSIZE / 2 ;
54 double ycenter = YCENTER ;
55 int ex = (int) (1.5*ORBSIZE) ;
56 int ey = (int) (1.5*ORBSIZE) ;
57 int re = ESIZE / 2 ;
58
59 double pi2 = 6.283185307 ;
60 gdImagePtr im; // Declare the image
61 FILE *pngout; // Declare output file
62
63 // define colors -----------------------------------------------------------
64 #define CMAX 240
65 #define CSTEP 30
66 #define CCNT 5
67 void colorstart() {
68 int cp, cq, ix, ired, igreen, iblue ;
69 white =gdImageColorAllocate (im, 255, 255, 255);
70 black =gdImageColorAllocate (im, 0, 0, 0);
71 gray =gdImageColorAllocate (im, 128, 128, 128);
72 dgray =gdImageColorAllocate (im, 96, 96, 96);
73 lgray =gdImageColorAllocate (im, 192, 192, 192);
74 cyan =gdImageColorAllocate (im, 0, 192, 192);
75 dcyan =gdImageColorAllocate (im, 0, 48, 48);
76 red =gdImageColorAllocate (im, 255, 0, 0);
77 dred =gdImageColorAllocate (im, 128, 0, 0);
78 yellow =gdImageColorAllocate (im, 255, 255, 0);
79 green =gdImageColorAllocate (im, 0, 255, 0);
80 blue =gdImageColorAllocate (im, 0, 0, 255);
81 magenta =gdImageColorAllocate (im, 192, 0, 192);
82 trans =gdImageColorAllocate (im, 1, 1, 1);
83
84 for( cp=0 ; cp < CCNT ; cp++ ) {
85 for( cq=0 ; cq < CCNT ; cq++ ) {
86 ix = CCNT*cp+cq ;
87 ired = CMAX - CSTEP*( cp + cq ) ;
88 igreen = 2*CSTEP * cp ;
89 iblue = 2*CSTEP * cq ;
90 carr[ ix] = gdImageColorAllocate(im, ired , igreen , iblue );
91 carr[NUM+ix] = gdImageColorAllocate(im, ired/2, igreen/2, iblue/2);
92 }
93 }
94 }
95
96 // set up array positions ---------------------------------------------------
97 void astart() {
98 int ap, aq, ai ;
99 double n = (double) NUM ;
100 double n2 = sqrt( n ) ;
101 int ni = (int) n2 ;
102 double nm = 0.5*(n2-1.0) ;
103
104 for( ap=0 ; ap < ni ; ap++ ) {
105 for( aq=0 ; aq < ni ; aq++ ) {
106 ai = ni * ap + aq ;
107 zarr[ai] = ((double) ap ) - nm ;
108 yarr[ai] = ((double) aq ) - nm ;
109 xarr[ai] = 0.0 ;
110 }
111 }
112 carr[NUM-1]=white ;
113 }
114
115 // draw arrowhead (either degrees or radians ) -----------------------------
116 void arrowhead( double xp, double yp, double asize,
117 double deg, double rad, int color ) {
118 double angl = rad+pi2*deg/360.0 ;
119 gdPoint arrow[3] ;
120
121 arrow[0].x = (int)(xp);
122 arrow[0].y = (int)(yp);
123 arrow[1].x = (int)(xp+asize*( -cos(angl)-0.5*sin(angl)));
124 arrow[1].y = (int)(yp+asize*( 0.5*cos(angl)- sin(angl)));
125 arrow[2].x = (int)(xp+asize*( -cos(angl)+0.5*sin(angl)));
126 arrow[2].y = (int)(yp+asize*(-0.5*cos(angl)- sin(angl)));
127 gdImageFilledPolygon( im, arrow, 3, color );
128 }
129
130 // draw arrow -------------------------------------------------------------
131 void arrow( double x0, double y0, double x1, double y1, int color ) {
132 double asize = 0.02*(x1-x0) ;
133
134 gdImageLine( im, (int)x0, (int)y0, (int)x1, (int)y1, color ) ;
135 arrowhead( x1, y1, 0.02*(x1-x0), 0.0, 0.0, color ) ;
136 }
137
138
139 // draw rotating earth and orbiting body and side arrow -------------
140
141 void earth( double ang ) {
142 double x, y ;
143 double xs, ys ;
144 int x0, y0 ;
145 int x1, y1 ;
146 double an0 ;
147 int i ;
148 int xcnt ;
149 int orbit = 2*ORBSIZE ;
150
151 gdImageFilledArc(im, ex, ey, ESIZE, ESIZE, 0, 360, dcyan, gdArc);
152 gdImageFilledArc(im, ex, ey, ESIZE, ESIZE, 90, 270, cyan, gdArc);
153 gdImageArc( im, ex, ey, orbit, orbit, 30, 330, white );
154 gdImageArc( im, ex, ey, orbit, orbit, 330, 30, dgray );
155
156 // draw longitude lines ( 6 = 180/30 degrees )
157 for( i=0 ; i < 6 ; i++ ) {
158 an0 = (ang/6.0) + pi2*( (double) i ) / 12.0 ;
159 x0 = ex - (int)( ((double)re) * cos(an0 ));
160 x1 = ex + (int)( ((double)re) * cos(an0 ));
161 y0 = ey + (int)( ((double)re) * sin(an0 ));
162 y1 = ey - (int)( ((double)re) * sin(an0 ));
163 gdImageLine( im, x0, y0, x1, y1, black );
164 }
165
166 // draw latitude lines
167 for( i=1 ; i < 3 ; i++ ) {
168 an0 = pi2*( (double) i ) / 12.0 ;
169 x0 = (int)( 2.0 * ((double)re) * cos(an0) );
170 gdImageArc( im, ex, ey, x0, x0, 0, 360, black );
171 }
172
173 // draw arrowhead to show side point of view
174 x= -ORBSIZE - 2.0*PSIZE ;
175 y= 0.0 ;
176 xs = x*cos(ang)+y*sin(ang) + (double) ex ;
177 ys = y*cos(ang)-x*sin(ang) + (double) ey ;
178
179 arrowhead( xs, ys, 2*PSIZE, 0.0, -ang, white );
180 }
181
182 // ========================================================================
183
184 int main() {
185 double angle ;
186 int i ;
187 int xcnt ;
188 int frame ;
189 char pngfilename[64];
190
191 double test ; // depth testing
192 int ox, oy ;
193 int s0 ;
194
195 double xu, yu ;
196 int xi, yi ;
197 int icol ;
198 double deg ;
199
200 system( RMMKDIR );
201
202 for( frame = 0 ; frame < NPICS ; frame++ ) {
203 im = gdImageCreateTrueColor(XSIZE, YSIZE );
204 sprintf( pngfilename, PNGFMT, frame );
205 pngout = fopen( pngfilename, "wb");
206
207 angle = frame * pi2 / NPICS ;
208 colorstart() ;
209 astart() ;
210 earth(angle) ;
211
212 // labels -----------------------------------------------------------
213
214 gdImageStringFT( im, NULL, // imagespace, bounding
215 white, FNT, FSZ, // color, font, fontsize
216 0.0, 0.00*XSIZE, 0.98*YSIZE, // angle, x, y
217 " Side View" ); // the text
218
219 gdImageStringFT( im, NULL, // imagespace, bounding
220 white, FNT, FSZ/2, // color, font, fontsize
221 0.0, 0.25*XSIZE, 0.27*YSIZE, // angle, x, y
222 " Top View" ); // the text
223
224 gdImageStringFT( im, NULL, // imagespace, bounding
225 white, FNT, FSZ/2, // color, font, fontsize
226 0.0, 0.50*XSIZE, 0.27*YSIZE, // angle, x, y
227 " Front View" ); // the text
228
229 gdImageStringFT( im, NULL, // imagespace, bounding
230 white, FNT, FSZ/2, // color, font, fontsize
231 0.0, 0.71*XSIZE, 0.27*YSIZE, // angle, x, y
232 " Side View" ); // the text
233
234 // time code -------------------------------------------------------
235
236 double time0 = ( 4.0 * (double) frame ) / ( (double) NPICS ) ;
237 char timestring[64] ;
238
239 sprintf( timestring, "%3.1f/4.0 hours, 1440x speedup", time0 );
240
241 gdImageStringFT( im, NULL, // imagespace, bounding
242 white, FNT, 0.6*FSZ, // color, font, fontsize
243 0.0, XSIZE-14.0*FSZ, // angle, x
244 0.98*YSIZE, timestring ); // y, the text
245
246 // direction arrows ------------------------------------------------
247
248 arrow( 0.00*XSIZE, ycenter, 0.96*XSIZE, ycenter, lgray );
249 arrow( 0.26*XSIZE, 0.25*ycenter, 0.50*XSIZE, 0.25*ycenter, lgray );
250 arrow( 0.71*XSIZE, 0.25*ycenter, 0.95*XSIZE, 0.25*ycenter, lgray );
251
252 // draw main view from top ----------------------------------------
253 for( i=0 ; i < NUM ; i++ ) {
254 zdis[i] =-cos(angle)*zarr[i]-sin(angle)*yarr[i] ;
255 wdis[i] = cos(angle)*yarr[i]-sin(angle)*zarr[i];
256 ydis[i] = ycenter - SPACE*wdis[i];
257 xdis[i] = xcenter + SPACE*(2.0*zdis[i]-0.5*NUMX) ;
258 }
259
260
261 for( test = -5.0*LAYER ; test < 5.0*LAYER ; test += LAYER ) {
262 for( i=0 ; i < NUM ; i++ ) {
263 for( xcnt = 0 ; xcnt < NUMX ; xcnt++ ) {
264 if( ( zdis[i] >= test ) && ( zdis[i] < ( test+LAYER ) ) ) {
265
266 // small top view
267 s0 = (int) ( 0.35*SIZE * (1.00 + ZFACTR * zdis[i] ) ) ;
268 ox = (int) ( 0.26*XSIZE + 0.25*(SPACE*xcnt+xdis[i]) );
269 oy = (int) ( 0.25*ydis[i] );
270 gdImageFilledArc(im, ox, oy, s0, s0, 0, 360, carr[i], gdArc);
271
272 // draw points in top orbit representation
273
274 xu = -ORBSIZE - ASCALE * wdis[i] ;
275 yu = ASCALE * ( ((double)xcnt) + 2.0*zdis[i]-0.5*NUMX );
276
277 xi = ex + (int)( xu*cos(angle)+yu*sin(angle)) ;
278 yi = ey + (int)( yu*cos(angle)-xu*sin(angle)) ;
279
280 if( ( xi < ex )
281 ||( yi < ( ey-re ) )
282 ||( yi > ( ey+re ) ) ) icol = carr[ i];
283 else icol = carr[NUM+i];
284
285 gdImageFilledArc( im, xi, yi, 3, 3, 0, 360, icol, gdArc );
286 }
287
288 if( ( wdis[i] >= test ) && ( wdis[i] < ( test+LAYER ) ) ) {
289 // main side view
290 s0 = (int) ( SIZE * (1.00 + ZFACTR * wdis[i] ) ) ;
291 ox = (int) ( SPACE*xcnt+xdis[i]);
292 oy = (int) ( ycenter-SPACE*zdis[i]) ;
293 gdImageFilledArc(im, ox, oy, s0, s0, 0, 360, carr[i], gdArc);
294
295 // small side view
296 s0 = (int) ( 0.35*SIZE * (1.00 + ZFACTR * wdis[i] ) ) ;
297 ox = (int) ( 0.71*XSIZE + 0.25*(SPACE*xcnt+xdis[i]));
298 oy = (int) ( 0.25*(ycenter-SPACE*zdis[i]) ) ;
299 gdImageFilledArc(im, ox, oy, s0, s0, 0, 360, carr[i], gdArc);
300 }
301 }
302
303 // small front view - apogee to left, closer
304 s0 = (int) ( 0.35*SIZE * (1.30 + 2.0* ZFACTR * zdis[i] ) ) ;
305 ox = (int) ( 0.60*XSIZE - 0.25*SPACE*wdis[i] );
306 oy = (int) ( 0.25*( ycenter -SPACE*zdis[i] ) );
307 gdImageFilledArc(im, ox, oy, s0, s0, 0, 360, carr[i], gdArc);
308 }
309 }
310
311 /* Output the frame in PNG format. */
312 gdImagePngEx( im, pngout, 1 );
313 gdImageDestroy(im);
314 fclose(pngout);
315 }
316
317 system( PNG2SWF );
318 }
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.