// @(#)root/gl:$Id$
// Author: Olivier Couet 17/04/2007
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "Riostream.h"
#include "TROOT.h"
#include "TGLIncludes.h"
#include "TGLUtil.h"
#include "TGLAxis.h"
#include "TGLText.h"
#include "TColor.h"
#include "TString.h"
#include "TMath.h"
#include "THLimitsFinder.h"
//______________________________________________________________________________
/* Begin_Html
GL Axis
To draw a 3D axis in a GL window. The labels are drawn using FTGL.
End_Html */
ClassImp(TGLAxis)
//______________________________________________________________________________
TGLAxis::TGLAxis(): TAttLine(1,1,1), TAttText(20,0.,1,42,0.04)
{
// Constructor.
Init();
}
//______________________________________________________________________________
void TGLAxis::Init()
{
// Default initialization.
fNDiv = fNDiv1 = fNDiv2 = fNDiv3 = 0;
fNTicks1 = fNTicks2 = 0;
fTicks1 = 0;
fTicks2 = 0;
fLabels = 0;
fText = 0;
fAngle1 = 90.;
fAngle2 = 0.;
fAngle3 = 0.;
fAxisLength = 0.;
fWmin = fWmax = 0.;
fTickMarksLength = 0.04; // % of fAxisLength
fTickMarksOrientation = 2; // can be 0, 1, 2, or 3
fLabelsOffset = 0.09; // % of fAxisLength
fLabelsSize = 0.06; // % of fAxisLength
fGridLength = 0.; // 0 means no grid
}
//______________________________________________________________________________
TGLAxis::~TGLAxis()
{
// Destructor.
if (fTicks1) delete [] fTicks1;
if (fTicks2) delete [] fTicks2;
if (fLabels) delete [] fLabels;
if (fText) delete fText;
}
//______________________________________________________________________________
void TGLAxis::PaintGLAxis(const Double_t p1[3], const Double_t p2[3],
Double_t wmin, Double_t wmax, Int_t ndiv,
Option_t *opt)
{
// Paint GL Axis.
//
// p1, p2 : Axis position in the 3D space.
// wmin, wmax : Minimum and maximum values along the axis. wmin < wmax.
// ndiv : Number of axis divisions. It is an integer in the form
// "ttsspp" where "tt" is the number of tertiary divisions,
// "ss" is the number of secondary divisions and "pp" the
// number of primary divisions.
// opt : Options.
// "N" - By default the number of divisions is optimized to
// get a nice labeling. When option "N" is given, the
// number of divisions is not optimized.
fNDiv = ndiv;
if (wmax<=wmin) {
fWmax = wmin;
fWmin = wmax;
} else {
fWmax = wmax;
fWmin = wmin;
}
// Compute the axis length.
Double_t x1 = p1[0], y1 = p1[1], z1 = p1[2];
Double_t x2 = p2[0], y2 = p2[1], z2 = p2[2];
fAxisLength = TMath::Sqrt((x2-x1)*(x2-x1)+
(y2-y1)*(y2-y1)+
(z2-z1)*(z2-z1));
TicksPositions(opt);
DoLabels();
// Paint using GL
glPushMatrix();
// Translation
glTranslatef(x1, y1, z1);
// Rotation in the Z plane
Double_t phi=0;
Double_t normal[3];
normal[0] = 0;
normal[1] = 1;
normal[2] = 0;
if (z1!=z2) {
if (y2==y1 && x2==x1) {
if (z20) {
theta = TMath::ATan((y2-y1)/(x2-x1));
theta = (180/TMath::Pi())*theta;
} else if ((x2-x1)<0) {
theta = TMath::ATan((y2-y1)/(x2-x1));
theta = 180+(180/TMath::Pi())*theta;
} else {
if (y2>y1) theta = 90;
else theta = 270;
}
} else {
if (x2GetColor(GetLineColor())))
col->GetRGB(red, green, blue);
glColor3d(red, green, blue);
TGLUtil::LineWidth(GetLineWidth());
glBegin(GL_LINES);
glVertex3d(0., 0., 0.);
glVertex3d(fAxisLength, 0., 0.);
glEnd();
}
//______________________________________________________________________________
void TGLAxis::PaintGLAxisTickMarks()
{
// Paint axis tick marks.
Int_t i;
// Ticks marks orientation;
Double_t yo=0, zo=0;
switch (fTickMarksOrientation) {
case 0:
yo = 0;
zo = 1;
break;
case 1:
yo = -1;
zo = 0;
break;
case 2:
yo = 0;
zo = -1;
break;
case 3:
yo = 1;
zo = 0;
break;
}
// Paint level 1 tick marks.
if (fTicks1) {
// Paint the tick marks, if needed.
if (fTickMarksLength) {
Double_t tl = fTickMarksLength*fAxisLength;
glBegin(GL_LINES);
for (i=0; iSetTextColor(GetTextColor());
fText->SetGLTextFont(GetTextFont());
fText->SetTextSize(fLabelsSize*fAxisLength);
fText->SetTextAlign(GetTextAlign());
}
fText->SetGLTextAngles(fAngle1, fAngle2, fAngle3);
switch (fTickMarksOrientation) {
case 0:
y = 0;
z = fLabelsOffset*fAxisLength;
break;
case 1:
y = -fLabelsOffset*fAxisLength;
z = 0;
break;
case 2:
y = 0;
z = -fLabelsOffset*fAxisLength;
break;
case 3:
y = fLabelsOffset*fAxisLength;
z = 0;
break;
}
for (i=0; iPaintGLText(x,y,z,fLabels[i]);
}
}
//______________________________________________________________________________
void TGLAxis::TicksPositions(Option_t *opt)
{
// Compute ticks positions.
Bool_t optionNoopt /* , optionLog */;
if (strchr(opt,'N')) optionNoopt = kTRUE; else optionNoopt = kFALSE;
// if (strchr(opt,'G')) optionLog = kTRUE; else optionLog = kFALSE;
// Determine number of tick marks 1, 2 and 3.
fNDiv3 = fNDiv/10000;
fNDiv2 = (fNDiv-10000*fNDiv3)/100;
fNDiv1 = fNDiv%100;
// Clean the tick marks arrays if they exist.
if (fTicks1) {
delete [] fTicks1;
fTicks1 = 0;
}
if (fTicks2) {
delete [] fTicks2;
fTicks2 = 0;
}
// Compute the tick marks positions according to the options.
if (optionNoopt) {
TicksPositionsNoOpt();
} else {
TicksPositionsOpt();
}
}
//______________________________________________________________________________
void TGLAxis::TicksPositionsNoOpt()
{
// Compute ticks positions. Linear and not optimized.
Int_t i, j, k;
Double_t step1 = fAxisLength/(fNDiv1);
fNTicks1 = fNDiv1+1;
fTicks1 = new Double_t[fNTicks1];
// Level 1 tick marks.
for (i=0; i