#include <ctype.h>
#include <assert.h>
#include "Riostream.h"
#include "TMath.h"
#include "TList.h"
#include "TClass.h"
#include "TAxis3D.h"
#include "TCanvas.h"
#include "TPad.h"
#include "TGaxis.h"
#include "TView.h"
#include "TVirtualPad.h"
#include "TVirtualX.h"
#include "TBrowser.h"
#include "TStyle.h"
const Char_t *TAxis3D::fgRulerName = "axis3druler";
ClassImp(TAxis3D)
TAxis3D::TAxis3D() : TNamed(TAxis3D::fgRulerName,"ruler")
{
   
   fSelected = 0;
   fZoomMode = kFALSE;
   fStickyZoom = kFALSE;
   InitSet();
}
TAxis3D::TAxis3D(Option_t *) : TNamed(TAxis3D::fgRulerName,"ruler")
{
   
   fSelected = 0;
   InitSet();
   fZoomMode = kFALSE;
   fStickyZoom = kFALSE;
}
TAxis3D::TAxis3D(const TAxis3D &axis) : TNamed(axis)
{
   
   ((TAxis3D&)axis).Copy(*this);
}
void TAxis3D::Copy(TObject &obj) const
{
   
   TNamed::Copy(obj);
   for (Int_t i=0;i<2;i++) fAxis[i].Copy(((TAxis3D&)obj).fAxis[i]);
}
void TAxis3D::InitSet()
{
   
   fAxis[0].SetName("xaxis");
   fAxis[1].SetName("yaxis");
   fAxis[2].SetName("zaxis");
   fAxis[0].Set(1,0.,1.);
   fAxis[1].Set(1,0.,1.);
   fAxis[2].Set(1,0.,1.);
   UseCurrentStyle();
}
void TAxis3D::Browse(TBrowser *b)
{
   
   for (Int_t i=0;i<3;i++) b->Add(&fAxis[i],fAxis[i].GetTitle());
}
Int_t TAxis3D::DistancetoPrimitive(Int_t px, Int_t py)
{
   
   Int_t dist = 9;
   for (int i=0;i<3;i++) {
      Int_t axDist = fAxis[i].DistancetoPrimitive(px,py);
      if (dist > axDist) { dist = axDist; fSelected = &fAxis[i]; }
   }
   if (fZoomMode)
      return 0;
   else
      return dist;
}
void TAxis3D::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   
   
   
   if (fSelected) fSelected->ExecuteEvent(event,px,py);
   
   static Double_t x0, y0, x1, y1;
   static Int_t pxold, pyold;
   static Int_t px0, py0;
   static Int_t linedrawn;
   if (!fZoomMode) return;
   
   gPad->SetCursor(kCross);
   switch (event) {
   case kButton1Down:
      gVirtualX->SetLineColor(-1);
      gPad->TAttLine::Modify();  
      ((TPad *)gPad)->AbsPixeltoXY(px,py,x0,y0);
      px0   = px; py0   = py;
      pxold = px; pyold = py;
      linedrawn = 0;
      break;
   case kButton1Motion:
      if (linedrawn) gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
      pxold = px;
      pyold = py;
      linedrawn = 1;
      gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
      break;
   case kButton1Up: {
      Int_t i;
      gPad->SetDoubleBuffer(1);
      gVirtualX->SetDrawMode(TVirtualX::kCopy); 
      TView *view = gPad->GetView();
      if (!view) break;                       
      Double_t min[3],max[3],viewCenter[3],viewCenterNDC[3];
      view->GetRange(min,max);
      for (i =0; i<3;i++) viewCenter[i] = (max[i]+min[i])/2;
      view->WCtoNDC(viewCenter,viewCenterNDC);
      
      Double_t center[3],pointNDC[3],size[3],oldSize[3];
      ((TPad *)gPad)->AbsPixeltoXY(px,py,x1,y1);
      pointNDC[0] = (x0+x1)/2; pointNDC[1] = (y0+y1)/2;
      pointNDC[2] = viewCenterNDC[2];
      view->NDCtoWC(pointNDC, center);
      for (i =0; i<3;i++) oldSize[i] = size[i]= (max[i]-min[i])/2;
      
      if (TMath::Abs(px-px0)+TMath::Abs(py - py0) > 4 ) {
         Double_t newEdge[3];
         for (i =0; i<3;i++) size[i] = -1;
         pointNDC[0] = x0; pointNDC[1] = y0;
         view->NDCtoWC(pointNDC, newEdge);
         for (i =0; i<3;i++) {
            Double_t newSize = TMath::Abs(newEdge[i]-center[i]);
            if ( newSize/oldSize[i] > 0.002)
               size[i] = TMath::Max(size[i], newSize);
            else
               size[i] = oldSize[i];
         }
         pointNDC[0] = x1; pointNDC[1] = y1;
         view->NDCtoWC(pointNDC, newEdge);
         for (i =0; i<3;i++) {
            Double_t newSize = TMath::Abs(newEdge[i]-center[i]);
            if ( newSize/oldSize[i] > 0.002)
               size[i] = TMath::Max(size[i], newSize);
            else
               size[i] = oldSize[i];
         }
#if 0
         if (fZooms == kMAXZOOMS) fZoom = 0;
         fZooms++;
         memcpy(fZoomMin[fZooms],min,3*sizeof(Float_t));
         memcpy(fZoomMax[fZooms],max,3*sizeof(Float_t));
#endif
      }
      for (i =0; i<3;i++) {
         max[i] = center[i] + size[i];
         min[i] = center[i] - size[i];
      }
      view->SetRange(min,max);
      if(!fStickyZoom)SwitchZoom();
         gPad->Modified(kTRUE);
         gPad->Update();
         break;
      }
      default: break;
   }
}
char *TAxis3D::GetObjectInfo(Int_t , Int_t ) const
{
   
   
   return (char*)"axis3d";
}
void TAxis3D::Paint(Option_t *)
{
   
   TGaxis axis;
   PaintAxis(&axis, 90);
}
void TAxis3D::PaintAxis(TGaxis *axis, Float_t ang)
{
   
   
   
   
   
   static Double_t epsil = 0.001;
   Double_t cosa, sina;
   Double_t bmin, bmax;
   Double_t r[24]       ;
   Int_t ndiv, i;
   Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24]  ;
   char chopax[8];
   Int_t ix1, ix2, iy1, iy2, iz1, iz2;
   Double_t rad;
   TView *view = gPad->GetView();
   if (!view) {
      Error("PaintAxis", "no TView in current pad");
      return;
   }
   rad  = TMath::ATan(1.) * 4. / 180.;
   cosa = TMath::Cos(ang*rad);
   sina = TMath::Sin(ang*rad);
   view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
   for (i = 1; i <= 8; ++i) {
      r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
      r[i*3 - 2] = av[i*3 - 2]*sina;
      r[i*3 - 1] = av[i*3 - 1];
   }
   view->WCtoNDC(&r[ix1*3 - 3], x1);
   view->WCtoNDC(&r[ix2*3 - 3], x2);
   view->WCtoNDC(&r[iy1*3 - 3], y1);
   view->WCtoNDC(&r[iy2*3 - 3], y2);
   view->WCtoNDC(&r[iz1*3 - 3], z1);
   view->WCtoNDC(&r[iz2*3 - 3], z2);
   view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
   Double_t *rmin = view->GetRmin();
   Double_t *rmax = view->GetRmax();
   axis->SetLineWidth(1);
   for (i=0;i<3;i++) {
      
      Double_t ax[2], ay[2];
      Bool_t logAx = kFALSE;
      memset(chopax,0,sizeof(chopax));
      switch (i) {
         case 0 :
            ax[0] = x1[0]; ax[1] = x2[0];
            ay[0] = x1[1]; ay[1] = x2[1];
            logAx = gPad->GetLogx();
            break;
         case 1 :
            if (TMath::Abs(y1[0] - y2[0]) < epsil)  y2[0] = y1[0];
            ax[0] = y1[0]; ax[1] = y2[0];
            ay[0] = y1[1]; ay[1] = y2[1];
            logAx = gPad->GetLogy();
            break;
         case 2 :
            ax[0] = z1[0]; ax[1] = z2[0];
            ay[0] = z1[1]; ay[1] = z2[1];
            strcpy(chopax, "SDH+=");
            logAx = gPad->GetLogz();
            break;
         default:
            assert(0);
            continue;
      };
      
      if ( ( TMath::Abs(ax[0] - ax[1]) + TMath::Abs(ay[0] - ay[1]))  < epsil  ) continue;
      if (i != 2 ) {
         if (ax[0] > ax[1]) strcpy(chopax, "SDHV=+");
         else               strcpy(chopax, "SDHV=-");
      }
      if (i==1 && (TMath::Abs(z1[0] - z2[0]) + TMath::Abs(z1[1] - z2[1])) < epsil)
         strcpy(chopax, "SDH+=");
      
      if (logAx) {
         strcat(chopax,"G");
         bmin = TMath::Power(10, rmin[i]);
         bmax = TMath::Power(10, rmax[i]);
      } else {
         bmin = rmin[i];
         bmax = rmax[i];
      }
      axis->SetLineColor(  fAxis[i].GetAxisColor());
      axis->SetTextFont(   fAxis[i].GetTitleFont());
      axis->SetTextColor(  fAxis[i].GetTitleColor());
      axis->SetTickSize(   fAxis[i].GetTickLength());
      axis->SetLabelColor( fAxis[i].GetLabelColor());
      axis->SetLabelFont(  fAxis[i].GetLabelFont());
      axis->SetLabelOffset(fAxis[i].GetLabelOffset()+fAxis[i].GetTickLength());
      axis->SetLabelSize(  fAxis[i].GetLabelSize());
      axis->SetTitle(      fAxis[i].GetTitle());
      axis->SetTitleOffset(fAxis[i].GetTitleOffset());
      axis->SetTitleSize(  fAxis[i].GetTitleSize());
      enum { kCenterTitle = BIT(12) }; 
      axis->SetBit(kCenterTitle, fAxis[i].TestBit(kCenterTitle));
      
      
      ndiv = fAxis[i].GetNdivisions();
      if (ndiv < 0) {
         ndiv = -ndiv;
         chopax[6] = 'N';
      }
      
      if (fAxis[i].GetTimeDisplay()) {
         strcat(chopax,"t");
         if (strlen(fAxis[i].GetTimeFormatOnly()) == 0) {
            axis->SetTimeFormat(fAxis[i].ChooseTimeFormat(bmax-bmin));
         } else {
            axis->SetTimeFormat(fAxis[i].GetTimeFormat());
         }
      }
      axis->SetOption(chopax);
      axis->PaintAxis(ax[0], ay[0], ax[1], ay[1], bmin, bmax, ndiv, chopax);
   }
}
Double_t *TAxis3D::PixeltoXYZ(Double_t px, Double_t py, Double_t *point3D, TView *view)
{
   
   
   Double_t *thisPoint = 0;
   if (!view && gPad) view = gPad->GetView();
   if (view) {
      Double_t x[3] = {px,py,0.5}; 
      Double_t min[3], max[3];
      view->GetRange(min,max);
      Int_t i;
      for (i =0; i<3;i++) min[i] = (max[i]+min[i])/2;
      view->WCtoNDC(min,max);
      min[0] = x[0]; min[1] = x[1];
      min[2] = max[2];
      view->NDCtoWC(min, x);
      for (i=0;i<3;i++) point3D[i] = x[i];
      thisPoint = point3D;
   }
   return thisPoint;
}
void TAxis3D::SavePrimitive(ostream &out, Option_t * )
{
   
   fAxis[0].SaveAttributes(out,GetName(),"->GetXaxis()");
   fAxis[1].SaveAttributes(out,GetName(),"->GetYaxis()");
   fAxis[2].SaveAttributes(out,GetName(),"->GetZaxis()");
}
void TAxis3D::UseCurrentStyle()
{
   
   if (gStyle->IsReading()) {
      fAxis[0].ResetAttAxis("X");
      fAxis[1].ResetAttAxis("Y");
      fAxis[2].ResetAttAxis("Z");
      fAxis[0].SetTitle("x");
      fAxis[0].SetLabelColor(kRed);   fAxis[0].SetAxisColor(kRed);
      fAxis[1].SetLabelColor(kGreen); fAxis[1].SetAxisColor(kGreen);
      fAxis[2].SetLabelColor(kBlue);  fAxis[2].SetAxisColor(kBlue);
   } else {
      gStyle->SetNdivisions (fAxis[0].GetNdivisions(), "x");
      gStyle->SetAxisColor  (fAxis[0].GetAxisColor(),  "x");
      gStyle->SetLabelColor (fAxis[0].GetLabelColor(), "x");
      gStyle->SetLabelFont  (fAxis[0].GetLabelFont(),  "x");
      gStyle->SetLabelOffset(fAxis[0].GetLabelOffset(),"x");
      gStyle->SetLabelSize  (fAxis[0].GetLabelSize(),  "x");
      gStyle->SetTickLength (fAxis[0].GetTickLength(), "x");
      gStyle->SetTitleOffset(fAxis[0].GetTitleOffset(),"x");
      gStyle->SetTitleSize  (fAxis[0].GetTitleSize(),  "x");
      gStyle->SetTitleColor (fAxis[0].GetTitleColor(), "x");
      gStyle->SetTitleFont  (fAxis[0].GetTitleFont(),  "x");
      gStyle->SetNdivisions (fAxis[1].GetNdivisions(), "y");
      gStyle->SetAxisColor  (fAxis[1].GetAxisColor(),  "y");
      gStyle->SetLabelColor (fAxis[1].GetLabelColor(), "y");
      gStyle->SetLabelFont  (fAxis[1].GetLabelFont(),  "y");
      gStyle->SetLabelOffset(fAxis[1].GetLabelOffset(),"y");
      gStyle->SetLabelSize  (fAxis[1].GetLabelSize(),  "y");
      gStyle->SetTickLength (fAxis[1].GetTickLength(), "y");
      gStyle->SetTitleOffset(fAxis[1].GetTitleOffset(),"y");
      gStyle->SetTitleSize  (fAxis[1].GetTitleSize(),  "y");
      gStyle->SetTitleColor (fAxis[1].GetTitleColor(), "y");
      gStyle->SetTitleFont  (fAxis[1].GetTitleFont(),  "y");
      gStyle->SetNdivisions (fAxis[2].GetNdivisions(), "z");
      gStyle->SetAxisColor  (fAxis[2].GetAxisColor(),  "z");
      gStyle->SetLabelColor (fAxis[2].GetLabelColor(), "z");
      gStyle->SetLabelFont  (fAxis[2].GetLabelFont(),  "z");
      gStyle->SetLabelOffset(fAxis[2].GetLabelOffset(),"z");
      gStyle->SetLabelSize  (fAxis[2].GetLabelSize(),  "z");
      gStyle->SetTickLength (fAxis[2].GetTickLength(), "z");
      gStyle->SetTitleOffset(fAxis[2].GetTitleOffset(),"z");
      gStyle->SetTitleSize  (fAxis[2].GetTitleSize(),  "z");
      gStyle->SetTitleColor (fAxis[2].GetTitleColor(), "z");
      gStyle->SetTitleFont  (fAxis[2].GetTitleFont(),  "z");
   }
}
Int_t TAxis3D::AxisChoice( Option_t *axis) const
{
   
   char achoice = toupper(axis[0]);
   if (achoice == 'X') return 0;
   if (achoice == 'Y') return 1;
   if (achoice == 'Z') return 2;
   return -1;
}
Int_t TAxis3D::GetNdivisions( Option_t *axis) const
{
   
   Int_t ax = AxisChoice(axis);
   return fAxis[ax].GetNdivisions();
}
Color_t TAxis3D::GetAxisColor( Option_t *axis) const
{
   
   Int_t ax = AxisChoice(axis);
   return fAxis[ax].GetAxisColor();
}
Color_t TAxis3D::GetLabelColor( Option_t *axis) const
{
   
   Int_t ax = AxisChoice(axis);
   return fAxis[ax].GetLabelColor();
}
Style_t TAxis3D::GetLabelFont( Option_t *axis) const
{
   
   Int_t ax = AxisChoice(axis);
   return fAxis[ax].GetLabelFont();
}
Float_t TAxis3D::GetLabelOffset( Option_t *axis) const
{
   
   Int_t ax = AxisChoice(axis);
   return fAxis[ax].GetLabelOffset();
}
Float_t TAxis3D::GetLabelSize( Option_t *axis) const
{
   
   Int_t ax = AxisChoice(axis);
   return fAxis[ax].GetLabelSize();
}
Float_t TAxis3D::GetTickLength( Option_t *axis) const
{
   
   Int_t ax = AxisChoice(axis);
   return fAxis[ax].GetTickLength();
}
Float_t TAxis3D::GetTitleOffset( Option_t *axis) const
{
   
   Int_t ax = AxisChoice(axis);
   fAxis[ax].GetTitleOffset();
   return 0;
}
#define AXISCHOICE                \
   Int_t i = AxisChoice(axis);    \
   Int_t nax = 1;                 \
   if (i == -1) { i = 0; nax = 3;}\
   for (Int_t ax=i;ax<nax+i;ax++)
void TAxis3D::SetNdivisions(Int_t n, Option_t *axis)
{
   
   AXISCHOICE {fAxis[ax].SetNdivisions(n);}
}
void TAxis3D::SetAxisColor(Color_t color, Option_t *axis)
{
   
   AXISCHOICE {fAxis[ax].SetAxisColor(color);}
}
void TAxis3D::SetAxisRange(Double_t xmin, Double_t xmax, Option_t *axis)
{
   
   Int_t ax = AxisChoice(axis);
   TAxis *theAxis = &fAxis[ax];
   Int_t bin1 = theAxis->FindBin(xmin);
   Int_t bin2 = theAxis->FindBin(xmax);
   theAxis->SetRange(bin1, bin2);
}
void TAxis3D::SetLabelColor(Color_t color, Option_t *axis)
{
   
   AXISCHOICE { fAxis[ax].SetLabelColor(color); }
}
void TAxis3D::SetLabelFont(Style_t font, Option_t *axis)
{
   
   AXISCHOICE { fAxis[ax].SetLabelFont(font); }
}
void TAxis3D::SetLabelOffset(Float_t offset, Option_t *axis)
{
   
   AXISCHOICE { fAxis[ax].SetLabelOffset(offset); }
}
void TAxis3D::SetLabelSize(Float_t size, Option_t *axis)
{
   
   AXISCHOICE { fAxis[ax].SetLabelSize(size); }
}
void TAxis3D::SetTickLength(Float_t length, Option_t *axis)
{
   
   AXISCHOICE { fAxis[ax].SetTickLength(length); }
}
void TAxis3D::SetTitleOffset(Float_t offset, Option_t *axis)
{
   
   AXISCHOICE { fAxis[ax].SetTitleOffset(offset); }
}
#undef AXISCHOICE
TAxis3D *TAxis3D::GetPadAxis(TVirtualPad *pad)
{
   
   TObject *obj = 0;
   TVirtualPad *thisPad=pad;
   if (!thisPad) thisPad = gPad;
   if (thisPad) {
      
      obj = thisPad->FindObject(TAxis3D::fgRulerName);
      if (!(obj && obj->InheritsFrom(Class()->GetName()))) obj = 0;
   }
   return (TAxis3D *)obj;
}
TAxis3D *TAxis3D::ToggleRulers(TVirtualPad *pad)
{
   
   
   TAxis3D *ax = 0;
   TVirtualPad *thisPad=pad;
   if (!thisPad) thisPad = gPad;
   if (thisPad && thisPad->GetView() ) {
      TAxis3D *a =  GetPadAxis(pad);
      if (a)  delete a;
      else {
         ax = new TAxis3D;
         ax->SetBit(kCanDelete);
         ax->Draw();
      }
      thisPad->Modified();
      thisPad->Update();
   }
   return ax;
}
TAxis3D *TAxis3D::ToggleZoom(TVirtualPad *pad)
{
   
   
   
   
   
   
   
   TAxis3D *ax = 0;
   TVirtualPad *thisPad=pad;
   if (!thisPad) thisPad = gPad;
   if (thisPad && thisPad->GetView()) {
      
      TList *l = thisPad->GetListOfPrimitives();
      TObject *o = l->FindObject(TAxis3D::fgRulerName);
      if (o && o->InheritsFrom(Class()->GetName())) { 
         if (o != l->Last()) { 
            l->Remove(o);
            l->AddLast(o);
         }
         ax = (TAxis3D *)o;
      } else { 
         ax = new TAxis3D;
         ax->SetBit(kCanDelete);
         ax->Draw();
      }
      ax->SwitchZoom();
   }
   return ax;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.