Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TPolyMarker.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Rene Brun 12/12/94
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, 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 "TVirtualPad.h"
15 #include "TPolyMarker.h"
16 #include "TClass.h"
17 #include "TMath.h"
18 
19 ClassImp(TPolyMarker);
20 
21 
22 /** \class TPolyMarker
23  \ingroup Hist
24 A PolyMarker is defined by an array on N points in a 2-D space.
25 At each point x[i], y[i] a marker is drawn.
26 Marker attributes are managed by TAttMarker.
27 See TMarker for the list of possible marker types.
28 */
29 
30 ////////////////////////////////////////////////////////////////////////////////
31 /// Default constructor.
32 
33 TPolyMarker::TPolyMarker(): TObject()
34 {
35  fN = 0;
36  fX = fY = 0;
37  fLastPoint = -1;
38 }
39 
40 ////////////////////////////////////////////////////////////////////////////////
41 /// Constructor.
42 
43 TPolyMarker::TPolyMarker(Int_t n, Option_t *option)
44  :TObject(), TAttMarker()
45 {
46  fOption = option;
47  SetBit(kCanDelete);
48  fLastPoint = -1;
49  if (n <= 0) {
50  fN = 0;
51  fLastPoint = -1;
52  fX = fY = 0;
53  return;
54  }
55  fN = n;
56  fX = new Double_t [fN];
57  fY = new Double_t [fN];
58 }
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 /// Constructor.
62 
63 TPolyMarker::TPolyMarker(Int_t n, Float_t *x, Float_t *y, Option_t *option)
64  :TObject(), TAttMarker()
65 {
66  fOption = option;
67  SetBit(kCanDelete);
68  fLastPoint = -1;
69  if (n <= 0) {
70  fN = 0;
71  fLastPoint = -1;
72  fX = fY = 0;
73  return;
74  }
75  fN = n;
76  fX = new Double_t [fN];
77  fY = new Double_t [fN];
78  if (!x || !y) return;
79  for (Int_t i=0; i<fN;i++) { fX[i] = x[i]; fY[i] = y[i]; }
80  fLastPoint = fN-1;
81 }
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Constructor.
85 
86 TPolyMarker::TPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)
87  :TObject(), TAttMarker()
88 {
89  fOption = option;
90  SetBit(kCanDelete);
91  fLastPoint = -1;
92  if (n <= 0) {
93  fN = 0;
94  fLastPoint = -1;
95  fX = fY = 0;
96  return;
97  }
98  fN = n;
99  fX = new Double_t [fN];
100  fY = new Double_t [fN];
101  if (!x || !y) return;
102  for (Int_t i=0; i<fN;i++) { fX[i] = x[i]; fY[i] = y[i]; }
103  fLastPoint = fN-1;
104 }
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 ///assignment operator
108 
109 TPolyMarker& TPolyMarker::operator=(const TPolyMarker& pm)
110 {
111  if(this!=&pm) {
112  TObject::operator=(pm);
113  TAttMarker::operator=(pm);
114  fN=pm.fN;
115  fLastPoint=pm.fLastPoint;
116  // delete first previous existing fX and fY
117  if (fX) delete [] fX;
118  if (fY) delete [] fY;
119  fX=pm.fX;
120  fY=pm.fY;
121  fOption=pm.fOption;
122  }
123  return *this;
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Destructor.
128 
129 TPolyMarker::~TPolyMarker()
130 {
131  if (fX) delete [] fX;
132  if (fY) delete [] fY;
133  fLastPoint = -1;
134 }
135 
136 ////////////////////////////////////////////////////////////////////////////////
137 /// Copy constructor.
138 
139 TPolyMarker::TPolyMarker(const TPolyMarker &polymarker) : TObject(polymarker), TAttMarker(polymarker)
140 {
141  fN = 0;
142  fX = fY = 0;
143  fLastPoint = -1;
144  ((TPolyMarker&)polymarker).Copy(*this);
145 }
146 
147 ////////////////////////////////////////////////////////////////////////////////
148 
149 void TPolyMarker::Copy(TObject &obj) const
150 {
151  // Copy.
152 
153  TObject::Copy(obj);
154  TAttMarker::Copy(((TPolyMarker&)obj));
155  ((TPolyMarker&)obj).fN = fN;
156  // delete first previous existing fX and fY
157  if (((TPolyMarker&)obj).fX) delete [] (((TPolyMarker&)obj).fX);
158  if (((TPolyMarker&)obj).fY) delete [] (((TPolyMarker&)obj).fY);
159  if (fN > 0) {
160  ((TPolyMarker&)obj).fX = new Double_t [fN];
161  ((TPolyMarker&)obj).fY = new Double_t [fN];
162  for (Int_t i=0; i<fN;i++) { ((TPolyMarker&)obj).fX[i] = fX[i], ((TPolyMarker&)obj).fY[i] = fY[i]; }
163  } else {
164  ((TPolyMarker&)obj).fX = 0;
165  ((TPolyMarker&)obj).fY = 0;
166  }
167  ((TPolyMarker&)obj).fOption = fOption;
168  ((TPolyMarker&)obj).fLastPoint = fLastPoint;
169 }
170 
171 ////////////////////////////////////////////////////////////////////////////////
172 /// Compute distance from point px,py to a polymarker.
173 ///
174 /// Compute the closest distance of approach from point px,py to each point
175 /// of the polymarker.
176 /// Returns when the distance found is below DistanceMaximum.
177 /// The distance is computed in pixels units.
178 
179 Int_t TPolyMarker::DistancetoPrimitive(Int_t px, Int_t py)
180 {
181  const Int_t big = 9999;
182 
183  // check if point is near one of the points
184  Int_t i, pxp, pyp, d;
185  Int_t distance = big;
186 
187  for (i=0;i<Size();i++) {
188  pxp = gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
189  pyp = gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
190  d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
191  if (d < distance) distance = d;
192  }
193  return distance;
194 }
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 /// Draw.
198 
199 void TPolyMarker::Draw(Option_t *option)
200 {
201  AppendPad(option);
202 }
203 
204 ////////////////////////////////////////////////////////////////////////////////
205 /// Draw polymarker.
206 
207 void TPolyMarker::DrawPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *)
208 {
209  TPolyMarker *newpolymarker = new TPolyMarker(n,x,y);
210  TAttMarker::Copy(*newpolymarker);
211  newpolymarker->fOption = fOption;
212  newpolymarker->SetBit(kCanDelete);
213  newpolymarker->AppendPad();
214 }
215 
216 ////////////////////////////////////////////////////////////////////////////////
217 /// Execute action corresponding to one event.
218 ///
219 /// This member function must be implemented to realize the action
220 /// corresponding to the mouse click on the object in the window
221 
222 void TPolyMarker::ExecuteEvent(Int_t, Int_t, Int_t)
223 {
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// ls.
228 
229 void TPolyMarker::ls(Option_t *) const
230 {
231  TROOT::IndentLevel();
232  printf("TPolyMarker N=%d\n",fN);
233 }
234 
235 ////////////////////////////////////////////////////////////////////////////////
236 /// Merge polymarkers in the collection in this polymarker.
237 
238 Int_t TPolyMarker::Merge(TCollection *li)
239 {
240  if (!li) return 0;
241  TIter next(li);
242 
243  //first loop to count the number of entries
244  TPolyMarker *pm;
245  Int_t npoints = 0;
246  while ((pm = (TPolyMarker*)next())) {
247  if (!pm->InheritsFrom(TPolyMarker::Class())) {
248  Error("Add","Attempt to add object of class: %s to a %s",pm->ClassName(),this->ClassName());
249  return -1;
250  }
251  npoints += pm->Size();
252  }
253 
254  //extend this polymarker to hold npoints
255  SetPoint(npoints-1,0,0);
256 
257  //merge all polymarkers
258  next.Reset();
259  while ((pm = (TPolyMarker*)next())) {
260  Int_t np = pm->Size();
261  Double_t *x = pm->GetX();
262  Double_t *y = pm->GetY();
263  for (Int_t i=0;i<np;i++) {
264  SetPoint(i,x[i],y[i]);
265  }
266  }
267 
268  return npoints;
269 }
270 
271 ////////////////////////////////////////////////////////////////////////////////
272 /// Paint.
273 
274 void TPolyMarker::Paint(Option_t *option)
275 {
276  PaintPolyMarker(fLastPoint+1, fX, fY, option);
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Paint polymarker.
281 
282 void TPolyMarker::PaintPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)
283 {
284  if (n <= 0) return;
285  TAttMarker::Modify(); //Change marker attributes only if necessary
286  Double_t *xx = x;
287  Double_t *yy = y;
288  if (gPad->GetLogx()) {
289  xx = new Double_t[n];
290  for (Int_t ix=0;ix<n;ix++) xx[ix] = gPad->XtoPad(x[ix]);
291  }
292  if (gPad->GetLogy()) {
293  yy = new Double_t[n];
294  for (Int_t iy=0;iy<n;iy++) yy[iy] = gPad->YtoPad(y[iy]);
295  }
296  gPad->PaintPolyMarker(n,xx,yy,option);
297  if (x != xx) delete [] xx;
298  if (y != yy) delete [] yy;
299 }
300 
301 ////////////////////////////////////////////////////////////////////////////////
302 /// Print polymarker.
303 
304 void TPolyMarker::Print(Option_t *) const
305 {
306  printf("TPolyMarker N=%d\n",fN);
307 }
308 
309 ////////////////////////////////////////////////////////////////////////////////
310 /// Save primitive as a C++ statement(s) on output stream out.
311 
312 void TPolyMarker::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
313 {
314  char quote = '"';
315  out<<" "<<std::endl;
316  out<<" Double_t *dum = 0;"<<std::endl;
317  if (gROOT->ClassSaved(TPolyMarker::Class())) {
318  out<<" ";
319  } else {
320  out<<" TPolyMarker *";
321  }
322  out<<"pmarker = new TPolyMarker("<<fN<<",dum,dum,"<<quote<<fOption<<quote<<");"<<std::endl;
323 
324  SaveMarkerAttributes(out,"pmarker",1,1,1);
325 
326  for (Int_t i=0;i<Size();i++) {
327  out<<" pmarker->SetPoint("<<i<<","<<fX[i]<<","<<fY[i]<<");"<<std::endl;
328  }
329  if (!strstr(option, "nodraw")) {
330  out<<" pmarker->Draw("
331  <<quote<<option<<quote<<");"<<std::endl;
332  }
333 }
334 
335 ////////////////////////////////////////////////////////////////////////////////
336 /// Set point following LastPoint to x, y.
337 /// Returns index of the point (new last point).
338 
339 Int_t TPolyMarker::SetNextPoint(Double_t x, Double_t y)
340 {
341  fLastPoint++;
342  SetPoint(fLastPoint, x, y);
343  return fLastPoint;
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Set point number n.
348 /// if n is greater than the current size, the arrays are automatically
349 /// extended
350 
351 void TPolyMarker::SetPoint(Int_t n, Double_t x, Double_t y)
352 {
353  if (n < 0) return;
354  if (!fX || !fY || n >= fN) {
355  // re-allocate the object
356  Int_t newN = TMath::Max(2*fN,n+1);
357  Double_t *savex = new Double_t [newN];
358  Double_t *savey = new Double_t [newN];
359  if (fX && fN){
360  memcpy(savex,fX,fN*sizeof(Double_t));
361  memset(&savex[fN],0,(newN-fN)*sizeof(Double_t));
362  delete [] fX;
363  }
364  if (fY && fN){
365  memcpy(savey,fY,fN*sizeof(Double_t));
366  memset(&savey[fN],0,(newN-fN)*sizeof(Double_t));
367  delete [] fY;
368  }
369  fX = savex;
370  fY = savey;
371  fN = newN;
372  }
373  fX[n] = x;
374  fY[n] = y;
375  fLastPoint = TMath::Max(fLastPoint,n);
376 }
377 
378 ////////////////////////////////////////////////////////////////////////////////
379 /// If n <= 0 the current arrays of points are deleted.
380 
381 void TPolyMarker::SetPolyMarker(Int_t n)
382 {
383  if (n <= 0) {
384  fN = 0;
385  fLastPoint = -1;
386  delete [] fX;
387  delete [] fY;
388  fX = fY = 0;
389  return;
390  }
391  SetPoint(n-1,0,0);
392 }
393 
394 ////////////////////////////////////////////////////////////////////////////////
395 /// If n <= 0 the current arrays of points are deleted.
396 
397 void TPolyMarker::SetPolyMarker(Int_t n, Float_t *x, Float_t *y, Option_t *option)
398 {
399  if (n <= 0) {
400  fN = 0;
401  fLastPoint = -1;
402  delete [] fX;
403  delete [] fY;
404  fX = fY = 0;
405  return;
406  }
407  fN =n;
408  if (fX) delete [] fX;
409  if (fY) delete [] fY;
410  fX = new Double_t[fN];
411  fY = new Double_t[fN];
412  for (Int_t i=0; i<fN;i++) {
413  if (x) fX[i] = (Double_t)x[i];
414  if (y) fY[i] = (Double_t)y[i];
415  }
416  fOption = option;
417  fLastPoint = fN-1;
418 }
419 
420 ////////////////////////////////////////////////////////////////////////////////
421 /// If n <= 0 the current arrays of points are deleted.
422 
423 void TPolyMarker::SetPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)
424 {
425  if (n <= 0) {
426  fN = 0;
427  fLastPoint = -1;
428  delete [] fX;
429  delete [] fY;
430  fX = fY = 0;
431  return;
432  }
433  fN =n;
434  if (fX) delete [] fX;
435  if (fY) delete [] fY;
436  fX = new Double_t[fN];
437  fY = new Double_t[fN];
438  for (Int_t i=0; i<fN;i++) {
439  if (x) fX[i] = x[i];
440  if (y) fY[i] = y[i];
441  }
442  fOption = option;
443  fLastPoint = fN-1;
444 }
445 
446 ////////////////////////////////////////////////////////////////////////////////
447 /// Stream a class object.
448 
449 void TPolyMarker::Streamer(TBuffer &R__b)
450 {
451  if (R__b.IsReading()) {
452  UInt_t R__s, R__c;
453  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
454  if (R__v > 1) {
455  R__b.ReadClassBuffer(TPolyMarker::Class(), this, R__v, R__s, R__c);
456  return;
457  }
458  //====process old versions before automatic schema evolution
459  TObject::Streamer(R__b);
460  TAttMarker::Streamer(R__b);
461  R__b >> fN;
462  fX = new Double_t[fN];
463  fY = new Double_t[fN];
464  Int_t i;
465  Float_t xold,yold;
466  for (i=0;i<fN;i++) {R__b >> xold; fX[i] = xold;}
467  for (i=0;i<fN;i++) {R__b >> yold; fY[i] = yold;}
468  fOption.Streamer(R__b);
469  R__b.CheckByteCount(R__s, R__c, TPolyMarker::IsA());
470  //====end of old versions
471 
472  } else {
473  R__b.WriteClassBuffer(TPolyMarker::Class(),this);
474  }
475 }