3030 */
3131public class PieRenderer extends SeriesRenderer <PieChart , Segment , SegmentFormatter > {
3232
33+ private static final float FULL_PIE_DEGS = 360f ;
34+ private static final float HALF_PIE_DEGS = 180f ;
35+
3336 // starting angle to use when drawing the first radial line of the first segment.
3437 private float startDegs = 0 ;
3538
3639 // number of degrees to extend from startDegs; can be used to "shape" the pie chart.
37- private float extentDegs = 360 ;
40+ private float extentDegs = FULL_PIE_DEGS ;
3841
3942 // TODO: express donut in units other than px.
4043 private float donutSize = 0.5f ;
@@ -240,7 +243,7 @@ protected PointF calculateLineEnd(float x, float y, float rad, float deg) {
240243
241244 protected PointF calculateLineEnd (PointF origin , float rad , float deg ) {
242245
243- double radians = deg * Math .PI / 180F ;
246+ double radians = deg * Math .PI / HALF_PIE_DEGS ;
244247 double x = rad * Math .cos (radians );
245248 double y = rad * Math .sin (radians );
246249
@@ -292,11 +295,10 @@ public Segment getContainingSegment(PointF point) {
292295 float dx = point .x - origin .x ;
293296 float dy = point .y - origin .y ;
294297 double theta = Math .atan2 (dy , dx );
295- double angle = (theta * (180f / Math .PI ));
298+ double angle = (theta * (HALF_PIE_DEGS / Math .PI ));
296299 if (angle < 0 ) {
297- // convert angle to 0-360 range with 0 being in the
298- // traditional "east" orientation:
299- angle += 360f ;
300+ // bring into 0-360 range
301+ angle += FULL_PIE_DEGS ;
300302 }
301303
302304 // find the segment whose starting and ending angle (degs) contains
@@ -310,10 +312,16 @@ public Segment getContainingSegment(PointF point) {
310312 float lastOffset = offset ;
311313 float sweep = (float ) (scale * (values [i ]) * extentDegs );
312314 offset += sweep ;
313- offset = offset % 360 ;
315+ offset = offset % FULL_PIE_DEGS ;
314316
315317 final double dist = signedDistance (offset , angle );
316- if (dist > 0 && dist <= signedDistance (offset , lastOffset )) {
318+ double endDist = signedDistance (offset , lastOffset );
319+ if (endDist < 0 ) {
320+ // segment accounts for more than 50% of the pie and wrapped around
321+ // need to correct:
322+ endDist = FULL_PIE_DEGS + endDist ;
323+ }
324+ if (dist > 0 && dist <= endDist ) {
317325 return sfPair .getSeries ();
318326 }
319327 i ++;
@@ -328,10 +336,10 @@ public Segment getContainingSegment(PointF point) {
328336 * @return
329337 */
330338 protected static float degsToScreenDegs (float degs ) {
331- degs = degs % 360 ;
339+ degs = degs % FULL_PIE_DEGS ;
332340
333341 if (degs > 0 ) {
334- return 360 - degs ;
342+ return FULL_PIE_DEGS - degs ;
335343 } else {
336344 return degs ;
337345 }
@@ -344,12 +352,12 @@ protected static float degsToScreenDegs(float degs) {
344352 * @return
345353 */
346354 protected static double signedDistance (double angle1 , double angle2 ) {
347- double d = Math .abs (angle1 - angle2 ) % 360 ;
348- double r = d > 180 ? 360 - d : d ;
355+ double d = Math .abs (angle1 - angle2 ) % FULL_PIE_DEGS ;
356+ double r = d > HALF_PIE_DEGS ? FULL_PIE_DEGS - d : d ;
349357
350358 //calculate sign
351- int sign = (angle1 - angle2 >= 0 && angle1 - angle2 <= 180 )
352- || (angle1 - angle2 <= -180 && angle1 - angle2 >= -360 ) ? 1 : -1 ;
359+ int sign = (angle1 - angle2 >= 0 && angle1 - angle2 <= HALF_PIE_DEGS )
360+ || (angle1 - angle2 <= -HALF_PIE_DEGS && angle1 - angle2 >= -FULL_PIE_DEGS ) ? 1 : -1 ;
353361 r *= sign ;
354362 return r ;
355363 }
@@ -359,7 +367,7 @@ protected static double signedDistance(double angle1, double angle2) {
359367 * @param degs
360368 */
361369 protected static void validateInputDegs (float degs ) {
362- if (degs < 0 || degs > 360 ) {
370+ if (degs < 0 || degs > FULL_PIE_DEGS ) {
363371 throw new IllegalArgumentException ("Degrees values must be between 0.0 and 360." );
364372 }
365373 }
0 commit comments