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