From a4db7e9fd524f8b9b3a05495d22799170b03dc07 Mon Sep 17 00:00:00 2001
From: Olivier Couet <Olivier.Couet@cern.ch>
Date: Thu, 14 Jun 2007 09:17:53 +0000
Subject: [PATCH] - From Guido Volpi:   * Cleanup in TPie and TPieSlice in the
 methods that evaluates if the pointer     is the slice area or in the area.

  * The labels now are not printed over the pie area.

  * Added the SetAngle3D() and GetAngle3D() method to change the perspecive
    angle if the 3d option is used.


git-svn-id: http://root.cern.ch/svn/root/trunk@19029 27541ba8-7e3a-0410-8455-c3a389f83636
---
 graf/inc/TPie.h      |  5 ++-
 graf/inc/TPieSlice.h |  2 --
 graf/src/TPie.cxx    | 81 ++++++++++++++++++++++++--------------------
 3 files changed, 49 insertions(+), 39 deletions(-)

diff --git a/graf/inc/TPie.h b/graf/inc/TPie.h
index d283c66d05e..7c32184fd4c 100644
--- a/graf/inc/TPie.h
+++ b/graf/inc/TPie.h
@@ -1,4 +1,4 @@
-// @(#)root/graf:$Name:  $:$Id: TPie.h,v 1.5 2006/12/11 11:00:27 couet Exp $
+// @(#)root/graf:$Name:  $:$Id: TPie.h,v 1.6 2007/01/24 17:06:21 couet Exp $
 // Author: Guido Volpi, Olivier Couet  03/11/2006
 
 /*************************************************************************
@@ -51,6 +51,7 @@ protected:
    TPieSlice **fPieSlices;      //[fNvals] Slice array of this pie-chart
    Bool_t      fIs3D;           //! true if the pseudo-3d is enabled
    Double_t    fHeight;         // Pheight height of the slice in pixel
+   Float_t     fAngle3D;        // The angle of the pseudo-3d view
 
 public:
    TPie();
@@ -65,6 +66,7 @@ public:
    Int_t          DistancetoSlice(Int_t,Int_t);
    virtual void   Draw(Option_t *option="l"); // *MENU*
    virtual void   ExecuteEvent(Int_t,Int_t,Int_t);
+   Float_t        GetAngle3D() { return fAngle3D; }
    Double_t       GetAngularOffset() { return fAngularOffset; }
    Int_t          GetEntryFillColor(Int_t);
    Int_t          GetEntryFillStyle(Int_t);
@@ -89,6 +91,7 @@ public:
    void           MakeSlices(Bool_t force=kFALSE);
    virtual void   Paint(Option_t *);
    void           SavePrimitive(ostream &out, Option_t *opts="");
+   void           SetAngle3D(Float_t val = 30.); // *MENU*
    void           SetAngularOffset(Double_t);
    void           SetCircle(Double_t x=.5, Double_t y=.5, Double_t rad=.4);
    void           SetEntryLabel(Int_t, const char *text="Slice");
diff --git a/graf/inc/TPieSlice.h b/graf/inc/TPieSlice.h
index c79d3f3a43d..b0a3a495a1e 100644
--- a/graf/inc/TPieSlice.h
+++ b/graf/inc/TPieSlice.h
@@ -31,8 +31,6 @@ class TPieSlice : public TNamed, public TAttFill, public TAttLine {
 
 private:
    Bool_t   fIsActive;        //! True if is the slice under the mouse pointer
-   Int_t    fX[6];            //! The x coordinates, in pixel value, of this slice
-   Int_t    fY[6];            //! The y coordinates, in pixel value, of this slice
 
 protected:
    TPie *fPie;             // The TPie object that contain this slice
diff --git a/graf/src/TPie.cxx b/graf/src/TPie.cxx
index 159cc3078c7..37d2f5ae5e0 100644
--- a/graf/src/TPie.cxx
+++ b/graf/src/TPie.cxx
@@ -1,4 +1,4 @@
-// @(#)root/graf:$Name:  $:$Id: TPie.cxx,v 1.15 2007/03/16 14:58:17 couet Exp $
+// @(#)root/graf:$Name:  $:$Id: TPie.cxx,v 1.16 2007/03/16 15:59:16 couet Exp $
 // Author: Guido Volpi, Olivier Couet 03/11/2006
 
 /*************************************************************************
@@ -177,7 +177,8 @@ Int_t TPie::DistancetoPrimitive(Int_t px, Int_t py)
 
    Int_t dist = 9999;
 
-   if ( (gCurrent_slice = DistancetoSlice(px,py))>=0 ) {
+   gCurrent_slice = DistancetoSlice(px,py);
+   if ( gCurrent_slice>=0 ) {
       if (gCurrent_rad<=fRadius) {
          dist = 0;
       }
@@ -208,13 +209,15 @@ Int_t TPie::DistancetoSlice(Int_t px, Int_t py)
    Double_t radY  = fRadius;
    Double_t radXY = 1.;
    if (fIs3D==kTRUE) {
-      radY  = .5*radX;
-      radXY = .5;
+      radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
+      radY  = radXY*radX;
    }
 
    Double_t phimin;
    Double_t cphi;
    Double_t phimax;
+
+   Float_t dPxl = (gPad->PixeltoY(0)-gPad->PixeltoY(1))/radY;
    for (Int_t i=0;i<fNvals;++i) {
       fPieSlices[i]->SetIsActive(kFALSE);
 
@@ -230,14 +233,16 @@ Int_t TPie::DistancetoSlice(Int_t px, Int_t py)
       Double_t dx  = (xx-fX-radOffset*TMath::Cos(cphi))/radX;
       Double_t dy  = (yy-fY-radOffset*TMath::Sin(cphi)*radXY)/radY;
 
+      if (TMath::Abs(dy)<dPxl) dy = dPxl;
+
       Double_t ang = TMath::ATan2(dy,dx);
       if (ang<0) ang += TMath::TwoPi();
 
       Double_t dist = TMath::Sqrt(dx*dx+dy*dy);
 
       if ( ((ang>=phimin && ang <= phimax) || (phimax>TMath::TwoPi() &&
-             ang+TMath::TwoPi()>=phimin && ang+TMath::TwoPi()<phimax)) &&
-             dist<=1.) { // if true the pointer is in the slice region
+            ang+TMath::TwoPi()>=phimin && ang+TMath::TwoPi()<phimax)) &&
+            dist<=1.) { // if true the pointer is in the slice region
 
          gCurrent_x    = dx;
          gCurrent_y    = dy;
@@ -267,7 +272,6 @@ Int_t TPie::DistancetoSlice(Int_t px, Int_t py)
          break;
       }
    }
-
    return result;
 }
 
@@ -310,8 +314,8 @@ void TPie::DrawGhost()
    Double_t radY  = fRadius;
    Double_t radXY = 1.;
    if (fIs3D) {
-      radY  = .5*radX;
-      radXY = .5;
+      radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
+      radY  = radXY*radX;
    }
 
    for (Int_t i=0;i<fNvals&&fIs3D==kTRUE;++i) {
@@ -406,6 +410,11 @@ void TPie::ExecuteEvent(Int_t event, Int_t px, Int_t py)
    if (!gPad) return;
    if (!gPad->IsEditable() && event != kMouseEnter) return;
 
+   if (gCurrent_slice<=-10) {
+      gPad->SetCursor(kCross);
+      return;
+   }
+
    MakeSlices();
 
    static bool isMovingPie(kFALSE);
@@ -436,8 +445,8 @@ void TPie::ExecuteEvent(Int_t event, Int_t px, Int_t py)
    Double_t radY  = fRadius;
    Double_t radXY = 1.;
    if (fIs3D==kTRUE) {
-      radY  = .5*radX;
-      radXY = .5;
+      radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
+      radY  = radXY*radX;
    }
 
    Int_t dx, dy;
@@ -749,6 +758,7 @@ void TPie::Init(Int_t np, Double_t ao, Double_t x, Double_t y, Double_t r)
    fSlices        = 0;
    fLegend        = 0;
    fHeight        = 0.08;
+   fAngle3D       = 30;
 
    fLabelsOffset = gStyle->GetLabelOffset();
 
@@ -885,7 +895,7 @@ void TPie::Paint(Option_t *option)
    Double_t radXY = 1.;
 
    if (fIs3D) {
-      radXY = .5;
+      radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
       radY = fRadius*radXY;
    }
 
@@ -957,28 +967,6 @@ void TPie::Paint(Option_t *option)
       arc->PaintEllipse(ax, ay, radX, radY, fSlices[2*i],
                                             fSlices[2*i+2], 0.);
 
-      // eval the 6 points to delimit the slice
-      Int_t x[3], y[3];
-      x[0] = gPad->XtoAbsPixel(ax);
-      y[0] = gPad->XtoAbsPixel(ay);
-      x[1] = gPad->XtoAbsPixel(ax+radX*TMath::Cos(fSlices[2*i]/180.*TMath::Pi()));
-      y[1] = gPad->XtoAbsPixel(ay+radX*TMath::Sin(fSlices[2*i]/180.*TMath::Pi()));
-      x[2] = gPad->XtoAbsPixel(ax+radX*TMath::Cos(fSlices[2*i+2]/180.*TMath::Pi()));
-      y[2] = gPad->XtoAbsPixel(ay+radX*TMath::Sin(fSlices[2*i+2]/180.*TMath::Pi()));
-
-      fPieSlices[i]->fX[0] = (x[0]+x[1])/2;
-      fPieSlices[i]->fY[0] = (y[0]+y[1])/2;
-      fPieSlices[i]->fX[1] = x[1];
-      fPieSlices[i]->fY[1] = y[1];
-      fPieSlices[i]->fY[2] = (x[1]+x[2])/2;
-      fPieSlices[i]->fY[2] = (y[1]+y[2])/2;
-      fPieSlices[i]->fX[3] = (x[0]+x[2])/2;
-      fPieSlices[i]->fY[3] = (y[0]+y[2])/2;
-      fPieSlices[i]->fX[5] = x[2];
-      fPieSlices[i]->fY[5] = y[2];
-      fPieSlices[i]->fY[4] = (x[1]+x[2])/2;
-      fPieSlices[i]->fY[4] = (y[1]+y[2])/2;
-
    } // end loop to draw the slices
 
    // Loop to place the labels.
@@ -1040,10 +1028,15 @@ void TPie::Paint(Option_t *option)
             lblang -= TMath::Pi();
          }
       } else { // horizontal labels (default direction)
-         if (aphi>TMath::Pi()/2. && aphi<=TMath::Pi()*3./2.) lx -= w;
-         if (aphi>=TMath::Pi() && aphi<TMath::TwoPi())       ly -= h;
+         aphi = TMath::ATan2(TMath::Sin(aphi)*radXY,TMath::Cos(aphi));
+         if (aphi>TMath::PiOver2() || aphi<=-TMath::PiOver2()) lx -= w;
+         if (aphi<0)                                           ly -= h;
       }
 
+      Float_t rphi = TMath::ATan2((ly-fY)*radXY,lx-fX);
+      if (rphi < 0 && fIs3D && label_off>=0.)
+         ly -= fHeight;
+
       textlabel->PaintLatex(lx,ly,
                             lblang*180/TMath::Pi()+GetTextAngle(),
                             GetTextSize(), tmptxt.Data());
@@ -1179,6 +1172,22 @@ void TPie::SavePrimitive(ostream &out, Option_t *option)
 }
 
 
+
+//______________________________________________________________________________
+void TPie::SetAngle3D(Float_t val) {
+   // Set the value of for the pseudo 3D view angle, in degree.
+   // The range of the permitted values is: [0,90]
+
+   // check if val is in the permitted range
+   while (val>360.) val -= 360.;
+   while (val<0)    val += 360.;
+   if      (val>=90 && val<180)   val = 180-val;
+   else if (val>=180 && val<=360) val = 360-val;
+
+   fAngle3D = val;
+}
+
+
 //______________________________________________________________________________
 void TPie::SetAngularOffset(Double_t offset)
 {
-- 
GitLab