#include "TGLAxisPainter.h"
#include "TGLRnrCtx.h"
#include "TGLCamera.h"
#include "TGLIncludes.h"
#include "TGLRnrCtx.h"
#include "TGLFontManager.h"
#include "TAxis.h"
#include "THLimitsFinder.h"
#include "TMath.h"
ClassImp(TGLAxisAttrib);
TGLAxisAttrib::TGLAxisAttrib() :
TAttAxis(),
fDir(1, 0, 0),
fMin(0),
fMax(100),
fTMNDim(1),
fTextAlign(TGLFont::kCenterDown),
fRelativeFontSize(kFALSE),
fAbsLabelFontSize(24),
fAbsTitleFontSize(24),
fLabelFontName("arial"),
fTitleFontName("arial")
{
fNdivisions = 510;
fLabelSize = 0.04;
fLabelColor = kWhite;
fTitleColor = kWhite;
fTMScale[0] = 1;
fTMScale[1] = 0.5;
fTMScale[2] = 0.25;
}
ClassImp(TGLAxisPainter);
TGLAxisPainter::TGLAxisPainter():
fAtt(0),
fMaxDigits(5),
fDecimals(0),
fExp(0)
{
}
void TGLAxisPainter::LabelsLimits(const char *label, Int_t &first, Int_t &last) const
{
last = strlen(label)-1;
for (Int_t i=0; i<=last; i++) {
if (strchr("1234567890-+.", label[i]) ) { first = i; return; }
}
Error("LabelsLimits", "attempt to draw a blank label");
}
inline void TGLAxisPainter::DrawTick(TGLVector3 &tv, Int_t order) const
{
for (Int_t dim=0; dim < fAtt->fTMNDim; dim++)
{
glVertex3dv(tv.Arr());
glVertex3dv((tv+fAtt->fTMOff[dim]*fAtt->fTMScale[order]).Arr());
}
}
void TGLAxisPainter::FormAxisValue(Float_t wlabel, char* label) const
{
sprintf(label,&fFormat[0],wlabel);
Int_t first, last;
LabelsLimits(label, first, last);
char chtemp[256];
if (label[first] == '.') {
strcpy(chtemp, "0");
strcat(chtemp, &label[first]);
strcpy(label, chtemp);
first = 1; last = strlen(label);
}
if (label[first] == '-' && label[first+1] == '.') {
strcpy(chtemp, "-0");
strcat(chtemp, &label[first+1]);
strcpy(label, chtemp);
first = 1; last = strlen(label);
}
if (fDecimals) {
char *adot = strchr(label,'.');
if (adot) adot[fDecimals] = 0;
} else {
while (label[last] == '0') { label[last] = 0; last--;}
}
if (label[last] == '.') {
label[last] = 0; last--;
}
if (last-first == 1 && label[first] == '-' && label[last] == '0') {
strcpy(label, "0");
label[last] = 0;
}
}
void TGLAxisPainter::SetTextFormat(Double_t bw1)
{
Double_t absMax = TMath::Max(TMath::Abs(fAtt->fMin),TMath::Abs(fAtt->fMax));
Double_t epsilon = 1e-5;
Double_t absMaxLog = TMath::Log10(absMax) + epsilon;
fExp = 0;
Int_t if1, if2;
Double_t xmicros = TMath::Power(10,-fMaxDigits);
if ( bw1 < xmicros && absMaxLog<0)
{
fExp = (Int_t)absMaxLog;
if (fExp%3 == 1) fExp += TMath::Sign(2, fExp);
if (fExp%3 == 2) fExp += TMath::Sign(1, fExp);
if1 = fMaxDigits;
if2 = fMaxDigits-2;
}
else
{
Float_t af = (absMax > 1) ? absMaxLog : TMath::Log10(absMax*0.0001);
af += epsilon;
Int_t clog = Int_t(af)+1;
if (clog > fMaxDigits) {
while (1) {
fExp++;
absMax /= 10;
if (fExp%3 == 0 && absMax <= TMath::Power(10,fMaxDigits-1)) break;
}
}
else if (clog < -fMaxDigits) {
Double_t rne = 1/TMath::Power(10,fMaxDigits-2);
while (1) {
fExp--;
absMax *= 10;
if (fExp%3 == 0 && absMax >= rne) break;
}
}
Int_t na = 0;
for (Int_t i=fMaxDigits-1; i>0; i--) {
if (TMath::Abs(absMax) < TMath::Power(10,i)) na = fMaxDigits-i;
}
Double_t size = TMath::Abs(fAtt->fMax - fAtt->fMin);
Int_t ndyn = (Int_t)(size/bw1);
while (ndyn) {
if ( size/ndyn <= 0.999 && na < fMaxDigits-2) {
na++;
ndyn /= 10;
}
else break;
}
if2 = na;
if1 = TMath::Max(clog+na,fMaxDigits)+1;
}
if (TMath::Min(fAtt->fMin,fAtt->fMax) < 0)if1 = if1+1;
if1 = TMath::Min(if1,32);
Double_t dwlabel = bw1*TMath::Power(10, -fExp);
while (dwlabel < TMath::Power(10,-if2)) {
if1++;
if2++;
}
if (if1 > 14) if1=14;
if (if2 > 14) if2=14;
if (if2) sprintf(fFormat,"%%%d.%df",if1,if2);
else sprintf(fFormat,"%%%d.%df",if1+1,1);
char chtemp[8];
sprintf(chtemp,"%g",dwlabel);
fDecimals = 0;
char *dot = strchr(chtemp,'.');
if (dot) fDecimals = chtemp + strlen(chtemp) -dot;
}
void TGLAxisPainter::RnrText(const char* txt, TGLVector3 pos, TGLFont &font) const
{
glPushMatrix();
glTranslatef(pos.X(), pos.Y(), pos.Z());
Float_t llx, lly, llz, urx, ury, urz;
font.BBox(txt, llx, lly, llz, urx, ury, urz);
if (txt[0] == '-')
urx += (urx-llx)/strlen(txt);
Float_t x=0, y=0;
switch (fAtt->fTextAlign)
{
case TGLFont::kCenterDown:
x = -urx*0.5; y = -ury;
break;
case TGLFont::kCenterUp:
x = -urx; y = 0;
break;
case TGLFont::kLeft:
x = -urx; y =(lly -ury)*0.5;
break;
case TGLFont::kRight:
x = 0; y = -ury*0.5;
break;
default:
break;
};
glRasterPos2i(0, 0);
glBitmap(0, 0, 0, 0, x, y, 0);
font.Render(txt);
glPopMatrix();
}
void TGLAxisPainter::Paint(TGLRnrCtx &rnrCtx, TGLAxisAttrib &att)
{
if (rnrCtx.Selection() || rnrCtx.Highlight())
return;
fAtt = &att;
TGLVector3 start = att.fDir*att.fMin;
TGLVector3 end = att.fDir*att.fMax;
Int_t n1a = TMath::FloorNint(att.fNdivisions/100);
Int_t n2a = att.fNdivisions-n1a*100;
Int_t bn1, bn2;
Double_t bw1, bw2;
Double_t bl1, bh1, bl2, bh2;
THLimitsFinder::Optimize(att.fMin, att.fMax, n1a, bl1, bh1, bn1, bw1);
THLimitsFinder::Optimize(bl1, bl1+bw1, n2a, bl2, bh2, bn2, bw2);
TGLFont font;
Double_t len=0;
if (att.fRelativeFontSize)
{
GLdouble mm[16];
GLdouble pm[16];
GLint vp[4];
glGetDoublev(GL_MODELVIEW_MATRIX, mm);
glGetDoublev(GL_PROJECTION_MATRIX, pm);
glGetIntegerv(GL_VIEWPORT, vp);
GLdouble dn[3];
GLdouble up[3];
gluProject(start.X(), start.Y(), start.Z(), mm, pm, vp, &dn[0], &dn[1], &dn[2]);
gluProject(end.X(), end.Y(), end.Z(), mm, pm, vp, &up[0], &up[1], &up[2]);
len = TMath::Sqrt(( up[0]-dn[0])*(up[0]-dn[0])
+ (up[1]-dn[1])*(up[1]-dn[1])
+ (up[2]-dn[2])*(up[2]-dn[2]));
}
{
Int_t fs = att.fRelativeFontSize ? Int_t(att.GetLabelSize()*len):att.fAbsLabelFontSize;
att.fAbsLabelFontSize = TGLFontManager::GetFontSize(fs, 8, 36);
rnrCtx.RegisterFont(att.fAbsLabelFontSize, att.fLabelFontName.Data(), TGLFont::kPixmap, font);
TGLUtil::Color(att.fLabelColor);
glPushMatrix();
TGLVector3 off = (att.fTMOff[0])*2.5;
glTranslated (off.X(), off.Y(), off.Z());
font.PreRender();
TGLVector3 pos = att.fDir*bl1;
TGLVector3 step = att.fDir*bw1;
SetTextFormat(bw1);
Double_t lab0 = bl1*TMath::Power(10, -fExp);
Double_t labStep = bw1*TMath::Power(10, -fExp);
char chtemp[10];
for (Int_t i=0; i<=bn1; i++)
{
FormAxisValue(lab0+i*labStep, &chtemp[0]);
font.RenderBitmap(chtemp, pos.X(), pos.Y(), pos.Z(), att.fTextAlign);
pos += step;
}
font.PostRender();
glPopMatrix();
rnrCtx.ReleaseFont(font);
}
if (att.fTitle.Length())
{
Int_t fs = (att.fRelativeFontSize)? Int_t(att.GetTitleSize()*len) : att.fAbsTitleFontSize;
att.fAbsTitleFontSize = TGLFontManager::GetFontSize(fs, 12, 36);
rnrCtx.RegisterFont(TGLFontManager::GetFontSize(fs, 12, 36),
att.fTitleFontName.Data(), TGLFont::kPixmap, font);
TGLUtil::Color(att.fTitleColor);
font.PreRender();
TGLVector3 pos = att.fTitlePos;
pos += att.fTMOff[0]*2.5;
TString title = att.fTitle;
if (att.fTitleUnits.Length())
{
if (fExp)
title += Form("[10^%d %s]", fExp, att.fTitleUnits.Data());
else
title += Form("[%s]", att.fTitleUnits.Data());
}
RnrText(title.Data(), pos, font);
font.PostRender();
rnrCtx.ReleaseFont(font);
}
TGLUtil::Color(att.fAxisColor);
glBegin(GL_LINES);
{
glVertex3dv(start.Arr());
glVertex3dv(end.Arr());
}
{
TGLVector3 tmStep1 = att.fDir*bw1;
TGLVector3 tmStep2 = att.fDir*bw2;
TGLVector3 tv1 = att.fDir*bl1;
TGLVector3 tv2;
for (Int_t t1=0; t1<bn1; t1++)
{
DrawTick(tv1, 0);
tv2 = tv1 + att.fDir*(bl2-bl1);
for (Int_t t2=0; t2<=bn2; t2++)
{
DrawTick(tv2, 1);
tv2 += tmStep2;
}
tv1 += tmStep1;
}
DrawTick(tv1, 0);
Int_t nc = Int_t((att.fMax-bh1)/bw2);
tv2 = att.fDir*bh1;
for(Int_t t2=0; t2<=nc; t2++)
{
DrawTick(tv2, 1);
tv2 += tmStep2;
}
nc = Int_t((bl1-att.fMin)/bw2);
tv2 = att.fDir*bl1;
for(Int_t t2=0; t2<=nc; t2++)
{
DrawTick(tv2, 1);
tv2 -= tmStep2;
}
}
glEnd();
}
Last change: Mon Nov 24 08:19:09 2008
Last generated: 2008-11-24 08:19
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.