#include <stdio.h>#include <values.h>#include <math.h>#include "gdc.h"#include "gdcpie.h"#include <string.h>#include <stdlib.h>Go to the source code of this file.
Data Structures | |
| struct | tmp_slice_t |
Defines | |
| #define | GDC_INCL |
| #define | GDC_LIB |
| #define | SET_RECT(gdp, x1, x2, y1, y2) |
| #define | PX(x) ( cx + (int)( ((float)rad)*sin(pscl*(double)(x)) ) ) |
| #define | PY(x) ( cy - (int)( ((float)rad)*cos(pscl*(double)(x)) ) ) |
| #define | CX(i, d) |
| #define | CY(i, d) |
| #define | IX(i, f, d) ( CX(i,d) + (int)( (double)rad * sin((double)(slice_angle[f][i])) ) ) |
| #define | IY(i, f, d) ( CY(i,d) - (int)( (double)rad * cos((double)(slice_angle[f][i])) ) ) |
| #define | OX(i, o, d) ( CX(i,d) + (int)( (double)rad * sin((double)(o)) ) ) |
| #define | OY(i, o, d) ( CY(i,d) - (int)( (double)rad * cos((double)(o)) ) ) |
| #define | TO_INT_DEG(o) (int)rint( (double)((o)/(2.0*M_PI)*360.0) ) |
| #define | TO_INT_DEG_FLOOR(o) (int)floor( (double)((o)/(2.0*M_PI)*360.0) ) |
| #define | TO_INT_DEG_CEIL(o) (int)ceil( (double)((o)/(2.0*M_PI)*360.0) ) |
| #define | TO_RAD(o) ( (o)/360.0*(2.0*M_PI) ) |
| #define | MOD_2PI(o) ( (o)>=(2.0*M_PI)? ((o)-(2.0*M_PI)): (((o)<0)? ((o)+(2.0*M_PI)): (o)) ) |
| #define | MOD_360(o) ( (o)>=360? (o)-360: (o) ) |
| #define | RAD_DIST1(a) ( (dist_foo1=ABS(((a>-.00001&&a<.00001)?0.00001:a)-pie_3D_rad)), ((dist_foo1>M_PI)? ABS(dist_foo1-2.0*M_PI): dist_foo1) ) |
| #define | RAD_DIST2(a) ( (dist_foo2=ABS(((a>-.00001&&a<.00001)?0.00001:a)-pie_3D_rad)), ((dist_foo2>M_PI)? ABS(dist_foo2-2.0*M_PI): dist_foo2) ) |
Functions | |
| static int | ocmpr (const void *a1, const void *b1) |
| void | pie_gif (short GIFWIDTH, short GIFHEIGHT, FILE *gif_fptr, GDCPIE_TYPE type, int num_points, char **lbl, float *val) |
| void | hola () |
Variables | |
| GDC_FONT_T | GDC_fontc [] |
| static float | pie_3D_rad |
| static float | dist_foo1 |
| static float | dist_foo2 |
| #define CX | ( | i, | |||
| d | ) |
Value:
( cx + \
(d? xdepth_3D: 0) + \
(int)( (double)(GDCPIE_explode?GDCPIE_explode[(i)]:0) * sin((double)(slice_angle[0][i])) ) )
Definition at line 51 of file gdcpie.cpp.
Referenced by pie_gif().
| #define CY | ( | i, | |||
| d | ) |
Value:
( cy - \
(d? ydepth_3D: 0) - \
(int)( (double)(GDCPIE_explode?GDCPIE_explode[(i)]:0) * cos((double)(slice_angle[0][i])) ) )
Definition at line 54 of file gdcpie.cpp.
Referenced by pie_gif().
| #define GDC_INCL |
Definition at line 7 of file gdcpie.cpp.
| #define GDC_LIB |
Definition at line 8 of file gdcpie.cpp.
| #define IX | ( | i, | |||
| f, | |||||
| d | ) | ( CX(i,d) + (int)( (double)rad * sin((double)(slice_angle[f][i])) ) ) |
| #define IY | ( | i, | |||
| f, | |||||
| d | ) | ( CY(i,d) - (int)( (double)rad * cos((double)(slice_angle[f][i])) ) ) |
| #define MOD_2PI | ( | o | ) | ( (o)>=(2.0*M_PI)? ((o)-(2.0*M_PI)): (((o)<0)? ((o)+(2.0*M_PI)): (o)) ) |
| #define MOD_360 | ( | o | ) | ( (o)>=360? (o)-360: (o) ) |
Definition at line 76 of file gdcpie.cpp.
| #define OX | ( | i, | |||
| o, | |||||
| d | ) | ( CX(i,d) + (int)( (double)rad * sin((double)(o)) ) ) |
| #define OY | ( | i, | |||
| o, | |||||
| d | ) | ( CY(i,d) - (int)( (double)rad * cos((double)(o)) ) ) |
| #define PX | ( | x | ) | ( cx + (int)( ((float)rad)*sin(pscl*(double)(x)) ) ) |
Definition at line 48 of file gdcpie.cpp.
| #define PY | ( | x | ) | ( cy - (int)( ((float)rad)*cos(pscl*(double)(x)) ) ) |
Definition at line 49 of file gdcpie.cpp.
| #define RAD_DIST1 | ( | a | ) | ( (dist_foo1=ABS(((a>-.00001&&a<.00001)?0.00001:a)-pie_3D_rad)), ((dist_foo1>M_PI)? ABS(dist_foo1-2.0*M_PI): dist_foo1) ) |
| #define RAD_DIST2 | ( | a | ) | ( (dist_foo2=ABS(((a>-.00001&&a<.00001)?0.00001:a)-pie_3D_rad)), ((dist_foo2>M_PI)? ABS(dist_foo2-2.0*M_PI): dist_foo2) ) |
| #define SET_RECT | ( | gdp, | |||
| x1, | |||||
| x2, | |||||
| y1, | |||||
| y2 | ) |
Value:
gdp[0].x = gdp[3].x = x1, \
gdp[0].y = gdp[1].y = y1, \
gdp[1].x = gdp[2].x = x2, \
gdp[2].y = gdp[3].y = y2
Definition at line 43 of file gdcpie.cpp.
| #define TO_INT_DEG | ( | o | ) | (int)rint( (double)((o)/(2.0*M_PI)*360.0) ) |
| #define TO_INT_DEG_CEIL | ( | o | ) | (int)ceil( (double)((o)/(2.0*M_PI)*360.0) ) |
| #define TO_INT_DEG_FLOOR | ( | o | ) | (int)floor( (double)((o)/(2.0*M_PI)*360.0) ) |
| #define TO_RAD | ( | o | ) | ( (o)/360.0*(2.0*M_PI) ) |
| void hola | ( | ) |
| static int ocmpr | ( | const void * | a1, | |
| const void * | b1 | |||
| ) | [static] |
Definition at line 96 of file gdcpie.cpp.
References tmp_slice_t::angle, pie_3D_rad, RAD_DIST1, RAD_DIST2, and tmp_slice_t::slice.
Referenced by pie_gif().
00097 { 00098 struct tmp_slice_t *a = (tmp_slice_t *)a1; 00099 struct tmp_slice_t *b = (tmp_slice_t *)b1; 00100 if( RAD_DIST1(a->angle) < RAD_DIST2(b->angle) ) 00101 return 1; 00102 if( RAD_DIST1(a->angle) > RAD_DIST2(b->angle) ) 00103 return -1; 00104 00105 /* a tie (will happen between each slice) */ 00106 /* are we within pie_3D_rad */ 00107 if( (a->angle < pie_3D_rad) && (pie_3D_rad < a->slice) || 00108 (a->slice < pie_3D_rad) && (pie_3D_rad < a->angle) ) 00109 return 1; 00110 if( (b->slice < pie_3D_rad) && (pie_3D_rad < b->angle) || 00111 (b->angle < pie_3D_rad) && (pie_3D_rad < b->slice) ) 00112 return -1; 00113 00114 /* let slice angle decide */ 00115 if( RAD_DIST1(a->slice) < RAD_DIST2(b->slice) ) 00116 return 1; 00117 if( RAD_DIST1(a->slice) > RAD_DIST2(b->slice) ) 00118 return -1; 00119 00120 return 0; 00121 }
| void pie_gif | ( | short | GIFWIDTH, | |
| short | GIFHEIGHT, | |||
| FILE * | gif_fptr, | |||
| GDCPIE_TYPE | type, | |||
| int | num_points, | |||
| char ** | lbl, | |||
| float * | val | |||
| ) |
Definition at line 132 of file gdcpie.cpp.
References ABS, tmp_slice_t::angle, cnt_nl(), CX, CY, FALSE, GDC_3DPIE, GDC_fontc, GDC_NOCOLOR, GDCImageStringNL(), GDCPIE_PCT_ABOVE, GDCPIE_PCT_BELOW, GDCPIE_PCT_LEFT, GDCPIE_PCT_NONE, GDCPIE_PCT_RIGHT, gdImageArc(), gdImageCreate(), gdImageDestroy(), gdImageFilledPolygon(), gdImageFillToBorder(), gdImageGif(), gdImageLine(), gdImageString(), tmp_slice_t::hidden, tmp_slice_t::i, IX, IY, load_font_conversions(), MAX, MIN, MOD_2PI, ocmpr(), OX, OY, pie_3D_rad, RAD_DIST1, RAD_DIST2, tmp_slice_t::slice, TO_INT_DEG, TO_INT_DEG_CEIL, TO_INT_DEG_FLOOR, TO_RAD, and TRUE.
Referenced by main().
00139 { 00140 #ifndef WIN32 00141 int i; 00142 00143 gdImagePtr im; 00144 int BGColor, 00145 LineColor, 00146 PlotColor, 00147 EdgeColor, 00148 EdgeColorShd, 00149 SliceColor[num_points], 00150 SliceColorShd[num_points]; 00151 00152 float rad = 0.0; // radius 00153 float tot_val = 0.0; 00154 float pscl; 00155 int cx, // affects PX() 00156 cy; // affects PY() 00157 /* ~ 1% for a size of 100 pixs */ 00158 /* label sizes will more dictate thos */ 00159 float min_grphable = ( GDCPIE_other_threshold < 0? 00160 100.0/(float)MIN(GIFWIDTH,GIFHEIGHT): 00161 (float)GDCPIE_other_threshold )/100.0; 00162 short num_slices1 = 0, 00163 num_slices2 = 0; 00164 char any_too_small = FALSE; 00165 char others[num_points]; 00166 float slice_angle[3][num_points]; // must be used with others[] 00167 char threeD = ( type == GDC_3DPIE ); 00168 00169 int xdepth_3D = 0, // affects PX() 00170 ydepth_3D = 0; // affects PY() 00171 int do3Dx = 0, // reserved for macro use 00172 do3Dy = 0; 00173 00174 // GDCPIE_3d_angle = MOD_360(90-GDCPIE_3d_angle+360); 00175 pie_3D_rad = TO_RAD( GDCPIE_3d_angle ); 00176 00177 xdepth_3D = threeD? (int)( cos((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0; 00178 ydepth_3D = threeD? (int)( sin((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0; 00179 // xdepth_3D = threeD? (int)( cos(pie_3D_rad) * GDCPIE_3d_depth ): 0; 00180 // ydepth_3D = threeD? (int)( sin(pie_3D_rad) * GDCPIE_3d_depth ): 0; 00181 00182 load_font_conversions(); 00183 00184 /* ----- get total value ----- */ 00185 for( i=0; i<num_points; ++i ) 00186 tot_val += val[i]; 00187 00188 /* ----- pie sizing ----- */ 00189 /* ----- make width room for labels, depth, etc.: ----- */ 00190 /* ----- determine pie's radius ----- */ 00191 { 00192 int title_hgt = GDCPIE_title? 1 /* title? horizontal text line */ 00193 + GDC_fontc[GDCPIE_title_size].h 00194 * (int)cnt_nl( GDCPIE_title, (int*)NULL ) 00195 + 2: 00196 0; 00197 float last = 0.0; 00198 float label_explode_limit = 0.0; 00199 int cheight, 00200 cwidth; 00201 00202 // maximum: no labels, explosions 00203 // gotta start somewhere 00204 rad = (float)MIN( GIFWIDTH/2-(1+ABS(xdepth_3D)), GIFHEIGHT/2-(1+ABS(ydepth_3D))-title_hgt ); 00205 00206 /* ok fix center, i.e., no floating re labels, explosion, etc. */ 00207 cx = GIFWIDTH/2 /* - xdepth_3D */ ; 00208 cy = (GIFHEIGHT-title_hgt)/2 + title_hgt /* + ydepth_3D */ ; 00209 00210 cheight = (GIFHEIGHT- title_hgt)/2 /* - ydepth_3D */ ; 00211 cwidth = cx; 00212 00213 /* walk around pie. determine spacing to edge */ 00214 for( i=0; i<num_points; ++i ) 00215 { 00216 float thos_pct = val[i]/tot_val; /* should never be > 100% */ 00217 float thos = thos_pct*(2.0*M_PI); /* pie-portion */ 00218 if( (thos_pct > min_grphable) || /* too small */ 00219 (!GDCPIE_missing || !GDCPIE_missing[i]) ) /* still want angles */ 00220 { 00221 int thos_explode = GDCPIE_explode? GDCPIE_explode[i]: 0; 00222 double thos_sin; 00223 double thos_cos; 00224 slice_angle[0][i] = thos/2.0+last; /* mid-point on full pie */ 00225 slice_angle[1][i] = last; /* 1st on full pie */ 00226 slice_angle[2][i] = thos+last; /* 2nd on full pie */ 00227 thos_sin = sin( (double)slice_angle[0][i] ); 00228 thos_cos = cos( (double)slice_angle[0][i] ); 00229 00230 if( !GDCPIE_missing || !(GDCPIE_missing[i]) ) 00231 { 00232 short lbl_wdth, 00233 lbl_hgt; 00234 float thos_y_explode_limit, 00235 thos_x_explode_limit; 00236 00237 /* start slice label height, width */ 00238 /* accounting for PCT placement, font */ 00239 if( lbl && lbl[i] ) 00240 { 00241 char foo[1+4+1+1]; /* XPG2 compatibility */ 00242 int pct_len; 00243 int lbl_len = 0; 00244 lbl_hgt = ( cnt_nl(lbl[i], &lbl_len) + (GDCPIE_percent_labels == GDCPIE_PCT_ABOVE || 00245 GDCPIE_percent_labels == GDCPIE_PCT_BELOW? 1: 0) ) 00246 * (GDC_fontc[GDCPIE_label_size].h+1); 00247 sprintf( foo, 00248 (GDCPIE_percent_labels==GDCPIE_PCT_LEFT || 00249 GDCPIE_percent_labels==GDCPIE_PCT_RIGHT) && 00250 lbl[i]? "(%.0f%%)": 00251 "%.0f%%", 00252 thos_pct * 100.0 ); 00253 pct_len = GDCPIE_percent_labels == GDCPIE_PCT_NONE? 0: strlen(foo); 00254 lbl_wdth = ( GDCPIE_percent_labels == GDCPIE_PCT_RIGHT || 00255 GDCPIE_percent_labels == GDCPIE_PCT_LEFT? lbl_len+1+pct_len: 00256 MAX(lbl_len,pct_len) ) 00257 * GDC_fontc[GDCPIE_label_size].w; 00258 } 00259 else 00260 lbl_wdth = lbl_hgt = 0; 00261 /* end label height, width */ 00262 00263 /* diamiter limited by thos piont's: explosion, label */ 00264 /* (radius to box @ slice_angle) - (explode) - (projected label size) */ 00265 /* radius constraint due to labels */ 00266 thos_y_explode_limit = (float)thos_cos==0.0? MAXFLOAT: 00267 ( (float)( (double)cheight/ABS(thos_cos) ) - 00268 (float)( thos_explode + (lbl[i]? GDCPIE_label_dist: 0) ) - 00269 (float)( lbl_hgt/2 ) / (float)ABS(thos_cos) ); 00270 thos_x_explode_limit = (float)thos_sin==0.0? MAXFLOAT: 00271 ( (float)( (double)cwidth/ABS(thos_sin) ) - 00272 (float)( thos_explode + (lbl[i]? GDCPIE_label_dist: 0) ) - 00273 (float)( lbl_wdth ) / (float)ABS(thos_sin) ); 00274 00275 rad = MIN( rad, thos_y_explode_limit ); 00276 rad = MIN( rad, thos_x_explode_limit ); 00277 00278 // ok at thos radius (which is most likely larger than final) 00279 // adjust for inter-label spacing 00280 // if( lbl[i] && *lbl[i] ) 00281 // { 00282 // char which_edge = slice_angle[0][i] > M_PI? +1: -1; // which semi 00283 // last_label_yedge = cheight - (int)( (rad + // top or bottom of label 00284 // (float)(thos_explode + 00285 // (float)GDCPIE_label_dist)) * (float)thos_cos ) + 00286 // ( (GDC_fontc[GDCPIE_label_size].h+1)/2 + 00287 // GDC_label_spacing )*which_edge; 00288 // } 00289 00290 /* radius constriant due to exploded depth */ 00291 /* at each edge of the slice, and the middle */ 00292 /* thos is really stupid */ 00293 /* thos section uses a different algorithm then above, but does the same thing */ 00294 /* could be combined, but each is ugly enough! */ 00295 // PROTECT /0 00296 if( threeD ) 00297 { 00298 short j; 00299 int thos_y_explode_pos; 00300 int thos_x_explode_pos; 00301 00302 // first N E S W (actually no need for N) 00303 if( (slice_angle[1][i] < M_PI_2 && M_PI_2 < slice_angle[2][i]) && // E 00304 (thos_x_explode_pos=OX(i,M_PI_2,1)) > cx+cwidth ) 00305 rad -= (float)ABS( (double)(1+thos_x_explode_pos-(cx+cwidth))/sin(M_PI_2) ); 00306 if( (slice_angle[1][i] < 3.0*M_PI_2 && 3.0*M_PI_2 < slice_angle[2][i]) && // W 00307 (thos_x_explode_pos=OX(i,3.0*M_PI_2,1)) < cx-cwidth ) 00308 rad -= (float)ABS( (double)(thos_x_explode_pos-(cx+cwidth))/sin(3.0*M_PI_2) ); 00309 if( (slice_angle[1][i] < M_PI && M_PI < slice_angle[2][i]) && // S 00310 (thos_y_explode_pos=OY(i,M_PI,1)) > cy+cheight ) 00311 rad -= (float)ABS( (double)(1+thos_y_explode_pos-(cy+cheight))/cos(M_PI) ); 00312 00313 for( j=0; j<3; ++j ) 00314 { 00315 thos_y_explode_pos = IY(i,j,1); 00316 if( thos_y_explode_pos < cy-cheight ) 00317 rad -= (float)ABS( (double)((cy-cheight)-thos_y_explode_pos)/cos((double)slice_angle[j][i]) ); 00318 if( thos_y_explode_pos > cy+cheight ) 00319 rad -= (float)ABS( (double)(1+thos_y_explode_pos-(cy+cheight))/cos((double)slice_angle[j][i]) ); 00320 00321 thos_x_explode_pos = IX(i,j,1); 00322 if( thos_x_explode_pos < cx-cwidth ) 00323 rad -= (float)ABS( (double)((cx-cwidth)-thos_x_explode_pos)/sin((double)slice_angle[j][i]) ); 00324 if( thos_x_explode_pos > cx+cwidth ) 00325 rad -= (float)ABS( (double)(1+thos_x_explode_pos-(cx+cwidth))/sin((double)slice_angle[j][i]) ); 00326 } 00327 } 00328 } 00329 others[i] = FALSE; 00330 } 00331 else 00332 { 00333 others[i] = TRUE; 00334 slice_angle[0][i] = -MAXFLOAT; 00335 } 00336 last += thos; 00337 } 00338 } 00339 00340 /* ----- go ahead and start the GIF ----- */ 00341 im = gdImageCreate( GIFWIDTH, GIFHEIGHT ); 00342 00343 /* --- allocate the requested colors --- */ 00344 BGColor = clrallocate( im, GDCPIE_BGColor ); 00345 LineColor = clrallocate( im, GDCPIE_LineColor ); 00346 PlotColor = clrallocate( im, GDCPIE_PlotColor ); 00347 if( GDCPIE_EdgeColor != GDC_NOCOLOR ) 00348 { 00349 EdgeColor = clrallocate( im, GDCPIE_EdgeColor ); 00350 if( threeD ) 00351 EdgeColorShd = clrshdallocate( im, GDCPIE_EdgeColor ); 00352 } 00353 00354 /* --- set color for each slice --- */ 00355 for( i=0; i<num_points; ++i ) 00356 if( GDCPIE_Color ) 00357 { 00358 unsigned long slc_clr = GDCPIE_Color[i]; 00359 00360 SliceColor[i] = clrallocate( im, slc_clr ); 00361 if( threeD ) 00362 SliceColorShd[i] = clrshdallocate( im, slc_clr ); 00363 } 00364 else 00365 { 00366 SliceColor[i] = PlotColor; 00367 if( threeD ) 00368 SliceColorShd[i] = clrshdallocate( im, GDCPIE_PlotColor ); 00369 } 00370 00371 pscl = (2.0*M_PI)/tot_val; 00372 00373 /* ----- calc: smallest a slice can be ----- */ 00374 /* 1/2 circum / num slices per side. */ 00375 /* determined by number of labels that'll fit (height) */ 00376 /* scale to user values */ 00377 /* ( M_PI / (GIFHEIGHT / (SFONTHGT+1)) ) */ 00378 // min_grphable = tot_val / 00379 // ( 2.0 * (float)GIFHEIGHT / (float)(SFONTHGT+1+TFONTHGT+2) ); 00380 00381 00382 if( threeD ) 00383 { 00384 /* draw background shaded pie */ 00385 { 00386 float rad1 = rad; 00387 for( i=0; i<num_points; ++i ) 00388 if( !(others[i]) && 00389 (!GDCPIE_missing || !GDCPIE_missing[i]) ) 00390 { 00391 float rad = rad1; 00392 00393 gdImageLine( im, CX(i,1), CY(i,1), IX(i,1,1), IY(i,1,1), SliceColorShd[i] ); 00394 gdImageLine( im, CX(i,1), CY(i,1), IX(i,2,1), IY(i,2,1), SliceColorShd[i] ); 00395 00396 gdImageArc( im, CX(i,1), CY(i,1), 00397 rad*2, rad*2, 00398 TO_INT_DEG_FLOOR(slice_angle[1][i])+270, 00399 TO_INT_DEG_CEIL(slice_angle[2][i])+270, 00400 SliceColorShd[i] ); 00401 rad1 = rad; 00402 rad *= 3.0/4.0; 00403 gdImageFillToBorder( im, IX(i,0,1), IY(i,0,1), SliceColorShd[i], SliceColorShd[i] ); 00404 rad = rad1; 00405 if( GDCPIE_EdgeColor != GDC_NOCOLOR ) 00406 { 00407 gdImageLine( im, CX(i,1), CY(i,1), IX(i,1,1), IY(i,1,1), EdgeColorShd ); 00408 gdImageLine( im, CX(i,1), CY(i,1), IX(i,2,1), IY(i,2,1), EdgeColorShd ); 00409 gdImageArc( im, CX(i,1), CY(i,1), 00410 rad*2, rad*2, 00411 TO_INT_DEG(slice_angle[1][i])+270, TO_INT_DEG(slice_angle[2][i])+270, 00412 EdgeColorShd); 00413 } 00414 } 00415 } 00416 /* fill in connection to foreground pie */ 00417 /* thos is where we earn our keep */ 00418 { 00419 struct tmp_slice_t tmp_slice[2*num_points+2]; 00420 int t, 00421 num_slice_angles = 0; 00422 00423 for( i=0; i<num_points; ++i ) 00424 if( !GDCPIE_missing || !GDCPIE_missing[i] ) 00425 { 00426 if( RAD_DIST1(slice_angle[1][i]) < RAD_DIST2(slice_angle[0][i]) ) 00427 tmp_slice[num_slice_angles].hidden = FALSE; 00428 else 00429 tmp_slice[num_slice_angles].hidden = TRUE; 00430 tmp_slice[num_slice_angles].i = i; 00431 tmp_slice[num_slice_angles].slice = slice_angle[0][i]; 00432 tmp_slice[num_slice_angles++].angle = slice_angle[1][i]; 00433 if( RAD_DIST1(slice_angle[2][i]) < RAD_DIST2(slice_angle[0][i]) ) 00434 tmp_slice[num_slice_angles].hidden = FALSE; 00435 else 00436 tmp_slice[num_slice_angles].hidden = TRUE; 00437 tmp_slice[num_slice_angles].i = i; 00438 tmp_slice[num_slice_angles].slice = slice_angle[0][i]; 00439 tmp_slice[num_slice_angles++].angle = slice_angle[2][i]; 00440 // identify which 2 slices (i) have a tangent parallel to depth angle 00441 if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+M_PI_2) ) 00442 { 00443 tmp_slice[num_slice_angles].i = i; 00444 tmp_slice[num_slice_angles].hidden = FALSE; 00445 tmp_slice[num_slice_angles].slice = slice_angle[0][i]; 00446 tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+M_PI_2 ); 00447 } 00448 if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+3.0*M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+3.0*M_PI_2) ) 00449 { 00450 tmp_slice[num_slice_angles].i = i; 00451 tmp_slice[num_slice_angles].hidden = FALSE; 00452 tmp_slice[num_slice_angles].slice = slice_angle[0][i]; 00453 tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+3.0*M_PI_2 ); 00454 } 00455 } 00456 00457 qsort( (void *)tmp_slice, num_slice_angles, sizeof(struct tmp_slice_t), ocmpr ); 00458 for( t=0; t<num_slice_angles; ++t ) 00459 { 00460 gdPoint gdp[4]; 00461 00462 i = tmp_slice[t].i; 00463 00464 gdp[0].x = CX(i,0); gdp[0].y = CY(i,0); 00465 gdp[1].x = CX(i,1); gdp[1].y = CY(i,1); 00466 gdp[2].x = OX(i,tmp_slice[t].angle,1); gdp[2].y = OY(i,tmp_slice[t].angle,1); 00467 gdp[3].x = OX(i,tmp_slice[t].angle,0); gdp[3].y = OY(i,tmp_slice[t].angle,0); 00468 00469 if( !(tmp_slice[t].hidden) ) 00470 gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] ); 00471 else 00472 { 00473 rad -= 2.0; /* no peeking */ 00474 gdp[0].x = OX(i,slice_angle[0][i],0); gdp[0].y = OY(i,slice_angle[0][i],0); 00475 gdp[1].x = OX(i,slice_angle[0][i],1); gdp[1].y = OY(i,slice_angle[0][i],1); 00476 rad += 2.0; 00477 gdp[2].x = OX(i,slice_angle[1][i],1); gdp[2].y = OY(i,slice_angle[1][i],1); 00478 gdp[3].x = OX(i,slice_angle[1][i],0); gdp[3].y = OY(i,slice_angle[1][i],0); 00479 gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] ); 00480 gdp[2].x = OX(i,slice_angle[2][i],1); gdp[2].y = OY(i,slice_angle[2][i],1); 00481 gdp[3].x = OX(i,slice_angle[2][i],0); gdp[3].y = OY(i,slice_angle[2][i],0); 00482 gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] ); 00483 } 00484 00485 00486 if( GDCPIE_EdgeColor != GDC_NOCOLOR ) 00487 { 00488 gdImageLine( im, CX(i,0), CY(i,0), CX(i,1), CY(i,1), EdgeColorShd ); 00489 gdImageLine( im, OX(i,tmp_slice[t].angle,0), OY(i,tmp_slice[t].angle,0), 00490 OX(i,tmp_slice[t].angle,1), OY(i,tmp_slice[t].angle,1), 00491 EdgeColorShd ); 00492 } 00493 } 00494 } 00495 } 00496 00497 00498 /* ----- pie face ----- */ 00499 { 00500 // float last = 0.0; 00501 float rad1 = rad; 00502 for( i=0; i<num_points; ++i ) 00503 if( !others[i] && 00504 (!GDCPIE_missing || !GDCPIE_missing[i]) ) 00505 { 00506 float rad = rad1; 00507 00508 // last += val[i]; 00509 // EXPLODE_CX_CY( slice_angle[0][i], i ); 00510 gdImageLine( im, CX(i,0), CY(i,0), IX(i,1,0), IY(i,1,0), SliceColor[i] ); 00511 gdImageLine( im, CX(i,0), CY(i,0), IX(i,2,0), IY(i,2,0), SliceColor[i] ); 00512 00513 gdImageArc( im, CX(i,0), CY(i,0), 00514 (int)rad*2, (int)rad*2, 00515 TO_INT_DEG_FLOOR(slice_angle[1][i])+270, 00516 TO_INT_DEG_CEIL(slice_angle[2][i])+270, 00517 SliceColor[i] ); 00518 rad1 = rad; 00519 rad *= 3.0/4.0; 00520 gdImageFillToBorder( im, IX(i,0,0), IY(i,0,0), SliceColor[i], SliceColor[i] ); 00521 /* catch missed pixels on narrow slices */ 00522 gdImageLine( im, CX(i,0), CY(i,0), IX(i,0,0), IY(i,0,0), SliceColor[i] ); 00523 rad = rad1; 00524 if( GDCPIE_EdgeColor != GDC_NOCOLOR ) 00525 { 00526 gdImageLine( im, CX(i,0), CY(i,0), IX(i,1,0), IY(i,1,0), EdgeColor ); 00527 gdImageLine( im, CX(i,0), CY(i,0), IX(i,2,0), IY(i,2,0), EdgeColor ); 00528 00529 gdImageArc( im, CX(i,0), CY(i,0), 00530 rad*2, rad*2, 00531 TO_INT_DEG(slice_angle[1][i])+270, TO_INT_DEG(slice_angle[2][i])+270, 00532 EdgeColor ); 00533 } 00534 } 00535 } 00536 00537 if( GDCPIE_title ) 00538 { 00539 int title_len; 00540 00541 cnt_nl( GDCPIE_title, &title_len ); 00542 GDCImageStringNL( im, 00543 &GDC_fontc[GDCPIE_title_size], 00544 (GIFWIDTH-title_len*GDC_fontc[GDCPIE_title_size].w)/2, 00545 1, 00546 GDCPIE_title, 00547 LineColor, 00548 GDC_JUSTIFY_CENTER ); 00549 } 00550 00551 /* labels */ 00552 if( lbl ) 00553 { 00554 float liner = rad; 00555 00556 rad += GDCPIE_label_dist; 00557 for( i=0; i<num_points; ++i ) 00558 { 00559 if( !others[i] && 00560 (!GDCPIE_missing || !GDCPIE_missing[i]) ) 00561 { 00562 char pct_str[1+4+1+1]; 00563 int pct_wdth; 00564 int lbl_wdth; 00565 short num_nl = cnt_nl( lbl[i], &lbl_wdth ); 00566 int lblx, pctx, 00567 lbly, pcty, 00568 linex, liney; 00569 00570 lbl_wdth *= GDC_fontc[GDCPIE_label_size].w; 00571 sprintf( pct_str, 00572 (GDCPIE_percent_labels==GDCPIE_PCT_LEFT || 00573 GDCPIE_percent_labels==GDCPIE_PCT_RIGHT) && 00574 lbl[i]? "(%.0f%%)": 00575 "%.0f%%", 00576 (val[i]/tot_val) * 100.0 ); 00577 pct_wdth = GDCPIE_percent_labels == GDCPIE_PCT_NONE? 00578 0: 00579 strlen(pct_str) * GDC_fontc[GDCPIE_label_size].w; 00580 00581 lbly = (liney = IY(i,0,0))-( num_nl * (1+GDC_fontc[GDCPIE_label_size].h) ) / 2; 00582 lblx = pctx = linex = IX(i,0,0); 00583 00584 if( slice_angle[0][i] > M_PI ) /* which semicircle */ 00585 { 00586 lblx -= lbl_wdth; 00587 pctx = lblx; 00588 ++linex; 00589 } 00590 else 00591 --linex; 00592 00593 switch( GDCPIE_percent_labels ) 00594 { 00595 case GDCPIE_PCT_LEFT: if( slice_angle[0][i] > M_PI ) 00596 pctx -= lbl_wdth-1; 00597 else 00598 lblx += pct_wdth+1; 00599 pcty = IY(i,0,0) - ( 1+GDC_fontc[GDCPIE_label_size].h ) / 2; 00600 break; 00601 case GDCPIE_PCT_RIGHT: if( slice_angle[0][i] > M_PI ) 00602 lblx -= pct_wdth-1; 00603 else 00604 pctx += lbl_wdth+1; 00605 pcty = IY(i,0,0) - ( 1+GDC_fontc[GDCPIE_label_size].h ) / 2; 00606 break; 00607 case GDCPIE_PCT_ABOVE: lbly += (1+GDC_fontc[GDCPIE_label_size].h) / 2; 00608 pcty = lbly - (GDC_fontc[GDCPIE_label_size].h); 00609 break; 00610 case GDCPIE_PCT_BELOW: lbly -= (1+GDC_fontc[GDCPIE_label_size].h) / 2; 00611 pcty = lbly + (GDC_fontc[GDCPIE_label_size].h) * num_nl; 00612 break; 00613 case GDCPIE_PCT_NONE: 00614 default: 00615 break; 00616 } 00617 00618 if( GDCPIE_percent_labels != GDCPIE_PCT_NONE ) 00619 gdImageString( im, 00620 GDC_fontc[GDCPIE_label_size].f, 00621 slice_angle[0][i] <= M_PI? pctx: 00622 pctx+lbl_wdth-pct_wdth, 00623 pcty, 00624 (unsigned char *)pct_str, 00625 LineColor ); 00626 if( lbl[i] ) 00627 GDCImageStringNL( im, 00628 &GDC_fontc[GDCPIE_label_size], 00629 lblx, 00630 lbly, 00631 lbl[i], 00632 LineColor, 00633 slice_angle[0][i] <= M_PI? GDC_JUSTIFY_LEFT: 00634 GDC_JUSTIFY_RIGHT ); 00635 if( GDCPIE_label_line ) 00636 { 00637 float rad = liner; 00638 gdImageLine( im, linex, liney, IX(i,0,0), IY(i,0,0), LineColor ); 00639 } 00640 } 00641 } 00642 rad -= GDCPIE_label_dist; 00643 } 00644 00645 gdImageGif(im, gif_fptr); 00646 00647 gdImageDestroy(im); 00648 return; 00649 #endif 00650 }
float dist_foo1 [static] |
Definition at line 88 of file gdcpie.cpp.
float dist_foo2 [static] |
Definition at line 88 of file gdcpie.cpp.
| struct GDC_FONT_T GDC_fontc[] |
Definition at line 11 of file gdc.cpp.
Referenced by load_font_conversions(), out_err(), out_graph(), and pie_gif().
float pie_3D_rad [static] |
1.5.1