UJF - Licence de Physique
[ Home| Syntaxe C++| Fichiers| Classes I| Classes II| Graphisme ]
ROOT est une bibliothèque de classes disponible gratuitement et facile à installer sur la plupart des machines. Les classes de ROOT offrent de très nombreuses possibilités pour gérer une interface graphique, gérer des bases de données énormes et la représentation de ces données. Nous utiliserons essentiellement ces dernières possibilités. ROOT permet de travailler soit en mode compilé (i.e., comme vous l'avez fait jusqu'à maintenant) soit en mode interprété ; cette dernière possibilité peu être parfois pratique mais nous ne l'utiliserons pas.
Dans ce petit chapitre, nous allons nous contenter de donner des exemples particuliers afin d'illustrer quelques modes de représentations dont vous pourriez avoir besoin. La liste des classes et leur description est accessible sur le site de ROOT
La première chose à savoir est qu'il faut une interface pour la gestion des fenêtres. Une classe prend ceci en charge, c'est la classe TApplication.
Une fenêtre graphique appartient à la classe TCanvas. On construit un TCanvas par
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
MonApp.Run();
return 0;
}
Selon que l'on veuille tracer un courbe (ou surface) à partir d'une fonction ou d'un tableau de points, on utilisera des méthodes assez différentes ; une fonction mathématique sera tracé par un objet ``fonction'' et un tableau de point par un ``graphe'' ou un ``histogramme''.
Une fonction 1D (y=f(x)) est décrite par la classe TF1.
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
TF1 f1("f1","sin(x)/x",0.,10.);
f1.Draw();
MonApp.Run();
return 0;
}
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
TF1 f1("f1","[0]*sin([1]*x)",-3.,3.);
f1.SetParameter(0,4.5); //parametre 0
f1.SetParameter(1,3.14); //parametre 1
f1.SetParName(0,"Amplitude");
f1.SetParName(1,"Omega");
f1.Draw();
MonApp.Run();
return 0;
}
Les paramètres sont représentés entre [ ] ; Il faut leur donner un valeur avec la méthode TF1::SetParameter() et il est possible de leur donner un nom avec la méthode TF1::SetParName() .
Une fonction 2D (z=f(x,y)) est décrite par la classe TF2.
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
TF2 f2("f2","sin(x)*sin(y)/(x*y)",0.,5.,0.,5.);
f2.Draw("surf4");
MonApp.Run();
return 0;
}
La classe TH1 sert à construire des histogrammes à 1D (X,Poids) ; la classe TH2, très analogue à la première sert pour les histogrammes de dimension 2 (X,Y,Poids) où Poids est le contenu du canal (bin) de l'histogramme. Il existe plusieurs type d'histogramme selon la nature des données que l'on entre dans celui-ci. Par exemple, un TH1F est un histogramme de float ; un TH1D est un histogramme de double (et de même à 2D).
Il y a deux principaux constructeur pour un histogramme 1D :
Il y a deux façons de remplir un histogramme :
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
TH1F h1("h1","Mon histo",101,0.,10.);
double dx=0.1;
for( double x=0; x<10. ; x+=dx) h1.Fill(x,x*x);
h1.Draw();
MonApp.Run();
return 0;
}
Un histogramme 2D possède les mêmes méthodes de base qu'un histogramme à 1D ; il suffit juste de rajouter la 2ème dimension. Par exemple, le constructeur sera
Un TMarker est un point (x,y) représenté par un ``marker'' (voir les différents types de markers). Les coordonnées du point sont des doubles. Le constructeur d'un TMarker a 3 arguments, 2 doubles pour les coordonnées du point et un int pour le type de TMarker.
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
c1.Range(-3.5,-2.1,3.5,2.1);
TMarker *m=new TMarker(0.,0.,8);
m->SetMarkerColor(2);
m->SetMarkerSize(0.3);
m->Draw();
m=new TMarker(-1.8,1.2,30);
m->SetMarkerColor(4);
m->SetMarkerSize(0.8);
m->Draw();
MonApp.Run();
return 0;
}
Une TLine permet de créer une ligne. Le constructeur prend 4 arguments, les coordonnées du point de départ (x0,y0) et du point d'arriver (x1,y1).
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
c1.Range(-3.5,-3.5,3.5,3.5);
TLine *L1=new TLine(-3.,0.,3,0.);
L1->SetLineColor(2);
L1->Draw();
TLine *L2=new TLine(-3.,-2.,1.5,1.8);
L2->SetLineColor(4);
L2->SetLineWidth(2.);
L2->SetLineStyle(2);
L2->Draw();
MonApp.Run();
return 0;
}
Une TEllipse permet de créer une ellipse. Le constructeur prend 3 arguments obligatoires, les coordonnées du centre de l'ellipse et le premier rayon (demi-axe). Les 4 autres arguments sont optionnels et correspondent à l'autre demi-axe, aux angles de départ et de fin si on veut tracer une portion d'ellipse et enfin un angle correspondant à la rotation éventuelle du demi-grand axe.
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
c1.Range(-3.5,-3.5,3.5,3.5);
TEllipse *ellipse=new TEllipse(0.,0.,1.,0.5);
TEllipse *cercle=new TEllipse(-2.,0.,1.);
ellipse->SetLineColor(2);
ellipse->Draw();
cercle->SetLineColor(7);
cercle->SetLineWidth(5.);
cercle->SetFillColor(4);
cercle->Draw();
MonApp.Run();
return 0;
}
Un TPave permet de créer un rectangle. Le constructeur prend 5 arguments obligatoires, les coordonnées du coin supérieur gauche, celles du coin inférieur droit et l'épaisseur du contour (un int). Le dernier argument est une option de tracer (facultatif).
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
c1.Range(-3.5,-3.5,3.5,3.5);
TPave *rectangle=new TPave(-1.,-1.,1.5,0.5);
rectangle->SetLineColor(2);
rectangle->SetFillColor(4);
rectangle->Draw();
MonApp.Run();
return 0;
}
Un TText permet d'afficher un texte sur une fenêtre graphique. Le constructeur prend 3 arguments, les coordonnées de la position du texte (2 doubles) et le texte lui même sous la forme d'une chaîne de caractères.
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
TCanvas c1("c1","Titre de la fenêtre",400, 400);
c1.Range(-3.5,-3.5,3.5,3.5);
TText *montexte=new TText(-1.,-1.,"Un petit texte");
montexte->Draw();
MonApp.Run();
return 0;
}
Il est possible de gérer le clavier et la souris en utilisant la classe TCanvas de ROOT. Pour cela, nous devons créer une classe (dans l'exemple, la classe Fenetre) dérivant de la classe TCanvas. Examiner attentivement l'exemple ci-dessous.
#include <TROOT.h>
#include <TApplication.h>
#include <TCanvas.h>
//
// Prototype de la classe Fenetre
//
class Fenetre : public TCanvas
{
public:
Fenetre(char *nom,char *titre,int width,int height);
void HandleInput(EEventType event, Int_t px, Int_t py);
};
//
// Implementation de la classe Fenetre
//
Fenetre::Fenetre(char *nom,char *titre,int width,int height):TCanvas(nom,titre,width,height)
{
Range(-3.5,-3.5,3.5,3.5);
ToggleEventStatus(); //Affichage de la position de la souris en bas de la fenetre
}
void Fenetre::HandleInput(EEventType event, Int_t px, Int_t py)
{
TCanvas::HandleInput(event,px,py);
double x,y;
switch (event)
{
//----------------------------------
// La souris : px et py sont les coordonnées pixel de la souris
//----------------------------------
case kMouseMotion:break; //si la souris bouge dans la fenetre
case kButton1Down:
AbsPixeltoXY(px,py,x,y);
cout<<"clic avec le bouton gauche en "<<x<<" "<<y<<endl;
break;
case kButton2Down:
AbsPixeltoXY(px,py,x,y);
cout<<"clic avec le bouton du milieu en "<<x<<" "<<y<<endl;
break;
case kButton3Down:
AbsPixeltoXY(px,py,x,y);
cout<<"clic avec le bouton droit en "<<x<<" "<<y<<endl;
break;
//----------------------------------
// Le clavier : px contient le code (ascii) de la touche
//----------------------------------
case kKeyPress:
switch(px)
{
case 'a': cout<<"vous avez appuyer sur 'a'"<<endl; break;
default: cout<<"la touche est : "<<char(px)<<endl;
}
break;
}
}
int main(int argc, char **argv)
{
TROOT root("root","titre");
TApplication MonApp("MonApp",&argc, argv);
Fenetre *mywin=new Fenetre("mywin","Titre de la fenêtre",400,400);
MonApp.Run();
return 0;
}