IMG_ARC_PIE and IMG_ARC_CHORD are
mutually exclusive; IMG_ARC_CHORD just
connects the starting and ending angles with a straight line, while
IMG_ARC_PIE produces a rounded edge.
IMG_ARC_NOFILL indicates that the arc
or chord should be outlined, not filled. IMG_ARC_EDGED,
used together with IMG_ARC_NOFILL, indicates that the
beginning and ending angles should be connected to the center - this is a
good way to outline (rather than fill) a 'pie slice'.

if(!$simulate_old_gd && is_callable('imagefilledarc')) { imagefilledarc($diagram, round($width/2), round($height/2), $width, $height, $position, $position+$deg, $color,IMG_ARC_EDGED); } else {// we use some maths to calculate the pixel on the circle$pix_x=round(floor(($width-2)/2)*cos($position/180*M_PI) +round($width/2));$pix_y=round(floor(($height-2)/2)*sin($position/180*M_PI) +round($height/2));// now we draw a line from the mid of the circle to the // calculated pixel on the circleimageline($diagram, round($width/2), round($height/2), $pix_x, $pix_y, $black);// now we need a pixel for flood filling. //- We could use maths to calculate a pixel inside the // piece: //$fill_x=round(floor(($width-10)/2)* // cos(($position+2)/180*M_PI)+round($width/2)); //$fill_y=round(floor(($height-10)/2)* // sin(($position+2)/180*M_PI)+round($height/2)); //- or we could use an universal pixel with less maths ;) // (top mid):$fill_x=floor($width/2)-2;$fill_y=3;// now we flood fill the circle@imagefilltoborder ($diagram,$fill_x,$fill_y,$black,$color);/* (it does not matter here that we fill more than we need because the next pieces will fix this) IF YOU ONLY WANT ONE PIECE (simulate imagefilledarc) you'd have to draw both border lines and flood fill afterwards */}// the position of the next piece is $deg degrees further$position+=$deg; }

Note that imageFilledArc() and imageArc() both take ints as degree measurements. This is no problem if you're *only* using imageArc() and/or imageFilledArc(). However, if you're using calculated degrees and plan to superimpose other drawing elements (eg., you want to make vertical lines between the shadow 3D effect) you need to floor() your degrees before converting them to radians, otherwise you'll get precision errors.

The original code snippet and the following suggestions are inefficient in that they rely on the overlying php to fill vertically using loops rather than taking advantage of the underlying drawing routines. Also, this is done by repeatedly drawing filled partial elipses and circular calculations are typically expensive (PHP may use tables, I'm not sure) The original code could be rewritten as

//Now do the joining pieces.//Note: Precompute cosines and sines for efficiency$c1=50*cos(45/180*M_PI);$s1=25*sin(45/180*M_PI);$c2=50*cos(75/180*M_PI);$s2=25*sin(75/180*M_PI);

$area1=array(100,60,100,50,50+$c1,50+$s1,50+$c1,60+$s1);$area2=array(50+$c1,50+$s1,50+$c1,60+$s1,50+$c2,60+$s2,50+$c2,50+$s2);//Note that piece 3 goes round the corner. So we are only interested in the leftmost extent. You would need to do this programatically. Also, you do not need to make vertical parts for any segments completely at the back of the pie (in fact, not filledarcs either)$area3=array(50+$c2,50+$s2,50+$c2,60+$s2,0,60,0,50);

The examples given so far for drawing a 3D looking pie chart are extremely inefficient and can give a huge performance hit to scripts that draw a lot of pies and in particular those that do offline processing on disk, rather than send a single pie chart to the browser (either way this modification saves you a lot of CPU cycles).

Modify the portion of the code that creates the 3D effect to only draw the outline (with IMG_ARC_NOFILL) of the pie layers below the top filled pie: