Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TColorWheel.cxx
Go to the documentation of this file.
1 // @(#)root/gpad:$Id$
2 // Author: Rene Brun 10/03/2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "Riostream.h"
13 #include "TROOT.h"
14 #include "TColorWheel.h"
15 #include "TCanvas.h"
16 #include "TText.h"
17 #include "TGraph.h"
18 #include "TArc.h"
19 #include "TLine.h"
20 #include "TColor.h"
21 #include "TMath.h"
22 
23 ClassImp(TColorWheel);
24 
25 /** \class TColorWheel
26 \ingroup gpad
27 
28 Draw the ROOT Color Wheel.
29 
30 The wheel contains the recommended 216 colors to be used in web applications.
31 The colors in the Color Wheel are created by TColor::CreateColorWheel.
32 
33 Using this color set for your text, background or graphics will give your
34 application a consistent appearance across different platforms and browsers.
35 
36 Colors are grouped by hue, the aspect most important in human perception.
37 Touching color chips have the same hue, but with different brightness and vividness.
38 
39 Colors of slightly different hues __clash__. If you intend to display
40 colors of the same hue together, you should pick them from the same group.
41 
42 Each color chip is identified by a mnemonic (e.g. kYellow) and a number.
43 The keywords, kRed, kBlue, kYellow, kPink, etc are defined in the header file __Rtypes.h__
44 that is included in all ROOT other header files. We strongly recommend to use these keywords
45 in your code instead of hardcoded color numbers, e.g.:
46 ~~~ {.cpp}
47  myObject.SetFillColor(kRed);
48  myObject.SetFillColor(kYellow-10);
49  myLine.SetLineColor(kMagenta+2);
50 ~~~
51 
52 Begin_Macro
53 {
54  TColorWheel *w = new TColorWheel();
55  cw = new TCanvas("cw","cw",0,0,400,400);
56  w->SetCanvas(cw);
57  w->Draw();
58 }
59 End_Macro
60 */
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// constructor
64 
65 TColorWheel::TColorWheel() :TNamed("wheel","ROOT Color Wheel")
66 {
67  fCanvas = 0;
68  fArc = 0;
69  fLine = 0;
70  fText = 0;
71  fGraph = 0;
72  fRmin = 2.1;
73  fRmax = 9.5;
74  fR0 = 4;
75  fDr = 1;
76  fRgray = 1.8;
77  fX[ 0] = fR0-0.2*fDr; fY[ 0] = 0;
78  fX[ 1] = fR0+fDr; fY[ 1] = 0.75*fDr;
79  fX[ 2] = fR0+fDr; fY[ 2] = -0.75*fDr;
80  fX[ 3] = fR0+2.2*fDr; fY[ 3] = 1.5*fDr;
81  fX[ 4] = fR0+2.2*fDr; fY[ 4] = 0;
82  fX[ 5] = fR0+2.2*fDr; fY[ 5] = -1.5*fDr;
83  fX[ 6] = fR0+3.4*fDr; fY[ 6] = 2.2*fDr;
84  fX[ 7] = fR0+3.4*fDr; fY[ 7] = 0.7*fDr;
85  fX[ 8] = fR0+3.4*fDr; fY[ 8] = -0.7*fDr;
86  fX[ 9] = fR0+3.4*fDr; fY[ 9] = -2.2*fDr;
87  fX[10] = fR0+4.6*fDr; fY[10] = 2.8*fDr;
88  fX[11] = fR0+4.6*fDr; fY[11] = 1.4*fDr;
89  fX[12] = fR0+4.6*fDr; fY[12] = 0;
90  fX[13] = fR0+4.6*fDr; fY[13] = -1.4*fDr;
91  fX[14] = fR0+4.6*fDr; fY[14] = -2.8*fDr;
92 
93  SetBit(kCanDelete);
94 }
95 
96 ////////////////////////////////////////////////////////////////////////////////
97 /// destructor
98 
99 TColorWheel::~TColorWheel()
100 {
101  //delete fCanvas; please don't do that
102  delete fArc;
103  delete fLine;
104  delete fText;
105  delete fGraph;
106 }
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// always return the color wheel
110 
111 Int_t TColorWheel::DistancetoPrimitive(Int_t px, Int_t py)
112 {
113  if (px+py < 0) return 1;
114  return 0;
115 }
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 /// Paint the color wheel
119 
120 void TColorWheel::Draw(Option_t *option)
121 {
122  if (!fCanvas) {
123  fCanvas = new TCanvas("wheel","ROOT Color Wheel",10,10,400,400);
124  fCanvas->ToggleEventStatus();
125  }
126  fCanvas->Range(-10.5,-10.5,10.5,10.5);
127  fCanvas->SetBorderMode(0);
128  fCanvas->SetFillColor(TColor::GetColor(243,241,174));
129  AppendPad(option);
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 /// Return the color number pointed by the mouse
134 
135 Int_t TColorWheel::GetColor(Int_t px, Int_t py) const
136 {
137  Double_t x = fCanvas->AbsPixeltoX(px);
138  Double_t y = fCanvas->AbsPixeltoY(py);
139  Int_t n = 0;
140 
141  n = InGray(x,y); if (n >= 0) return n;
142  n = InCircles (x,y,kMagenta, 0); if (n >= 0) return n;
143  n = InRectangles(x,y,kPink, 30); if (n >= 0) return n;
144  n = InCircles (x,y,kRed, 60); if (n >= 0) return n;
145  n = InRectangles(x,y,kOrange, 90); if (n >= 0) return n;
146  n = InCircles (x,y,kYellow,120); if (n >= 0) return n;
147  n = InRectangles(x,y,kSpring,150); if (n >= 0) return n;
148  n = InCircles (x,y,kGreen, 180); if (n >= 0) return n;
149  n = InRectangles(x,y,kTeal, 210); if (n >= 0) return n;
150  n = InCircles (x,y,kCyan, 240); if (n >= 0) return n;
151  n = InRectangles(x,y,kAzure, 270); if (n >= 0) return n;
152  n = InCircles (x,y,kBlue, 300); if (n >= 0) return n;
153  n = InRectangles(x,y,kViolet,330); if (n >= 0) return n;
154  return -1;
155 }
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 /// Return the color number pointed by the mouse
159 
160 char *TColorWheel::GetObjectInfo(Int_t px, Int_t py) const
161 {
162  static char info[50];
163  info[0] = 0;
164 
165  Int_t n = GetColor(px,py);
166  if (n < 0) return info;
167  TColor *color = gROOT->GetColor(n);
168  if (!color) return info;
169  Int_t r = (Int_t)(255.01*color->GetRed());
170  Int_t g = (Int_t)(255.01*color->GetGreen());
171  Int_t b = (Int_t)(255.01*color->GetBlue());
172  int res = snprintf(info,sizeof(info),"col %d, %s, r=%3d, g=%3d, b=%3d",n,color->GetName(),r,g,b);
173  // check improbable error condition, suppress gcc9 warnings
174  if ((res < 0) || (res >= (int) sizeof(info)))
175  info[0] = 0;
176  return info;
177 }
178 
179 ////////////////////////////////////////////////////////////////////////////////
180 /// Return the color number when the mouse point to a circle
181 
182 Int_t TColorWheel::InCircles(Double_t x, Double_t y, Int_t coffset, Double_t angle) const
183 {
184  Double_t ang = angle*TMath::DegToRad();
185  Double_t u,v;
186  Rotate(x,y,u,v,ang);
187  Double_t r2 = 0.7*0.7*fDr*fDr;
188  for (Int_t i=0;i<15;i++) {
189  Double_t dx = u-fX[i];
190  Double_t dy = v-fY[i];
191  if (dx*dx+dy*dy < r2) return coffset+i-10;
192  }
193  return -1;
194 }
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 /// Return the color number when the mouse point to the gray circle
198 
199 Int_t TColorWheel::InGray(Double_t x, Double_t y) const
200 {
201  if (x*x+y*y > fRgray*fRgray) return -1;
202  Double_t ang = TMath::ATan2(y,x)*TMath::RadToDeg();
203  if (ang < 0) ang += 360;
204  if (ang < 60) return kWhite;
205  if (ang < 120) return kGray;
206  if (ang < 180) return kGray+1;
207  if (ang < 240) return kGray+2;
208  if (ang < 300) return kGray+3;
209  return kBlack;
210 }
211 
212 ////////////////////////////////////////////////////////////////////////////////
213 /// Return the color number when the mouse point to a rectangle
214 
215 Int_t TColorWheel::InRectangles(Double_t x, Double_t y, Int_t coffset, Double_t angle) const
216 {
217  Double_t ang = angle*TMath::DegToRad();
218  Double_t u,v;
219  Rotate(x,y,u,v,ang);
220  if (TMath::Abs(v) > 1) return -1;
221  if (u < fRmin || u > fRmax) return -1;
222  Int_t div = (Int_t)(10*(u-fRmin)/(fRmax-fRmin));
223  if (v > 0) return coffset + div+1;
224  return coffset+div-9;
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 /// Paint the color wheel
229 
230 void TColorWheel::Paint(Option_t * /*option*/)
231 {
232  if (!fArc) {
233  fArc = new TArc;
234  fLine = new TLine;
235  fText = new TText();
236  fGraph = new TGraph();
237  }
238  PaintGray();
239  PaintCircles (kMagenta, 0);
240  PaintRectangles(kPink, 30);
241  PaintCircles (kRed, 60);
242  PaintRectangles(kOrange, 90);
243  PaintCircles (kYellow,120);
244  PaintRectangles(kSpring,150);
245  PaintCircles (kGreen, 180);
246  PaintRectangles(kTeal, 210);
247  PaintCircles (kCyan, 240);
248  PaintRectangles(kAzure, 270);
249  PaintCircles (kBlue, 300);
250  PaintRectangles(kViolet,330);
251 
252  fText->SetTextFont(72);
253  fText->SetTextColor(kBlue);
254  fText->SetTextAlign(11);
255  fText->SetTextSize(0.03);
256  fText->SetTextAngle(0);
257  fText->PaintText(-10.2,-10.2,"ROOT Color Wheel");
258 }
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 /// Draw one color of type circle
262 
263 void TColorWheel::PaintCircle(Int_t coffset,Int_t n, Double_t x, Double_t y, Double_t ang) const
264 {
265  Double_t u,v;
266  Rotate(x,y,u,v,ang);
267  Int_t colorn = coffset+n;
268  TColor *color = gROOT->GetColor(colorn);
269  if (!color) return;
270  fArc->SetFillColor(colorn);
271  fArc->SetLineColor(14);
272  Double_t r = 0.7*fDr;
273  fArc->PaintEllipse(u,v,r,r,0,360,0);
274  fText->SetTextSize(0.03);
275  fText->SetTextAlign(22);
276  if (255*color->GetLight() <150 && n != 0) fText->SetTextColor(0);
277  if (n>0) fText->PaintText(u,v,Form("+%d",n));
278  else fText->PaintText(u,v,Form("%d", n));
279 }
280 
281 ////////////////////////////////////////////////////////////////////////////////
282 /// Draw all colors of type circle
283 
284 void TColorWheel::PaintCircles(Int_t coffset, Double_t angle) const
285 {
286  Double_t ang = TMath::DegToRad()*angle;
287  Double_t u,v,u0,v0;
288  Rotate(fR0+4.6*fDr,2.8*fDr,u0,v0,ang);
289  Rotate(fR0+5.8*fDr,2.1*fDr,u,v,ang);
290  fLine->PaintLine(u,v,u0,v0);
291  fText->SetTextAlign(22);
292  fText->SetTextFont(72);
293  fText->SetTextColor(1);
294  fText->SetTextSize(0.03);
295  Double_t tangle = angle-90;
296  if (angle == 240) tangle = -30;
297  if (angle == 300) tangle = 30;
298  TColor *col = gROOT->GetColor(coffset);
299  if (!col) return;
300  fText->SetTextAngle(tangle);
301  fText->PaintText(u,v,col->GetName());
302 
303  for (Int_t i=0;i<15;i++) {
304  PaintCircle(coffset,i-10, fX[i], fY[i], ang);
305  }
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 /// Draw all colors of type rectangle
310 
311 void TColorWheel::PaintRectangles(Int_t coffset, Double_t angle) const
312 {
313  Double_t ang = TMath::DegToRad()*angle;
314  Double_t rmin = fRmin, rmax=fRmax;
315  Double_t dr = (rmax-rmin)/10;
316  Double_t dy = -1.0;
317 
318  Double_t u,v,u0,v0;
319  Rotate(rmax+0.62*dr,0,u,v,ang);
320  Rotate(rmax-dr,0.9*dy,u0,v0,ang);
321  fLine->PaintLine(u,v,u0,v0);
322  fText->SetTextAlign(22);
323  fText->SetTextFont(72);
324  fText->SetTextColor(1);
325  fText->SetTextSize(0.03);
326  Double_t tangle = angle+90;
327  if (angle == 30) tangle = -60;
328  if (angle == 90) tangle = 0;
329  if (angle == 150) tangle = 60;
330  if (angle == 210) tangle = -60;
331  if (angle == 270) tangle = 0;
332  fText->SetTextAngle(tangle);
333  TColor *color = gROOT->GetColor(coffset);
334  if (!color) return;
335  fText->PaintText(u,v,color->GetName());
336 
337  Double_t x[5],y[5];
338  Int_t n=-10;
339  for (Int_t j=0;j<2;j++) {
340  for (Int_t i=0;i<10;i++) {
341  n++;
342  Int_t colorn = coffset +n;
343  color = gROOT->GetColor(colorn);
344  Rotate(rmin+i*dr, 0,x[0],y[0],ang);
345  Rotate(rmin+i*dr, dy,x[1],y[1],ang);
346  Rotate(rmin+i*dr+dr,dy,x[2],y[2],ang);
347  Rotate(rmin+i*dr+dr, 0,x[3],y[3],ang);
348  fGraph->SetFillColor(colorn);
349  fGraph->PaintGraph(4,x,y,"f");
350  Rotate(rmin+i*dr+0.5*dr,0.5*dy,x[0],y[0],ang);
351  fText->SetTextSize(0.03);
352  fText->SetTextAlign(22);
353  if (color) {
354  if (255*color->GetLight() <110) fText->SetTextColor(0);
355  }
356  Double_t tang = angle-90;
357  if (angle > 180) tang -=180;
358  fText->SetTextAngle(tang);
359  if (n > 0) fText->PaintText(x[0],y[0],Form("+%d",n));
360  else fText->PaintText(x[0],y[0],Form("%d",n));
361  }
362  dy=1;
363  }
364 
365  Rotate(rmin,-dy,x[0],y[0],ang);
366  Rotate(rmax,-dy,x[1],y[1],ang);
367  Rotate(rmax, dy,x[2],y[2],ang);
368  Rotate(rmin, dy,x[3],y[3],ang);
369  Rotate(rmin,-dy,x[4],y[4],ang);
370  fGraph->SetLineColor(1);
371  fGraph->SetLineWidth(1);
372  fGraph->PaintGraph(5,x,y,"l");
373  fLine->SetLineWidth(1);
374  Rotate(rmin+3*dr,-dy,x[0],y[0],ang);
375  Rotate(rmin+3*dr, dy,x[1],y[1],ang);
376  fLine->PaintLine(x[0],y[0],x[1],y[1]);
377  Rotate(rmin+6*dr,-dy,x[0],y[0],ang);
378  Rotate(rmin+6*dr, dy,x[1],y[1],ang);
379  fLine->PaintLine(x[0],y[0],x[1],y[1]);
380  Rotate(rmin+9*dr,-dy,x[0],y[0],ang);
381  Rotate(rmin+9*dr, dy,x[1],y[1],ang);
382  fLine->PaintLine(x[0],y[0],x[1],y[1]);
383  Rotate(rmin+7*dr,-dy,x[0],y[0],ang);
384  Rotate(rmin+7*dr, dy,x[1],y[1],ang);
385  fLine->PaintLine(x[0],y[0],x[1],y[1]);
386  Rotate(rmin+6*dr,0,x[0],y[0],ang);
387  Rotate(rmax, 0,x[1],y[1],ang);
388  fLine->PaintLine(x[0],y[0],x[1],y[1]);
389 }
390 
391 ////////////////////////////////////////////////////////////////////////////////
392 /// Draw the gray colors + white + black
393 
394 void TColorWheel::PaintGray() const
395 {
396  Double_t r = fRgray;
397  fArc->SetFillColor(kWhite);
398  fArc->PaintEllipse(0,0,r,r,0,60,0);
399  fArc->SetFillColor(kGray);
400  fArc->PaintEllipse(0,0,r,r,60,120,0);
401  fArc->SetFillColor(kGray+1);
402  fArc->PaintEllipse(0,0,r,r,120,180,0);
403  fArc->SetFillColor(kGray+2);
404  fArc->PaintEllipse(0,0,r,r,180,240,0);
405  fArc->SetFillColor(kGray+3);
406  fArc->PaintEllipse(0,0,r,r,240,300,0);
407  fArc->SetFillColor(kBlack);
408  fArc->PaintEllipse(0,0,r,r,300,360,0);
409 
410  fText->SetTextAlign(22);
411  fText->SetTextFont(62);
412  fText->SetTextColor(1);
413  fText->SetTextSize(0.02);
414  fText->SetTextAngle(40);
415  fText->PaintText(0.5*r,0.3*r,"kWhite");
416  fText->SetTextAngle(0);
417  fText->PaintText(0,0.8*r,"kGray");
418  fText->SetTextColor(10);
419  fText->SetTextFont(72);
420  fText->SetTextSize(0.03);
421  fText->PaintText(-0.6*r, 0.3*r,"+1");
422  fText->PaintText(-0.6*r,-0.3*r,"+2");
423  fText->PaintText(0,-0.6*r,"+3");
424  fText->SetTextAngle(-40);
425  fText->SetTextSize(0.02);
426  fText->SetTextFont(62);
427  fText->PaintText(0.5*r,-0.35*r,"kBlack");
428 }
429 
430 ////////////////////////////////////////////////////////////////////////////////
431 /// Rotate point x,y with an angle=ang
432 
433 void TColorWheel::Rotate(Double_t x, Double_t y, Double_t &u, Double_t &v, Double_t ang) const
434 {
435  u = x*TMath::Cos(ang) + y*TMath::Sin(ang);
436  v = x*TMath::Sin(ang) - y*TMath::Cos(ang);
437 }