ROOT  6.06/09
Reference Guide
TView3D.cxx
Go to the documentation of this file.
1 // @(#)root/g3d:$Id$
2 // Author: Rene Brun, Nenad Buncic, Evgueni Tcherniaev, Olivier Couet 18/08/95
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 "RConfigure.h"
13 
14 #include "TVirtualPad.h"
15 #include "TView3D.h"
16 #include "TAxis3D.h"
17 #include "TPolyLine3D.h"
18 #include "TVirtualX.h"
19 #include "TROOT.h"
20 #include "TClass.h"
21 #include "TList.h"
22 #include "TPluginManager.h"
23 #include "TMath.h"
24 
25 // Remove when TView3Der3DPad fix in ExecuteRotateView() is removed
26 #include "TVirtualViewer3D.h"
27 
29 
30 //const Int_t kPerspective = BIT(14);
31 
32 const Int_t kCARTESIAN = 1;
33 const Int_t kPOLAR = 2;
34 const Double_t kRad = 3.14159265358979323846/180.0;
35 
36 /** \class TView3D
37 \ingroup g3d
38 The 3D view class.
39 
40 This package was originally written by Evgueni Tcherniaev from IHEP/Protvino.
41 
42 The original Fortran implementation was adapted to HIGZ/PAW by Olivier Couet and
43 Evgueni Tcherniaev.
44 
45 This View class is a subset of the original system. It has been converted to a
46 C++ class by Rene Brun.
47 
48 TView3D creates a 3-D view in the current pad. In this 3D view Lego and Surface
49 plots can be drawn and also 3D polyline and markers. Most of the time a TView3D
50 is created automatically when a 3D object needs to be painted in a pad (for
51 instance a Lego or a Surface plot).
52 
53 In some case a TView3D should be explicitly. For instance to paint a 3D simple
54 scene composed of simple objects like polylines and polymarkers.
55 The following macro gives an example:
56 
57 Begin_Macro(source)
58 {
59  cV3D = new TCanvas("cV3D","PolyLine3D & PolyMarker3D Window",200,10,500,500);
60 
61  // Creating a view
62  TView3D *view = (TView3D*) TView::CreateView(1);
63  view->SetRange(5,5,5,25,25,25);
64 
65  // Create a first PolyLine3D
66  TPolyLine3D *pl3d1 = new TPolyLine3D(6);
67  pl3d1->SetPoint(0, 10, 20, 10);
68  pl3d1->SetPoint(1, 15, 15, 15);
69  pl3d1->SetPoint(2, 20, 20, 20);
70  pl3d1->SetPoint(3, 20, 10, 20);
71  pl3d1->SetPoint(4, 10, 10, 20);
72  pl3d1->SetPoint(5, 10, 10, 10);
73 
74  // Create a first PolyMarker3D
75  TPolyMarker3D *pm3d1 = new TPolyMarker3D(9);
76  pm3d1->SetPoint( 0, 10, 10, 10);
77  pm3d1->SetPoint( 1, 20, 20, 20);
78  pm3d1->SetPoint( 2, 10, 20, 20);
79  pm3d1->SetPoint( 3, 10, 10, 20);
80  pm3d1->SetPoint( 4, 20, 20, 10);
81  pm3d1->SetPoint( 5, 20, 10, 10);
82  pm3d1->SetPoint( 6, 20, 10, 20);
83  pm3d1->SetPoint( 7, 10, 20, 10);
84  pm3d1->SetPoint( 8, 15, 15, 15);
85  pm3d1->SetMarkerSize(2);
86  pm3d1->SetMarkerColor(4);
87  pm3d1->SetMarkerStyle(2);
88 
89  // Draw
90  pl3d1->Draw();
91  pm3d1->Draw();
92 }
93 End_Macro
94 
95 
96 Several coordinate systems are available:
97 
98  - Cartesian
99  - Polar
100  - Cylindrical
101  - Spherical
102  - PseudoRapidity/Phi
103 */
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Default constructor
107 
109 {
110  fSystem = 0;
111  fOutline = 0;
112  fDefaultOutline = kFALSE;
113  fAutoRange = kFALSE;
114  fChanged = kFALSE;
115 
116  fPsi = 0;
117  Int_t i;
118  for (i = 0; i < 3; i++) {
119  fRmin[i] = 0;
120  fRmax[i] = 1;
121  fX1[i] = fX2[i] = fY1[i] = fY2[i] = fZ1[i] = fZ2[i] = 0;
122  }
123 
124  if (gPad) {
125  fLongitude = -90 - gPad->GetPhi();
126  fLatitude = 90 - gPad->GetTheta();
127  } else {
128  fLongitude = 0;
129  fLatitude = 0;
130  }
131  Int_t irep = 1;
132  ResetView(fLongitude, fLatitude, fPsi, irep);
133 }
134 
135 ////////////////////////////////////////////////////////////////////////////////
136 /// TView3D constructor
137 ///
138 /// Creates a 3-D view in the current pad
139 /// rmin[3], rmax[3] are the limits of the object depending on
140 /// the selected coordinate system
141 ///
142 /// Before drawing a 3-D object in a pad, a 3-D view must be created.
143 /// Note that a view is automatically created when drawing legos or surfaces.
144 ///
145 /// The coordinate system is selected via system:
146 /// - system = 1 Cartesian
147 /// - system = 2 Polar
148 /// - system = 3 Cylindrical
149 /// - system = 4 Spherical
150 /// - system = 5 PseudoRapidity/Phi
151 
152 TView3D::TView3D(Int_t system, const Double_t *rmin, const Double_t *rmax) : TView()
153 {
154  Int_t irep;
155 
157 
158  fSystem = system;
159  fOutline = 0;
161  fAutoRange = kFALSE;
162  fChanged = kFALSE;
163 
164  if (system == kCARTESIAN || system == kPOLAR || system == 11) fPsi = 0;
165  else fPsi = 90;
166 
167  // By default pad range in 3-D view is (-1,-1,1,1), so ...
168  if (gPad) gPad->Range(-1, -1, 1, 1);
169  fAutoRange = kFALSE;
170 
171  Int_t i;
172  for (i = 0; i < 3; i++) {
173  if (rmin) fRmin[i] = rmin[i];
174  else fRmin[i] = 0;
175  if (rmax) fRmax[i] = rmax[i];
176  else fRmax[i] = 1;
177  fX1[i] = fX2[i] = fY1[i] = fY2[i] = fZ1[i] = fZ2[i] = 0;
178  }
179 
180  if (gPad) {
181  fLongitude = -90 - gPad->GetPhi();
182  fLatitude = 90 - gPad->GetTheta();
183  } else {
184  fLongitude = 0;
185  fLatitude = 0;
186  }
187  ResetView(fLongitude, fLatitude, fPsi, irep);
188 
189  if (gPad) gPad->SetView(this);
190  if (system == 11) SetPerspective();
191 }
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 /// Copy constructor.
195 
197  :TView(tv),
198  fLatitude(tv.fLatitude),
199  fLongitude(tv.fLongitude),
200  fPsi(tv.fPsi),
201  fDview(tv.fDview),
202  fDproj(tv.fDproj),
203  fUpix(tv.fUpix),
204  fVpix(tv.fVpix),
205  fSystem(tv.fSystem),
206  fOutline(tv.fOutline),
207  fDefaultOutline(tv.fDefaultOutline),
208  fAutoRange(tv.fAutoRange),
209  fChanged(tv.fChanged)
210 {
211  for (Int_t i=0; i<16; i++) {
212  fTN[i]=tv.fTN[i];
213  fTB[i]=tv.fTB[i];
214  fTnorm[i]=tv.fTnorm[i];
215  fTback[i]=tv.fTback[i];
216  }
217  for(Int_t i=0; i<3; i++) {
218  fRmax[i]=tv.fRmax[i];
219  fRmin[i]=tv.fRmin[i];
220  fX1[i]=tv.fX1[i];
221  fX2[i]=tv.fX2[i];
222  fY1[i]=tv.fY1[i];
223  fY2[i]=tv.fY2[i];
224  fZ1[i]=tv.fZ1[i];
225  fZ2[i]=tv.fZ2[i];
226  }
227  for(Int_t i=0; i<4; i++)
228  fUVcoord[i]=tv.fUVcoord[i];
229 }
230 
231 ////////////////////////////////////////////////////////////////////////////////
232 /// Assignment operator.
233 
235 {
236  if (this!=&tv) {
237  TView::operator=(tv);
238  fLatitude=tv.fLatitude;
239  fLongitude=tv.fLongitude;
240  fPsi=tv.fPsi;
241  fDview=tv.fDview;
242  fDproj=tv.fDproj;
243  fUpix=tv.fUpix;
244  fVpix=tv.fVpix;
245  fSystem=tv.fSystem;
246  fOutline=tv.fOutline;
249  fChanged=tv.fChanged;
250  for(Int_t i=0; i<16; i++) {
251  fTN[i]=tv.fTN[i];
252  fTB[i]=tv.fTB[i];
253  fTnorm[i]=tv.fTnorm[i];
254  fTback[i]=tv.fTback[i];
255  }
256  for(Int_t i=0; i<3; i++) {
257  fRmax[i]=tv.fRmax[i];
258  fRmin[i]=tv.fRmin[i];
259  fX1[i]=tv.fX1[i];
260  fX2[i]=tv.fX2[i];
261  fY1[i]=tv.fY1[i];
262  fY2[i]=tv.fY2[i];
263  fZ1[i]=tv.fZ1[i];
264  fZ2[i]=tv.fZ2[i];
265  }
266  for(Int_t i=0; i<4; i++)
267  fUVcoord[i]=tv.fUVcoord[i];
268  }
269  return *this;
270 }
271 
272 ////////////////////////////////////////////////////////////////////////////////
273 /// TView3D default destructor.
274 
276 {
277  if (fOutline) fOutline->Delete();
278  delete fOutline;
279  fOutline = 0;
280 }
281 
282 ////////////////////////////////////////////////////////////////////////////////
283 /// Define axis vertices.
284 ///
285 /// Input:
286 /// - ANG - angle between X and Y axis
287 ///
288 /// Output:
289 /// - AV(3,8) - axis vertices
290 /// - IX1 - 1st point of X-axis
291 /// - IX2 - 2nd point of X-axis
292 /// - IY1 - 1st point of Y-axis
293 /// - IY2 - 2nd point of Y-axis
294 /// - IZ1 - 1st point of Z-axis
295 /// - IZ2 - 2nd point of Z-axis
296 /*
297  ~~~ {.cpp}
298  8 6
299  / \ /|\
300  5 / \ 7 5 / | \ 7
301  |\ /| | | |
302  THETA < 90 | \6/ | THETA > 90 | /2\ |
303  (Top view) | | | (Bottom view) |/ \|
304  1 \ | /3 1 \ /3
305  \|/ \ /
306  2 4
307  ~~~
308 */
309 
310 void TView3D::AxisVertex(Double_t ang, Double_t *av, Int_t &ix1, Int_t &ix2, Int_t &iy1, Int_t &iy2, Int_t &iz1, Int_t &iz2)
311 {
312  // Local variables
313  Double_t cosa, sina;
314  Int_t i, k;
315  Double_t p[8] /* was [2][4] */;
316  Int_t i1, i2, i3, i4, ix, iy;
317  ix = 0;
318 
319  // Parameter adjustments
320  av -= 4;
321 
322  sina = TMath::Sin(ang*kRad);
323  cosa = TMath::Cos(ang*kRad);
324  p[0] = fRmin[0];
325  p[1] = fRmin[1];
326  p[2] = fRmax[0];
327  p[3] = fRmin[1];
328  p[4] = fRmax[0];
329  p[5] = fRmax[1];
330  p[6] = fRmin[0];
331  p[7] = fRmax[1];
332  //*-*- F I N D T H E M O S T L E F T P O I N T */
333  i1 = 1;
334  if (fTN[0] < 0) i1 = 2;
335  if (fTN[0]*cosa + fTN[1]*sina < 0) i1 = 5 - i1;
336 
337  //*-*- S E T O T H E R P O I N T S */
338  i2 = i1 % 4 + 1;
339  i3 = i2 % 4 + 1;
340  i4 = i3 % 4 + 1;
341 
342  //*-*- S E T A X I S V E R T I X E S */
343  av[4] = p[(i1 << 1) - 2];
344  av[5] = p[(i1 << 1) - 1];
345  av[7] = p[(i2 << 1) - 2];
346  av[8] = p[(i2 << 1) - 1];
347  av[10] = p[(i3 << 1) - 2];
348  av[11] = p[(i3 << 1) - 1];
349  av[13] = p[(i4 << 1) - 2];
350  av[14] = p[(i4 << 1) - 1];
351  for (i = 1; i <= 4; ++i) {
352  av[i*3 + 3] = fRmin[2];
353  av[i*3 + 13] = av[i*3 + 1];
354  av[i*3 + 14] = av[i*3 + 2];
355  av[i*3 + 15] = fRmax[2];
356  }
357 
358  //*-*- S E T A X I S
359 
360  if (av[4] == av[7]) ix = 2;
361  if (av[5] == av[8]) ix = 1;
362  iy = 3 - ix;
363  //*-*- X - A X I S
364  ix1 = ix;
365  if (av[ix*3 + 1] > av[(ix + 1)*3 + 1]) ix1 = ix + 1;
366  ix2 = (ix << 1) - ix1 + 1;
367  //*-*- Y - A X I S
368  iy1 = iy;
369  if (av[iy*3 + 2] > av[(iy + 1)*3 + 2]) iy1 = iy + 1;
370  iy2 = (iy << 1) - iy1 + 1;
371  //*-*- Z - A X I S
372  iz1 = 1;
373  iz2 = 5;
374 
375  if (fTN[10] >= 0) return;
376  k = (ix1 - 1)*3 + ix2;
377  if (k%2) return;
378  if (k == 2) {
379  ix1 = 4;
380  ix2 = 3;
381  }
382  if (k == 4) {
383  ix1 = 3;
384  ix2 = 4;
385  }
386  if (k == 6) {
387  ix1 = 1;
388  ix2 = 4;
389  }
390  if (k == 8) {
391  ix1 = 4;
392  ix2 = 1;
393  }
394 
395  k = (iy1 - 1)*3 + iy2;
396  if (k%2) return;
397  if (k == 2) {
398  iy1 = 4;
399  iy2 = 3;
400  return;
401  }
402  if (k == 4) {
403  iy1 = 3;
404  iy2 = 4;
405  return;
406  }
407  if (k == 6) {
408  iy1 = 1;
409  iy2 = 4;
410  return;
411  }
412  if (k == 8) {
413  iy1 = 4;
414  iy2 = 1;
415  }
416 }
417 
418 ////////////////////////////////////////////////////////////////////////////////
419 /// Define perspective view.
420 ///
421 /// Compute transformation matrix from world coordinates
422 /// to normalized coordinates (-1 to +1)
423 ///
424 /// Input :
425 /// - theta, phi - spherical angles giving the direction of projection
426 /// - psi - screen rotation angle
427 /// - cov[3] - center of view
428 /// - dview - distance from COV to COP (center of projection)
429 /// - umin, umax, vmin, vmax - view window in projection plane
430 /// - dproj - distance from COP to projection plane
431 /// - bcut, fcut - backward/forward range w.r.t projection plane (fcut<=0)
432 ///
433 /// Output :
434 /// - nper[16] - normalizing transformation
435 ///
436 /// compute tr+rot to get COV in origin, view vector parallel to -Z axis, up
437 /// vector parallel to Y.
438 ///
439 /// ~~~ {.cpp}
440 /// ^Yv UP ^ proj. plane
441 /// | | /|
442 /// | | / |
443 /// | dproj / x--- center of window (COW)
444 /// COV |----------|--x--|------------> Zv
445 /// / | VRP'z
446 /// / ---> | /
447 /// / VPN |/
448 /// Xv
449 /// ~~~
450 ///
451 /// 1. translate COP to origin of MARS : Tper = T(-copx, -copy, -copz)
452 /// 2. rotate VPN : R = Rz(-psi)*Rx(-theta)*Rz(-phi) (inverse Euler)
453 /// 3. left-handed screen reference to right-handed one of MARS : Trl
454 ///
455 /// T12 = Tper*R*Trl
456 
457 
459 {
460  Double_t t12[16];
461  Double_t cov[3];
462  Int_t i;
463  for (i=0; i<3; i++) cov[i] = 0.5*(fRmax[i]+fRmin[i]);
464 
465  Double_t c1 = TMath::Cos(fPsi*kRad);
466  Double_t s1 = TMath::Sin(fPsi*kRad);
467  Double_t c2 = TMath::Cos(fLatitude*kRad);
468  Double_t s2 = TMath::Sin(fLatitude*kRad);
469  Double_t s3 = TMath::Cos(fLongitude*kRad);
470  Double_t c3 = -TMath::Sin(fLongitude*kRad);
471 
472  t12[0] = c1*c3 - s1*c2*s3;
473  t12[4] = c1*s3 + s1*c2*c3;
474  t12[8] = s1*s2;
475  t12[3] = 0;
476 
477  t12[1] = -s1*c3 - c1*c2*s3;
478  t12[5] = -s1*s3 + c1*c2*c3;
479  t12[9] = c1*s2;
480  t12[7] = 0;
481 
482  t12[2] = s2*s3;
483  t12[6] = -s2*c3;
484  t12[10] = c2; // contains Trl
485  t12[11] = 0;
486 
487  // translate with -COP (before rotation):
488  t12[12] = -(cov[0]*t12[0]+cov[1]*t12[4]+cov[2]*t12[8]);
489  t12[13] = -(cov[0]*t12[1]+cov[1]*t12[5]+cov[2]*t12[9]);
490  t12[14] = -(cov[0]*t12[2]+cov[1]*t12[6]+cov[2]*t12[10]);
491  t12[15] = 1;
492 
493  // translate with (0, 0, -dview) after rotation
494 
495  t12[14] -= fDview;
496 
497  // reflection on Z :
498  t12[2] *= -1;
499  t12[6] *= -1;
500  t12[10] *= -1;
501  t12[14] *= -1;
502 
503  // Now we shear the center of window from (0.5*(umin+umax), 0.5*(vmin+vmax), dproj)
504  // to (0, 0, dproj)
505 
506  Double_t a2 = -fUVcoord[0]/fDproj; // shear coef. on x
507  Double_t b2 = -fUVcoord[1]/fDproj; // shear coef. on y
508 
509  // | 1 0 0 0 |
510  // SHz(a2,b2) = | 0 1 0 0 |
511  // | a2 b2 1 0 |
512  // | 0 0 0 1 |
513 
514  fTnorm[0] = t12[0] + a2*t12[2];
515  fTnorm[1] = t12[1] + b2*t12[2];
516  fTnorm[2] = t12[2];
517  fTnorm[3] = 0;
518 
519  fTnorm[4] = t12[4] + a2*t12[6];
520  fTnorm[5] = t12[5] + b2*t12[6];
521  fTnorm[6] = t12[6];
522  fTnorm[7] = 0;
523 
524  fTnorm[8] = t12[8] + a2*t12[10];
525  fTnorm[9] = t12[9] + b2*t12[10];
526  fTnorm[10] = t12[10];
527  fTnorm[11] = 0;
528 
529  fTnorm[12] = t12[12] + a2*t12[14];
530  fTnorm[13] = t12[13] + b2*t12[14];
531  fTnorm[14] = t12[14];
532  fTnorm[15] = 1;
533 
534  // Scale so that the view volume becomes the canonical one
535  //
536  // Sper = (2/(umax-umin), 2/(vmax-vmin), 1/dproj
537  //
538  Double_t sz = 1./fDproj;
539  Double_t sx = 1./fUVcoord[2];
540  Double_t sy = 1./fUVcoord[3];
541 
542  fTnorm[0] *= sx;
543  fTnorm[4] *= sx;
544  fTnorm[8] *= sx;
545  fTnorm[1] *= sy;
546  fTnorm[5] *= sy;
547  fTnorm[9] *= sy;
548  fTnorm[2] *= sz;
549  fTnorm[6] *= sz;
550  fTnorm[10] *= sz;
551  fTnorm[12] *= sx;
552  fTnorm[13] *= sy;
553  fTnorm[14] *= sz;
554 }
555 
556 ////////////////////////////////////////////////////////////////////////////////
557 /// Define view direction (in spherical coordinates)
558 ///
559 /// Compute transformation matrix from world coordinates
560 /// to normalized coordinates (-1 to +1)
561 ///
562 /// Input:
563 /// - S(3) - scale factors
564 /// - C(3) - centre of scope
565 /// - COSPHI - longitude COS
566 /// - SINPHI - longitude SIN
567 /// - COSTHE - latitude COS (angle between +Z and view direc.)
568 /// - SINTHE - latitude SIN
569 /// - COSPSI - screen plane rotation angle COS
570 /// - SINPSI - screen plane rotation angle SIN
571 
573  Double_t cosphi, Double_t sinphi,
574  Double_t costhe, Double_t sinthe,
575  Double_t cospsi, Double_t sinpsi,
576  Double_t *tnorm, Double_t *tback)
577 {
578  if (IsPerspective()) {
580  return;
581  }
582  Int_t i, k;
583  Double_t tran[16] /* was [4][4] */, rota[16] /* was [4][4] */;
584  Double_t c1, c2, c3, s1, s2, s3, scalex, scaley, scalez;
585 
586  // Parameter adjustments
587  tback -= 5;
588  tnorm -= 5;
589 
590  scalex = s[0];
591  scaley = s[1];
592  scalez = s[2];
593 
594  //*-*- S E T T R A N S L A T I O N M A T R I X
595  tran[0] = 1 / scalex;
596  tran[1] = 0;
597  tran[2] = 0;
598  tran[3] = -c[0] / scalex;
599 
600  tran[4] = 0;
601  tran[5] = 1 / scaley;
602  tran[6] = 0;
603  tran[7] = -c[1] / scaley;
604 
605  tran[8] = 0;
606  tran[9] = 0;
607  tran[10] = 1 / scalez;
608  tran[11] = -c[2] / scalez;
609 
610  tran[12] = 0;
611  tran[13] = 0;
612  tran[14] = 0;
613  tran[15] = 1;
614 
615  //*-*- S E T R O T A T I O N M A T R I X
616  // ( C(PSI) S(PSI) 0) (1 0 0 ) ( C(90+PHI) S(90+PHI) 0)
617  // (-S(PSI) C(PSI) 0) * (0 C(THETA) S(THETA)) * (-S(90+PHI) C(90+PHI) 0)
618  // ( 0 0 1) (0 -S(THETA) C(THETA)) ( 0 0 1)
619  c1 = cospsi;
620  s1 = sinpsi;
621  c2 = costhe;
622  s2 = sinthe;
623  c3 = -sinphi;
624  s3 = cosphi;
625 
626  rota[0] = c1*c3 - s1*c2*s3;
627  rota[1] = c1*s3 + s1*c2*c3;
628  rota[2] = s1*s2;
629  rota[3] = 0;
630 
631  rota[4] = -s1*c3 - c1* c2*s3;
632  rota[5] = -s1*s3 + c1* c2*c3;
633  rota[6] = c1*s2;
634  rota[7] = 0;
635 
636  rota[8] = s2*s3;
637  rota[9] = -s2*c3;
638  rota[10] = c2;
639  rota[11] = 0;
640 
641  rota[12] = 0;
642  rota[13] = 0;
643  rota[14] = 0;
644  rota[15] = 1;
645 
646  //*-*- F I N D T R A N S F O R M A T I O N M A T R I X
647  for (i = 1; i <= 3; ++i) {
648  for (k = 1; k <= 4; ++k) {
649  tnorm[k + (i << 2)] = rota[(i << 2) - 4]*tran[k - 1] + rota[(i
650  << 2) - 3]*tran[k + 3] + rota[(i << 2) - 2]*tran[k +7]
651  + rota[(i << 2) - 1]*tran[k + 11];
652  }
653  }
654 
655  //*-*- S E T B A C K T R A N S L A T I O N M A T R I X
656  tran[0] = scalex;
657  tran[3] = c[0];
658 
659  tran[5] = scaley;
660  tran[7] = c[1];
661 
662  tran[10] = scalez;
663  tran[11] = c[2];
664 
665  //*-*- F I N D B A C K T R A N S F O R M A T I O N
666  for (i = 1; i <= 3; ++i) {
667  for (k = 1; k <= 4; ++k) {
668  tback[k + (i << 2)] = tran[(i << 2) - 4]*rota[(k << 2) - 4] +
669  tran[(i << 2) - 3]*rota[(k << 2) - 3] + tran[(i << 2) -2]
670  *rota[(k << 2) - 2] + tran[(i << 2) - 1]*rota[(k <<2) - 1];
671  }
672  }
673 }
674 
675 ////////////////////////////////////////////////////////////////////////////////
676 /// Draw the outline of a cube while rotating a 3-d object in the pad.
677 
678 void TView3D::DrawOutlineCube(TList *outline, Double_t *rmin, Double_t *rmax)
679 {
680  TPolyLine3D::DrawOutlineCube(outline,rmin,rmax);
681 }
682 
683 ////////////////////////////////////////////////////////////////////////////////
684 /// Execute action corresponding to one event.
685 
687 {
688  ExecuteRotateView(event,px,py);
689 }
690 
691 ////////////////////////////////////////////////////////////////////////////////
692 /// Execute action corresponding to one event.
693 ///
694 /// This member function is called when a object is clicked with the locator
695 ///
696 /// If Left button clicked in the object area, while the button is kept down
697 /// the cube representing the surrounding frame for the corresponding
698 /// new latitude and longitude position is drawn.
699 
701 {
702  static Int_t system, framewasdrawn;
703  static Double_t xrange, yrange, xmin, ymin, longitude1, latitude1, longitude2, latitude2;
704  static Double_t newlatitude, newlongitude, oldlatitude, oldlongitude;
705  Double_t dlatitude, dlongitude, x, y;
706  Int_t irep = 0;
707  Double_t psideg;
708  Bool_t opaque = gPad->OpaqueMoving();
709 
710  // All coordinates transformation are from absolute to relative
711  if (!gPad->IsEditable()) return;
712  gPad->AbsCoordinates(kTRUE);
713 
714  switch (event) {
715 
716  case kKeyPress :
717  fChanged = kTRUE;
718  MoveViewCommand(Char_t(px), py);
719  break;
720 
721  case kMouseMotion:
722  gPad->SetCursor(kRotate);
723  break;
724 
725  case kButton1Down:
726 
727  // remember position of the cube
728  xmin = gPad->GetX1();
729  ymin = gPad->GetY1();
730  xrange = gPad->GetX2() - xmin;
731  yrange = gPad->GetY2() - ymin;
732  x = gPad->PixeltoX(px);
733  y = gPad->PixeltoY(py);
734  system = GetSystem();
735  framewasdrawn = 0;
736  if (system == kCARTESIAN || system == kPOLAR || IsPerspective()) {
737  longitude1 = 180*(x-xmin)/xrange;
738  latitude1 = 90*(y-ymin)/yrange;
739  } else {
740  latitude1 = 90*(x-xmin)/xrange;
741  longitude1 = 180*(y-ymin)/yrange;
742  }
743  newlongitude = oldlongitude = -90 - gPad->GetPhi();
744  newlatitude = oldlatitude = 90 - gPad->GetTheta();
745  psideg = GetPsi();
746 
747  // if outline isn't set, make it look like a cube
748  if(!fOutline)
750  break;
751 
752  case kButton1Motion:
753  {
754  // draw the surrounding frame for the current mouse position
755  // first: Erase old frame
756  fChanged = kTRUE;
757  if (framewasdrawn && !opaque) fOutline->Paint();
758  framewasdrawn = 1;
759  x = gPad->PixeltoX(px);
760  y = gPad->PixeltoY(py);
761  if (system == kCARTESIAN || system == kPOLAR || IsPerspective()) {
762  longitude2 = 180*(x-xmin)/xrange;
763  latitude2 = 90*(y-ymin)/yrange;
764  } else {
765  latitude2 = 90*(x-xmin)/xrange;
766  longitude2 = 180*(y-ymin)/yrange;
767  }
768  dlongitude = longitude2 - longitude1;
769  dlatitude = latitude2 - latitude1;
770  newlatitude = oldlatitude + dlatitude;
771  newlongitude = oldlongitude - dlongitude;
772  psideg = GetPsi();
773  ResetView(newlongitude, newlatitude, psideg, irep);
774  if (!opaque) {
775  fOutline->Paint();
776  } else {
777  psideg = GetPsi();
778  SetView(newlongitude, newlatitude, psideg, irep);
779  gPad->SetPhi(-90-newlongitude);
780  gPad->SetTheta(90-newlatitude);
781  gPad->Modified(kTRUE);
782  }
783 
784  break;
785  }
786  case kButton1Up:
787  if (gROOT->IsEscaped()) {
788  gROOT->SetEscape(kFALSE);
789  if (opaque) {
790  psideg = GetPsi();
791  SetView(oldlongitude, oldlatitude, psideg, irep);
792  gPad->SetPhi(-90-oldlongitude);
793  gPad->SetTheta(90-oldlatitude);
794  gPad->Modified(kTRUE);
795  }
796  break;
797  }
798 
799  // Temporary fix for 2D drawing problems on pad. fOutline contains
800  // a TPolyLine3D object for the rotation box. This will be painted
801  // through a newly created TView3Der3DPad instance, which is left
802  // behind on pad. This remaining creates 2D drawing problems.
803  //
804  // This is a TEMPORARY fix - will be removed when proper multiple viewers
805  // on pad problems are resolved.
806  if (gPad) {
807  TVirtualViewer3D *viewer = gPad->GetViewer3D();
808  if (viewer && !strcmp(viewer->IsA()->GetName(),"TView3Der3DPad")) {
809  gPad->ReleaseViewer3D();
810  delete viewer;
811  }
812  }
813  // End fix
814 
815  // Recompute new view matrix and redraw
816  psideg = GetPsi();
817  SetView(newlongitude, newlatitude, psideg, irep);
818  gPad->SetPhi(-90-newlongitude);
819  gPad->SetTheta(90-newlatitude);
820  gPad->Modified(kTRUE);
821 
822  // Set line color, style and width
823  gVirtualX->SetLineColor(-1);
824  gVirtualX->SetLineStyle(-1);
825  gVirtualX->SetLineWidth(-1);
826  break;
827  }
828 
829  // set back to default transformation mode
830  gPad->AbsCoordinates(kFALSE);
831 }
832 
833 ////////////////////////////////////////////////////////////////////////////////
834 /// Find Z component of NORMAL in normalized coordinates.
835 ///
836 /// Input:
837 /// - X - X-component of NORMAL
838 /// - Y - Y-component of NORMAL
839 /// - Z - Z-component of NORMAL
840 ///
841 /// Output:
842 /// - ZN - Z-component of NORMAL in normalized coordinates
843 
845 {
846  zn = x*(fTN[1] * fTN[6] - fTN[2] * fTN[5]) + y*(fTN[2] * fTN[4] -
847  fTN[0] * fTN[6]) + z*(fTN[0] * fTN[5] - fTN[1] * fTN[4]);
848 }
849 
850 ////////////////////////////////////////////////////////////////////////////////
851 /// Find critical PHI sectors.
852 ///
853 /// Input:
854 /// - IOPT - options:
855 /// 1. from BACK to FRONT 'BF'
856 /// 2. from FRONT to BACK 'FB'
857 /// - KPHI - number of phi sectors
858 /// - APHI(*) - PHI separators (modified internally)
859 ///
860 /// Output:
861 /// - IPHI1 - initial sector
862 /// - IPHI2 - final sector
863 
864 void TView3D::FindPhiSectors(Int_t iopt, Int_t &kphi, Double_t *aphi, Int_t &iphi1, Int_t &iphi2)
865 {
866  Int_t iphi[2], i, k;
867  Double_t dphi;
868  Double_t x1, x2, z1, z2, phi1, phi2;
869 
870  // Parameter adjustments
871  --aphi;
872 
873  if (aphi[kphi + 1] == aphi[1]) aphi[kphi + 1] += 360;
874  dphi = TMath::Abs(aphi[kphi + 1] - aphi[1]);
875  if (dphi != 360) {
876  aphi[kphi + 2] = (aphi[1] + aphi[kphi + 1]) / (float)2. + 180;
877  aphi[kphi + 3] = aphi[1] + 360;
878  kphi += 2;
879  }
880 
881  //*-*- F I N D C R I T I C A L S E C T O R S
882  k = 0;
883  for (i = 1; i <= kphi; ++i) {
884  phi1 = kRad*aphi[i];
885  phi2 = kRad*aphi[i + 1];
886  x1 = fTN[0]*TMath::Cos(phi1) + fTN[1]*TMath::Sin(phi1);
887  x2 = fTN[0]*TMath::Cos(phi2) + fTN[1]*TMath::Sin(phi2);
888  if (x1 >= 0 && x2 > 0) continue;
889  if (x1 <= 0 && x2 < 0) continue;
890  ++k;
891  if (k == 3) break;
892  iphi[k - 1] = i;
893  }
894  if (k != 2) {
895  Error("FindPhiSectors", "something strange: num. of critical sector not equal 2");
896  iphi1 = 1;
897  iphi2 = 2;
898  return;
899  }
900 
901  //*-*- F I N D O R D E R O F C R I T I C A L S E C T O R S
902  phi1 = kRad*(aphi[iphi[0]] + aphi[iphi[0] + 1]) / (float)2.;
903  phi2 = kRad*(aphi[iphi[1]] + aphi[iphi[1] + 1]) / (float)2.;
904  z1 = fTN[8]*TMath::Cos(phi1) + fTN[9]*TMath::Sin(phi1);
905  z2 = fTN[8]*TMath::Cos(phi2) + fTN[9]*TMath::Sin(phi2);
906  if ((z1 <= z2 && iopt == 1) || (z1 > z2 && iopt == 2)) {
907  iphi1 = iphi[0];
908  iphi2 = iphi[1];
909  } else {
910  iphi1 = iphi[1];
911  iphi2 = iphi[0];
912  }
913 }
914 
915 ////////////////////////////////////////////////////////////////////////////////
916 /// Find critical THETA sectors for given PHI sector.
917 ///
918 /// Input:
919 /// - IOPT - options:
920 /// 1. from BACK to FRONT 'BF'
921 /// 2. from FRONT to BACK 'FB'
922 /// - PHI - PHI sector
923 /// - KTH - number of THETA sectors
924 /// - ATH(*) - THETA separators (modified internally)
925 ///
926 /// Output:
927 /// - ITH1 - initial sector
928 /// - ITH2 - final sector
929 
930 void TView3D::FindThetaSectors(Int_t iopt, Double_t phi, Int_t &kth, Double_t *ath, Int_t &ith1, Int_t &ith2)
931 {
932  Int_t i, k, ith[2];
933  Double_t z1, z2, cosphi, sinphi, tncons, th1, th2, dth;
934 
935  // Parameter adjustments
936  --ath;
937 
938  // Function Body
939  dth = TMath::Abs(ath[kth + 1] - ath[1]);
940  if (dth != 360) {
941  ath[kth + 2] = 0.5*(ath[1] + ath[kth + 1]) + 180;
942  ath[kth + 3] = ath[1] + 360;
943  kth += 2;
944  }
945 
946  //*-*- F I N D C R I T I C A L S E C T O R S
947  cosphi = TMath::Cos(phi*kRad);
948  sinphi = TMath::Sin(phi*kRad);
949  k = 0;
950  for (i = 1; i <= kth; ++i) {
951  th1 = kRad*ath[i];
952  th2 = kRad*ath[i + 1];
953  FindNormal(TMath::Cos(th1)*cosphi, TMath::Cos(th1)*sinphi, -TMath::Sin(th1), z1);
954  FindNormal(TMath::Cos(th2)*cosphi, TMath::Cos(th2)*sinphi, -TMath::Sin(th2), z2);
955  if (z1 >= 0 && z2 > 0) continue;
956  if (z1 <= 0 && z2 < 0) continue;
957  ++k;
958  if (k == 3) break;
959  ith[k - 1] = i;
960  }
961  if (k != 2) {
962  Error("FindThetaSectors", "Something strange: num. of critical sectors not equal 2");
963  ith1 = 1;
964  ith2 = 2;
965  return;
966  }
967 
968  //*-*- F I N D O R D E R O F C R I T I C A L S E C T O R S
969  tncons = fTN[8]*TMath::Cos(phi*kRad) + fTN[9]*TMath::Sin(phi*kRad);
970  th1 = kRad*(ath[ith[0]] + ath[ith[0] + 1]) / (float)2.;
971  th2 = kRad*(ath[ith[1]] + ath[ith[1] + 1]) / (float)2.;
972  z1 = tncons*TMath::Sin(th1) + fTN[10]*TMath::Cos(th1);
973  z2 = tncons*TMath::Sin(th2) + fTN[10]*TMath::Cos(th2);
974  if ((z1 <= z2 && iopt == 1) || (z1 > z2 && iopt == 2)) {
975  ith1 = ith[0];
976  ith2 = ith[1];
977  } else {
978  ith1 = ith[1];
979  ith2 = ith[0];
980  }
981 }
982 
983 ////////////////////////////////////////////////////////////////////////////////
984 /// Find centre of a MIN-MAX scope and scale factors
985 ///
986 /// Output:
987 /// - SCALE(3) - scale factors
988 /// - CENTER(3) - centre
989 /// - IREP - reply (-1 if error in min-max)
990 
991 void TView3D::FindScope(Double_t *scale, Double_t *center, Int_t &irep)
992 {
993  irep = 0;
994  Double_t sqrt3 = 0.5*TMath::Sqrt(3.0);
995 
996  for (Int_t i = 0; i < 3; i++) {
997  if (fRmin[i] >= fRmax[i]) { irep = -1; return;}
998  scale[i] = sqrt3*(fRmax[i] - fRmin[i]);
999  center[i] = 0.5*(fRmax[i] + fRmin[i]);
1000  }
1001 }
1002 
1003 ////////////////////////////////////////////////////////////////////////////////
1004 /// Return distance to axis from point px,py.
1005 ///
1006 /// Algorithm:
1007 ///
1008 /// ~~~ {.cpp}
1009 /// A(x1,y1) P B(x2,y2)
1010 /// ------------------------------------------------
1011 /// I
1012 /// I
1013 /// I
1014 /// I
1015 /// M(x,y)
1016 ///
1017 /// Let us call a = distance AM A=a**2
1018 /// b = distance BM B=b**2
1019 /// c = distance AB C=c**2
1020 /// d = distance PM D=d**2
1021 /// u = distance AP U=u**2
1022 /// v = distance BP V=v**2 c = u + v
1023 ///
1024 /// D = A - U
1025 /// D = B - V = B -(c-u)**2
1026 /// ==> u = (A -B +C)/2c
1027 /// ~~~
1028 
1030 {
1031  Double_t x1,y1,x2,y2;
1032  Double_t x = px;
1033  Double_t y = py;
1034  ratio = 0;
1035 
1036  if (fSystem != 1) return 9998; // only implemented for Cartesian coordinates
1037  if (axis == 1) {
1038  x1 = gPad->XtoAbsPixel(fX1[0]);
1039  y1 = gPad->YtoAbsPixel(fX1[1]);
1040  x2 = gPad->XtoAbsPixel(fX2[0]);
1041  y2 = gPad->YtoAbsPixel(fX2[1]);
1042  } else if (axis == 2) {
1043  x1 = gPad->XtoAbsPixel(fY1[0]);
1044  y1 = gPad->YtoAbsPixel(fY1[1]);
1045  x2 = gPad->XtoAbsPixel(fY2[0]);
1046  y2 = gPad->YtoAbsPixel(fY2[1]);
1047  } else {
1048  x1 = gPad->XtoAbsPixel(fZ1[0]);
1049  y1 = gPad->YtoAbsPixel(fZ1[1]);
1050  x2 = gPad->XtoAbsPixel(fZ2[0]);
1051  y2 = gPad->YtoAbsPixel(fZ2[1]);
1052  }
1053  Double_t xx1 = x - x1;
1054  Double_t xx2 = x - x2;
1055  Double_t x1x2 = x1 - x2;
1056  Double_t yy1 = y - y1;
1057  Double_t yy2 = y - y2;
1058  Double_t y1y2 = y1 - y2;
1059  Double_t a = xx1*xx1 + yy1*yy1;
1060  Double_t b = xx2*xx2 + yy2*yy2;
1061  Double_t c = x1x2*x1x2 + y1y2*y1y2;
1062  if (c <= 0) return 9999;
1063  Double_t v = TMath::Sqrt(c);
1064  Double_t u = (a - b + c)/(2*v);
1065  Double_t d = TMath::Abs(a - u*u);
1066 
1067  Int_t dist = Int_t(TMath::Sqrt(d) - 0.5);
1068  ratio = u/v;
1069  return dist;
1070 }
1071 
1072 ////////////////////////////////////////////////////////////////////////////////
1073 /// Get maximum view extent.
1074 
1076 {
1077  Double_t dx = 0.5*(fRmax[0]-fRmin[0]);
1078  Double_t dy = 0.5*(fRmax[1]-fRmin[1]);
1079  Double_t dz = 0.5*(fRmax[2]-fRmin[2]);
1080  Double_t extent = TMath::Sqrt(dx*dx+dy*dy+dz*dz);
1081  return extent;
1082 }
1083 
1084 ////////////////////////////////////////////////////////////////////////////////
1085 /// Get Range function.
1086 
1088 {
1089  for (Int_t i = 0; i < 3; max[i] = fRmax[i], min[i] = fRmin[i], i++) { }
1090 }
1091 
1092 ////////////////////////////////////////////////////////////////////////////////
1093 /// Get Range function.
1094 
1096 {
1097  for (Int_t i = 0; i < 3; max[i] = fRmax[i], min[i] = fRmin[i], i++) { }
1098 }
1099 
1100 ////////////////////////////////////////////////////////////////////////////////
1101 /// Get current window extent.
1102 
1103 void TView3D::GetWindow(Double_t &u0, Double_t &v0, Double_t &du, Double_t &dv) const
1104 {
1105  u0 = fUVcoord[0];
1106  v0 = fUVcoord[1];
1107  du = fUVcoord[2];
1108  dv = fUVcoord[3];
1109 }
1110 
1111 ////////////////////////////////////////////////////////////////////////////////
1112 /// Check if point is clipped in perspective view.
1113 
1115 {
1116  if (TMath::Abs(p[0])>p[2]) return kTRUE;
1117  if (TMath::Abs(p[1])>p[2]) return kTRUE;
1118  return kFALSE;
1119 }
1120 
1121 ////////////////////////////////////////////////////////////////////////////////
1122 /// Transfer point from normalized to world coordinates.
1123 ///
1124 /// Input:
1125 /// - PN(3) - point in world coordinate system
1126 /// - PW(3) - point in normalized coordinate system
1127 
1128 void TView3D::NDCtoWC(const Float_t* pn, Float_t* pw)
1129 {
1130  pw[0] = fTback[0]*pn[0] + fTback[1]*pn[1] + fTback[2]*pn[2] + fTback[3];
1131  pw[1] = fTback[4]*pn[0] + fTback[5]*pn[1] + fTback[6]*pn[2] + fTback[7];
1132  pw[2] = fTback[8]*pn[0] + fTback[9]*pn[1] + fTback[10]*pn[2] + fTback[11];
1133 }
1134 
1135 ////////////////////////////////////////////////////////////////////////////////
1136 /// Transfer point from normalized to world coordinates.
1137 ///
1138 /// Input:
1139 /// - PN(3) - point in world coordinate system
1140 /// - PW(3) - point in normalized coordinate system
1141 
1142 void TView3D::NDCtoWC(const Double_t* pn, Double_t* pw)
1143 {
1144  pw[0] = fTback[0]*pn[0] + fTback[1]*pn[1] + fTback[2]*pn[2] + fTback[3];
1145  pw[1] = fTback[4]*pn[0] + fTback[5]*pn[1] + fTback[6]*pn[2] + fTback[7];
1146  pw[2] = fTback[8]*pn[0] + fTback[9]*pn[1] + fTback[10]*pn[2] + fTback[11];
1147 }
1148 
1149 ////////////////////////////////////////////////////////////////////////////////
1150 /// Transfer vector of NORMAL from word to normalized coordinates.
1151 ///
1152 /// Input:
1153 /// - PW(3) - vector of NORMAL in word coordinate system
1154 /// - PN(3) - vector of NORMAL in normalized coordinate system
1155 
1157 {
1158  Double_t x, y, z, a1, a2, a3, b1, b2, b3, c1, c2, c3;
1159 
1160  x = pw[0];
1161  y = pw[1];
1162  z = pw[2];
1163  a1 = fTnorm[0];
1164  a2 = fTnorm[1];
1165  a3 = fTnorm[2];
1166  b1 = fTnorm[4];
1167  b2 = fTnorm[5];
1168  b3 = fTnorm[6];
1169  c1 = fTnorm[8];
1170  c2 = fTnorm[9];
1171  c3 = fTnorm[10];
1172  pn[0] = x*(b2*c3 - b3*c2) + y*(b3*c1 - b1*c3) + z*(b1*c2 - b2*c1);
1173  pn[1] = x*(c2*a3 - c3*a2) + y*(c3*a1 - c1*a3) + z*(c1*a2 - c2*a1);
1174  pn[2] = x*(a2*b3 - a3*b2) + y*(a3*b1 - a1*b3) + z*(a1*b2 - a2*b1);
1175 }
1176 
1177 ////////////////////////////////////////////////////////////////////////////////
1178 /// Transfer vector of NORMAL from word to normalized coordinates.
1179 ///
1180 /// Input:
1181 /// - PW(3) - vector of NORMAL in word coordinate system
1182 /// - PN(3) - vector of NORMAL in normalized coordinate system
1183 
1185 {
1186  Double_t x, y, z, a1, a2, a3, b1, b2, b3, c1, c2, c3;
1187 
1188  x = pw[0];
1189  y = pw[1];
1190  z = pw[2];
1191  a1 = fTnorm[0];
1192  a2 = fTnorm[1];
1193  a3 = fTnorm[2];
1194  b1 = fTnorm[4];
1195  b2 = fTnorm[5];
1196  b3 = fTnorm[6];
1197  c1 = fTnorm[8];
1198  c2 = fTnorm[9];
1199  c3 = fTnorm[10];
1200  pn[0] = x*(b2*c3 - b3*c2) + y*(b3*c1 - b1*c3) + z*(b1*c2 - b2*c1);
1201  pn[1] = x*(c2*a3 - c3*a2) + y*(c3*a1 - c1*a3) + z*(c1*a2 - c2*a1);
1202  pn[2] = x*(a2*b3 - a3*b2) + y*(a3*b1 - a1*b3) + z*(a1*b2 - a2*b1);
1203 }
1204 
1205 ////////////////////////////////////////////////////////////////////////////////
1206 /// Set the correct window size for lego and surface plots.
1207 ///
1208 /// Set the correct window size for lego and surface plots.
1209 /// And draw the background if necessary.
1210 ///
1211 /// Input parameters:
1212 /// - RBACK : Background colour
1213 
1215 {
1216  Int_t i, k;
1217  Double_t x, y, z, r1, r2, r3, xx, yy, smax[2];
1218  Double_t xgraf[6], ygraf[6];
1219 
1220  for (i = 1; i <= 2; ++i) {
1221  smax[i - 1] = fTnorm[(i << 2) - 1];
1222  for (k = 1; k <= 3; ++k) {
1223  if (fTnorm[k + (i << 2) - 5] < 0) {
1224  smax[i - 1] += fTnorm[k + (i << 2) - 5]*fRmin[k-1];
1225  } else {
1226  smax[i - 1] += fTnorm[k + (i << 2) - 5]*fRmax[k-1];
1227  }
1228  }
1229  }
1230 
1231  //*-*- Compute x,y range
1232  Double_t xmin = -smax[0];
1233  Double_t xmax = smax[0];
1234  Double_t ymin = -smax[1];
1235  Double_t ymax = smax[1];
1236  Double_t dx = xmax-xmin;
1237  Double_t dy = ymax-ymin;
1238  Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
1239  Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
1240 
1241  // Range() could change the size of the pad pixmap and therefore should
1242  // be called before the other paint routines
1243  gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
1244  ymin - dyr*gPad->GetBottomMargin(),
1245  xmax + dxr*gPad->GetRightMargin(),
1246  ymax + dyr*gPad->GetTopMargin());
1247  gPad->RangeAxis(xmin, ymin, xmax, ymax);
1248 
1249  //*-*- Draw the background if necessary
1250  if (rback > 0) {
1251  r1 = -1;
1252  r2 = -1;
1253  r3 = -1;
1254  xgraf[0] = -smax[0];
1255  xgraf[1] = -smax[0];
1256  xgraf[2] = -smax[0];
1257  xgraf[3] = -smax[0];
1258  xgraf[4] = smax[0];
1259  xgraf[5] = smax[0];
1260  ygraf[0] = -smax[1];
1261  ygraf[1] = smax[1];
1262  ygraf[2] = -smax[1];
1263  ygraf[3] = smax[1];
1264  ygraf[5] = smax[1];
1265  ygraf[4] = -smax[1];
1266  for (i = 1; i <= 8; ++i) {
1267  x = 0.5*((1 - r1)*fRmin[0] + (r1 + 1)*fRmax[0]);
1268  y = 0.5*((1 - r2)*fRmin[1] + (r2 + 1)*fRmax[1]);
1269  z = 0.5*((1 - r3)*fRmin[2] + (r3 + 1)*fRmax[2]);
1270  xx = fTnorm[0]*x + fTnorm[1]*y + fTnorm[2]*z + fTnorm[3];
1271  yy = fTnorm[4]*x + fTnorm[5]*y + fTnorm[6]*z + fTnorm[7];
1272  if (TMath::Abs(xx - xgraf[1]) <= 1e-4) {
1273  if (ygraf[1] >= yy) ygraf[1] = yy;
1274  if (ygraf[2] <= yy) ygraf[2] = yy;
1275  }
1276  if (TMath::Abs(xx - xgraf[5]) <= 1e-4) {
1277  if (ygraf[5] >= yy) ygraf[5] = yy;
1278  if (ygraf[4] <= yy) ygraf[4] = yy;
1279  }
1280  if (TMath::Abs(yy - ygraf[0]) <= 1e-4) xgraf[0] = xx;
1281  if (TMath::Abs(yy - ygraf[3]) <= 1e-4) xgraf[3] = xx;
1282  r1 = -r1;
1283  if (i % 2 == 0) r2 = -r2;
1284  if (i >= 4) r3 = 1;
1285  }
1286  gPad->PaintFillArea(6, xgraf, ygraf);
1287  }
1288 }
1289 
1290 ////////////////////////////////////////////////////////////////////////////////
1291 /// Store axis coordinates in the NDC system.
1292 
1293 void TView3D::SetAxisNDC(const Double_t *x1, const Double_t *x2, const Double_t *y1, const Double_t *y2, const Double_t *z1, const Double_t *z2)
1294 {
1295  for (Int_t i=0;i<3;i++) {
1296  fX1[i] = x1[i];
1297  fX2[i] = x2[i];
1298  fY1[i] = y1[i];
1299  fY2[i] = y2[i];
1300  fZ1[i] = z1[i];
1301  fZ2[i] = z2[i];
1302  }
1303 }
1304 
1305 ////////////////////////////////////////////////////////////////////////////////
1306 /// Set default viewing window.
1307 
1309 {
1310  if (!gPad) return;
1311  Double_t screen_factor = 1.;
1312  Double_t du, dv;
1313  Double_t extent = GetExtent();
1314  fDview = 3*extent;
1315  fDproj = 0.5*extent;
1316 
1317  // width in pixels
1318  fUpix = gPad->GetWw()*gPad->GetAbsWNDC();
1319 
1320  // height in pixels
1321  fVpix = gPad->GetWh()*gPad->GetAbsHNDC();
1322  du = 0.5*screen_factor*fDproj;
1323  dv = du*fVpix/fUpix; // keep aspect ratio
1324  SetWindow(0, 0, du, dv);
1325 }
1326 
1327 ////////////////////////////////////////////////////////////////////////////////
1328 /// This is a function which creates default outline.
1329 ///
1330 /// ~~~ {.cpp}
1331 /// x = fRmin[0] X = fRmax[0]
1332 /// y = fRmin[1] Y = fRmax[1]
1333 /// z = fRmin[2] Z = fRmax[2]
1334 ///
1335 /// (x,Y,Z) +---------+ (X,Y,Z)
1336 /// / /|
1337 /// / / |
1338 /// / / |
1339 /// (x,y,Z) +---------+ |
1340 /// | | + (X,Y,z)
1341 /// | | /
1342 /// | | /
1343 /// | |/
1344 /// +---------+
1345 /// (x,y,z) (X,y,z)
1346 /// ~~~
1347 
1349 {
1350  if (!fOutline) {
1352  fOutline = new TList();
1353  }
1355 }
1356 
1357 ////////////////////////////////////////////////////////////////////////////////
1358 /// Set the parallel option (default).
1359 
1361 {
1362  if (!IsPerspective()) return;
1364  Int_t irep;
1365  ResetView(fLongitude, fLatitude, fPsi, irep);
1366 }
1367 
1368 ////////////////////////////////////////////////////////////////////////////////
1369 /// Set perspective option.
1370 
1372 {
1373  if (IsPerspective()) return;
1375  Int_t irep;
1376  SetDefaultWindow();
1377  ResetView(fLongitude, fLatitude, fPsi, irep);
1378 }
1379 
1380 ////////////////////////////////////////////////////////////////////////////////
1381 /// Set Range function.
1382 
1384 {
1385  Int_t irep;
1386  for (Int_t i = 0; i < 3; fRmax[i] = max[i], fRmin[i] = min[i], i++) { }
1388  ResetView(fLongitude, fLatitude, fPsi, irep);
1389  if(irep < 0)
1390  Error("SetRange", "problem setting view");
1392 }
1393 
1394 ////////////////////////////////////////////////////////////////////////////////
1395 /// Set 3-D View range.
1396 ///
1397 /// Input:
1398 /// - x0, y0, z0 are minimum coordinates
1399 /// - x1, y1, z1 are maximum coordinates
1400 ///
1401 /// - flag values are:
1402 /// - 0 (set always) <- default
1403 /// - 1 (shrink view)
1404 /// - 2 (expand view)
1405 
1407 {
1408  Double_t rmax[3], rmin[3];
1409 
1410  switch (flag) {
1411  case 2: // expand view
1412  GetRange(rmin, rmax);
1413  rmin[0] = x0 < rmin[0] ? x0 : rmin[0];
1414  rmin[1] = y0 < rmin[1] ? y0 : rmin[1];
1415  rmin[2] = z0 < rmin[2] ? z0 : rmin[2];
1416  rmax[0] = x1 > rmax[0] ? x1 : rmax[0];
1417  rmax[1] = y1 > rmax[1] ? y1 : rmax[1];
1418  rmax[2] = z1 > rmax[2] ? z1 : rmax[2];
1419  break;
1420 
1421  case 1: // shrink view
1422  GetRange(rmin, rmax);
1423  rmin[0] = x0 > rmin[0] ? x0 : rmin[0];
1424  rmin[1] = y0 > rmin[1] ? y0 : rmin[1];
1425  rmin[2] = z0 > rmin[2] ? z0 : rmin[2];
1426  rmax[0] = x1 < rmax[0] ? x1 : rmax[0];
1427  rmax[1] = y1 < rmax[1] ? y1 : rmax[1];
1428  rmax[2] = z1 < rmax[2] ? z1 : rmax[2];
1429  break;
1430 
1431  default:
1432  rmin[0] = x0; rmax[0] = x1;
1433  rmin[1] = y0; rmax[1] = y1;
1434  rmin[2] = z0; rmax[2] = z1;
1435  }
1436  SetRange(rmin, rmax);
1437 }
1438 
1439 ////////////////////////////////////////////////////////////////////////////////
1440 /// Set viewing window.
1441 
1443 {
1444  fUVcoord[0] = u0;
1445  fUVcoord[1] = v0;
1446  fUVcoord[2] = du;
1447  fUVcoord[3] = dv;
1448 }
1449 
1450 ////////////////////////////////////////////////////////////////////////////////
1451 /// Set view parameters.
1452 
1453 void TView3D::SetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)
1454 {
1455  ResetView(longitude, latitude, psi, irep);
1456 }
1457 
1458 ////////////////////////////////////////////////////////////////////////////////
1459 /// Recompute window for perspective view.
1460 
1462 {
1463  if (!IsPerspective()) return;
1464  Double_t upix = fUpix;
1465  Double_t vpix = fVpix;
1466 
1467  // width in pixels
1468  fUpix = gPad->GetWw()*gPad->GetAbsWNDC();
1469 
1470  // height in pixels
1471  fVpix = gPad->GetWh()*gPad->GetAbsHNDC();
1472  Double_t u0 = fUVcoord[0]*fUpix/upix;
1473  Double_t v0 = fUVcoord[1]*fVpix/vpix;
1474  Double_t du = fUVcoord[2]*fUpix/upix;
1475  Double_t dv = fUVcoord[3]*fVpix/vpix;
1476  SetWindow(u0, v0, du, dv);
1478 }
1479 
1480 ////////////////////////////////////////////////////////////////////////////////
1481 /// Set view direction (in spherical coordinates).
1482 ///
1483 /// Input
1484 /// - PHI - longitude
1485 /// - THETA - latitude (angle between +Z and view direction)
1486 /// - PSI - rotation in screen plane
1487 ///
1488 /// Output:
1489 /// - IREP - reply (-1 if error in min-max)
1490 ///
1491 /// Errors: error in min-max scope
1492 
1493 void TView3D::ResetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)
1494 {
1495  Double_t scale[3], centre[3];
1496  Double_t c1, c2, c3, s1, s2, s3;
1497 
1498  //*-*- F I N D C E N T E R O F S C O P E A N D
1499  //*-*- S C A L E F A C T O R S
1500  FindScope(scale, centre, irep);
1501  if (irep < 0) {
1502  Error("ResetView", "Error in min-max scope");
1503  return;
1504  }
1505 
1506  //*-*- S E T T R A N S F O R M A T I O N M A T R I C E S
1507  fLongitude = longitude;
1508  fPsi = psi;
1509  fLatitude = latitude;
1510 
1511  if (IsPerspective()) {
1513  return;
1514  }
1515 
1516  c1 = TMath::Cos(longitude*kRad);
1517  s1 = TMath::Sin(longitude*kRad);
1518  c2 = TMath::Cos(latitude*kRad);
1519  s2 = TMath::Sin(latitude*kRad);
1520  c3 = TMath::Cos(psi*kRad);
1521  s3 = TMath::Sin(psi*kRad);
1522  DefineViewDirection(scale, centre, c1, s1, c2, s2, c3, s3, fTnorm, fTback);
1523  c3 = 1;
1524  s3 = 0;
1525  DefineViewDirection(scale, centre, c1, s1, c2, s2, c3, s3, fTN, fTB);
1526 }
1527 
1528 ////////////////////////////////////////////////////////////////////////////////
1529 /// Transfer point from world to normalized coordinates.
1530 ///
1531 /// Input:
1532 /// - PW(3) - point in world coordinate system
1533 /// - PN(3) - point in normalized coordinate system
1534 
1535 void TView3D::WCtoNDC(const Float_t *pw, Float_t *pn)
1536 {
1537  // perspective view
1538  if (IsPerspective()) {
1539  for (Int_t i=0; i<3; i++)
1540  pn[i] = pw[0]*fTnorm[i]+pw[1]*fTnorm[i+4]+pw[2]*fTnorm[i+8]+fTnorm[i+12];
1541  if (pn[2]>0) {
1542  pn[0] /= pn[2];
1543  pn[1] /= pn[2];
1544  } else {
1545  pn[0] *= 1000.;
1546  pn[1] *= 1000.;
1547  }
1548  return;
1549  }
1550  // parallel view
1551  pn[0] = fTnorm[0]*pw[0] + fTnorm[1]*pw[1] + fTnorm[2]*pw[2] + fTnorm[3];
1552  pn[1] = fTnorm[4]*pw[0] + fTnorm[5]*pw[1] + fTnorm[6]*pw[2] + fTnorm[7];
1553  pn[2] = fTnorm[8]*pw[0] + fTnorm[9]*pw[1] + fTnorm[10]*pw[2] + fTnorm[11];
1554 }
1555 
1556 ////////////////////////////////////////////////////////////////////////////////
1557 /// Transfer point from world to normalized coordinates.
1558 ///
1559 /// Input:
1560 /// - PW(3) - point in world coordinate system
1561 /// - PN(3) - point in normalized coordinate system
1562 
1563 void TView3D::WCtoNDC(const Double_t *pw, Double_t *pn)
1564 {
1565  // perspective view
1566  if (IsPerspective()) {
1567  for (Int_t i=0; i<3; i++)
1568  pn[i] = pw[0]*fTnorm[i]+pw[1]*fTnorm[i+4]+pw[2]*fTnorm[i+8]+fTnorm[i+12];
1569  if (pn[2]>0) {
1570  pn[0] /= pn[2];
1571  pn[1] /= pn[2];
1572  } else {
1573  pn[0] *= 1000.;
1574  pn[1] *= 1000.;
1575  }
1576  return;
1577  }
1578 
1579  // parallel view
1580  pn[0] = fTnorm[0]*pw[0] + fTnorm[1]*pw[1] + fTnorm[2]*pw[2] + fTnorm[3];
1581  pn[1] = fTnorm[4]*pw[0] + fTnorm[5]*pw[1] + fTnorm[6]*pw[2] + fTnorm[7];
1582  pn[2] = fTnorm[8]*pw[0] + fTnorm[9]*pw[1] + fTnorm[10]*pw[2] + fTnorm[11];
1583 }
1584 
1585 ////////////////////////////////////////////////////////////////////////////////
1586 /// Force the current pad to be updated.
1587 
1589 {
1590  TVirtualPad *thisPad = pad;
1591  if (!thisPad) thisPad = gPad;
1592  if (thisPad) {
1593 #ifdef R__HAS_COCOA
1594  thisPad->AbsCoordinates(kFALSE);
1595 #endif
1596  thisPad->Modified();
1597  thisPad->Update();
1598  }
1599 }
1600 
1601 ////////////////////////////////////////////////////////////////////////////////
1602 /// API to rotate view and adjust the pad provided it the current one.
1603 
1605 {
1606  Int_t iret;
1607  Double_t p = phi;
1608  Double_t t = theta;
1609  SetView(p, t, 0, iret);
1610 
1611  // Adjust current pad too
1612  TVirtualPad *thisPad = pad;
1613  if (!thisPad) thisPad = gPad;
1614  if (thisPad) {
1615  thisPad->SetPhi(-90-p);
1616  thisPad->SetTheta(90-t);
1617  thisPad->Modified();
1618  thisPad->Update();
1619  }
1620 }
1621 
1622 ////////////////////////////////////////////////////////////////////////////////
1623 /// Set to side view.
1624 
1626 {
1627  RotateView(0,90.0,pad);
1628 }
1629 
1630 ////////////////////////////////////////////////////////////////////////////////
1631 /// Set to front view.
1632 
1634 {
1635  RotateView(270.0,90.0,pad);
1636 }
1637 
1638 ////////////////////////////////////////////////////////////////////////////////
1639 /// Set to top view.
1640 
1642 {
1643  RotateView(270.0,0.0,pad);
1644 }
1645 
1646 ////////////////////////////////////////////////////////////////////////////////
1647 /// Turn on /off 3D axis.
1648 
1650 {
1651  TAxis3D::ToggleRulers(pad);
1652 }
1653 
1654 ////////////////////////////////////////////////////////////////////////////////
1655 /// Turn on /off the interactive option to
1656 /// Zoom / Move / Change attributes of 3D axis correspond this view.
1657 
1659 {
1660  TAxis3D::ToggleZoom(pad);
1661 }
1662 
1663 ////////////////////////////////////////////////////////////////////////////////
1664 /// Adjust all sides of view in respect of the biggest one.
1665 
1667 {
1668  Double_t min[3],max[3];
1669  GetRange(min,max);
1670  int i;
1671  Double_t maxSide = 0;
1672  // Find the largest side
1673  for (i=0;i<3; i++) maxSide = TMath::Max(maxSide,max[i]-min[i]);
1674  //Adjust scales:
1675  for (i=0;i<3; i++) max[i] += maxSide - (max[i]-min[i]);
1676  SetRange(min,max);
1677 
1678  AdjustPad(pad);
1679 }
1680 
1681 ////////////////////////////////////////////////////////////////////////////////
1682 /// Move view into the center of the scene.
1683 
1685 {
1686  Double_t min[3],max[3];
1687  GetRange(min,max);
1688  int i;
1689  for (i=0;i<3; i++) {
1690  if (max[i] > 0) min[i] = -max[i];
1691  else max[i] = -min[i];
1692  }
1693  SetRange(min,max);
1694  AdjustPad(pad);
1695 }
1696 
1697 ////////////////////////////////////////////////////////////////////////////////
1698 /// unZOOM this view.
1699 
1700 void TView3D::UnzoomView(TVirtualPad *pad,Double_t unZoomFactor )
1701 {
1702  if (TMath::Abs(unZoomFactor) < 0.001) return;
1703  ZoomView(pad,1./unZoomFactor);
1704 }
1705 
1706 ////////////////////////////////////////////////////////////////////////////////
1707 /// ZOOM this view.
1708 
1710 {
1711  if (TMath::Abs(zoomFactor) < 0.001) return;
1712  Double_t min[3],max[3];
1713  GetRange(min,max);
1714  int i;
1715  for (i=0;i<3; i++) {
1716  // Find center
1717  Double_t c = (max[i]+min[i])/2;
1718  // Find a new size
1719  Double_t s = (max[i]-min[i])/(2*zoomFactor);
1720  // Set a new size
1721  max[i] = c + s;
1722  min[i] = c - s;
1723  }
1724  SetRange(min,max);
1725  AdjustPad(pad);
1726 }
1727 
1728 ////////////////////////////////////////////////////////////////////////////////
1729 /// Move focus to a different box position and extent in nsteps. Perform
1730 /// rotation with dlat,dlong,dpsi at each step.
1731 
1733  Double_t dlong, Double_t dlat, Double_t dpsi)
1734 {
1735  if (!IsPerspective()) return;
1736  if (nsteps<1) return;
1737  Double_t fc = 1./Double_t(nsteps);
1738  Double_t oc[3], od[3], dir[3];
1739  dir[0] = 0;
1740  dir[1] = 0;
1741  dir[2] = 1.;
1742  Int_t i, j;
1743  for (i=0; i<3; i++) {
1744  oc[i] = 0.5*(fRmin[i]+fRmax[i]);
1745  od[i] = 0.5*(fRmax[i]-fRmin[i]);
1746  }
1747  Double_t dox = cov[0]-oc[0];
1748  Double_t doy = cov[1]-oc[1];
1749  Double_t doz = cov[2]-oc[2];
1750 
1751  Double_t dd = TMath::Sqrt(dox*dox+doy*doy+doz*doz);
1752  if (dd!=0) {;
1753  dir[0] = dox/dd;
1754  dir[1] = doy/dd;
1755  dir[2] = doz/dd;
1756  }
1757  dd *= fc;
1758  dox = fc*(dx-od[0]);
1759  doy = fc*(dy-od[1]);
1760  doz = fc*(dz-od[2]);
1761  for (i=0; i<nsteps; i++) {
1762  oc[0] += dd*dir[0];
1763  oc[1] += dd*dir[1];
1764  oc[2] += dd*dir[2];
1765  od[0] += dox;
1766  od[1] += doy;
1767  od[2] += doz;
1768  for (j=0; j<3; j++) {
1769  fRmin[j] = oc[j]-od[j];
1770  fRmax[j] = oc[j]+od[j];
1771  }
1772  SetDefaultWindow();
1773  fLatitude += dlat;
1774  fLongitude += dlong;
1775  fPsi += dpsi;
1777  if (gPad) {
1778  gPad->Modified();
1779  gPad->Update();
1780  }
1781  }
1782 }
1783 
1784 ////////////////////////////////////////////////////////////////////////////////
1785 /// - 'a' increase scale factor (clip cube borders)
1786 /// - 's' decrease scale factor (clip cube borders)
1787 
1789 {
1790  if (count <= 0) count = 1;
1791  switch (option) {
1792  case '+':
1793  ZoomView();
1794  break;
1795  case '-':
1796  UnzoomView();
1797  break;
1798  case 's':
1799  case 'S':
1800  UnzoomView();
1801  break;
1802  case 'a':
1803  case 'A':
1804  ZoomView();
1805  break;
1806  case 'l':
1807  case 'L':
1808  case 'h':
1809  case 'H':
1810  case 'u':
1811  case 'U':
1812  case 'i':
1813  case 'I':
1814  MoveWindow(option);
1815  break;
1816  case 'j':
1817  case 'J':
1818  ZoomIn();
1819  break;
1820  case 'k':
1821  case 'K':
1822  ZoomOut();
1823  break;
1824  default:
1825  break;
1826  }
1827 }
1828 
1829 ////////////////////////////////////////////////////////////////////////////////
1830 /// Move view window :
1831 /// - l,L - left
1832 /// - h,H - right
1833 /// - u,U - down
1834 /// - i,I - up
1835 
1837 {
1838  if (!IsPerspective()) return;
1839  Double_t shiftu = 0.1*fUVcoord[2];
1840  Double_t shiftv = 0.1*fUVcoord[3];
1841  switch (option) {
1842  case 'l':
1843  case 'L':
1844  fUVcoord[0] += shiftu;
1845  break;
1846  case 'h':
1847  case 'H':
1848  fUVcoord[0] -= shiftu;
1849  break;
1850  case 'u':
1851  case 'U':
1852  fUVcoord[1] += shiftv;
1853  break;
1854  case 'i':
1855  case 'I':
1856  fUVcoord[1] -= shiftv;
1857  break;
1858  default:
1859  return;
1860  }
1862  if (gPad) {
1863  gPad->Modified();
1864  gPad->Update();
1865  }
1866 }
1867 
1868 ////////////////////////////////////////////////////////////////////////////////
1869 /// Zoom in.
1870 
1872 {
1873  if (!IsPerspective()) return;
1874  Double_t extent = GetExtent();
1875  Double_t fc = 0.1;
1876  if (fDview<extent) {
1877  fDview -= fc*extent;
1878  } else {
1879  fDview /= 1.25;
1880  }
1882  if (gPad) {
1883  gPad->Modified();
1884  gPad->Update();
1885  }
1886 }
1887 
1888 ////////////////////////////////////////////////////////////////////////////////
1889 /// Zoom out.
1890 
1892 {
1893  if (!IsPerspective()) return;
1894  Double_t extent = GetExtent();
1895  Double_t fc = 0.1;
1896  if (fDview<extent) {
1897  fDview += fc*extent;
1898  } else {
1899  fDview *= 1.25;
1900  }
1902  if (gPad) {
1903  gPad->Modified();
1904  gPad->Update();
1905  }
1906 }
1907 
1908 ////////////////////////////////////////////////////////////////////////////////
1909 /// Stream an object of class TView3D.
1910 
1911 void TView3D::Streamer(TBuffer &R__b)
1912 {
1913  if (R__b.IsReading()) {
1914  UInt_t R__s, R__c;
1915  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1916  if (R__v > 1) {
1917  R__b.ReadClassBuffer(TView3D::Class(), this, R__v, R__s, R__c);
1918  return;
1919  }
1920  //====process old versions before automatic schema evolution
1921  //unfortunately we forgot to increment the TView3D version number
1922  //when the class was upgraded to double precision in version 2.25.
1923  //we are forced to use the file version number to recognize old files.
1924  if (R__b.GetParent() && R__b.GetVersionOwner() < 22500) { //old version in single precision
1925  TObject::Streamer(R__b);
1926  TAttLine::Streamer(R__b);
1927  Float_t single, sa[12];
1928  Int_t i;
1929  R__b >> fSystem;
1930  R__b >> single; fLatitude = single;
1931  R__b >> single; fLongitude = single;
1932  R__b >> single; fPsi = single;
1933  R__b.ReadStaticArray(sa); for (i=0;i<12;i++) fTN[i] = sa[i];
1934  R__b.ReadStaticArray(sa); for (i=0;i<12;i++) fTB[i] = sa[i];
1935  R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fRmax[i] = sa[i];
1936  R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fRmin[i] = sa[i];
1937  R__b.ReadStaticArray(sa); for (i=0;i<12;i++) fTnorm[i] = sa[i];
1938  R__b.ReadStaticArray(sa); for (i=0;i<12;i++) fTback[i] = sa[i];
1939  R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fX1[i] = sa[i];
1940  R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fX2[i] = sa[i];
1941  R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fY1[i] = sa[i];
1942  R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fY2[i] = sa[i];
1943  R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fZ1[i] = sa[i];
1944  R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fZ2[i] = sa[i];
1945  R__b >> fOutline;
1946  R__b >> fDefaultOutline;
1947  R__b >> fAutoRange;
1948  } else {
1949  TObject::Streamer(R__b);
1950  TAttLine::Streamer(R__b);
1951  R__b >> fLatitude;
1952  R__b >> fLongitude;
1953  R__b >> fPsi;
1954  R__b.ReadStaticArray(fTN);
1955  R__b.ReadStaticArray(fTB);
1956  R__b.ReadStaticArray(fRmax);
1957  R__b.ReadStaticArray(fRmin);
1958  R__b.ReadStaticArray(fTnorm);
1959  R__b.ReadStaticArray(fTback);
1960  R__b.ReadStaticArray(fX1);
1961  R__b.ReadStaticArray(fX2);
1962  R__b.ReadStaticArray(fY1);
1963  R__b.ReadStaticArray(fY2);
1964  R__b.ReadStaticArray(fZ1);
1965  R__b.ReadStaticArray(fZ2);
1966  R__b >> fSystem;
1967  R__b >> fOutline;
1968  R__b >> fDefaultOutline;
1969  R__b >> fAutoRange;
1970  }
1971  //====end of old versions
1972 
1973  } else {
1974  R__b.WriteClassBuffer(TView3D::Class(),this);
1975  }
1976 }
1977 
1978 // Shortcuts for menus
1987 
1988 
virtual void ResizePad()
Recompute window for perspective view.
Definition: TView3D.cxx:1461
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition: TBuffer.cxx:229
virtual void WCtoNDC(const Float_t *pw, Float_t *pn)
Transfer point from world to normalized coordinates.
Definition: TView3D.cxx:1535
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
virtual void MoveFocus(Double_t *center, Double_t dx, Double_t dy, Double_t dz, Int_t nsteps=10, Double_t dlong=0, Double_t dlat=0, Double_t dpsi=0)
Move focus to a different box position and extent in nsteps.
Definition: TView3D.cxx:1732
Double_t fUpix
Definition: TView3D.h:39
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TView3D.cxx:686
float xmin
Definition: THbookFile.cxx:93
Double_t fPsi
Definition: TView3D.h:36
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
Double_t fVpix
Definition: TView3D.h:40
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
Int_t fSystem
Definition: TView3D.h:54
static TAxis3D * ToggleZoom(TVirtualPad *pad=0)
Turn ON / OFF the "Ruler" and "zoom mode" of the TAxis3D object attached to the current pad (if pad =...
Definition: TAxis3D.cxx:766
virtual void SetOutlineToCube()
This is a function which creates default outline.
Definition: TView3D.cxx:1348
Double_t fLatitude
Definition: TView3D.h:34
Bool_t IsReading() const
Definition: TBuffer.h:81
virtual void AxisVertex(Double_t ang, Double_t *av, Int_t &ix1, Int_t &ix2, Int_t &iy1, Int_t &iy2, Int_t &iz1, Int_t &iz2)
Define axis vertices.
Definition: TView3D.cxx:310
virtual void DrawOutlineCube(TList *outline, Double_t *rmin, Double_t *rmax)
Draw the outline of a cube while rotating a 3-d object in the pad.
Definition: TView3D.cxx:678
static TAxis3D * ToggleRulers(TVirtualPad *pad=0)
Turn ON / OFF the "Ruler", TAxis3D object attached to the current pad.
Definition: TAxis3D.cxx:738
short Version_t
Definition: RtypesCore.h:61
Double_t fTB[16]
Definition: TView3D.h:42
virtual void UnZoom()
Definition: TView3D.cxx:1986
Double_t fRmin[3]
Definition: TView3D.h:44
float Float_t
Definition: RtypesCore.h:53
virtual Double_t GetPsi()
Definition: TView3D.h:94
TCanvas * c1
Definition: legend1.C:2
float ymin
Definition: THbookFile.cxx:93
virtual void ZoomMove()
Definition: TView3D.cxx:1984
virtual void ZoomOut()
Zoom out.
Definition: TView3D.cxx:1891
virtual void Update()=0
virtual void ZoomView(TVirtualPad *pad=0, Double_t zoomFactor=1.25)
ZOOM this view.
Definition: TView3D.cxx:1709
Double_t fZ1[3]
Definition: TView3D.h:52
virtual void SetTheta(Double_t theta=30)=0
See TView3D.
Definition: TView.h:36
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
virtual void ToggleZoom(TVirtualPad *pad=0)
Turn on /off the interactive option to Zoom / Move / Change attributes of 3D axis correspond this vie...
Definition: TView3D.cxx:1658
Bool_t fChanged
Definition: TView3D.h:58
virtual void Centered()
Definition: TView3D.cxx:1979
Bool_t fDefaultOutline
Definition: TView3D.h:56
Double_t fTN[16]
Definition: TView3D.h:41
ClassImp(TView3D) const Int_t kCARTESIAN
#define gROOT
Definition: TROOT.h:340
virtual void SetAxisNDC(const Double_t *x1, const Double_t *x2, const Double_t *y1, const Double_t *y2, const Double_t *z1, const Double_t *z2)
Store axis coordinates in the NDC system.
Definition: TView3D.cxx:1293
virtual void PadRange(Int_t rback)
Set the correct window size for lego and surface plots.
Definition: TView3D.cxx:1214
virtual void MoveViewCommand(Char_t chCode, Int_t count=1)
Definition: TView3D.cxx:1788
virtual void NormalWCtoNDC(const Float_t *pw, Float_t *pn)
Transfer vector of NORMAL from word to normalized coordinates.
Definition: TView3D.cxx:1156
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual void FindPhiSectors(Int_t iopt, Int_t &kphi, Double_t *aphi, Int_t &iphi1, Int_t &iphi2)
Find critical PHI sectors.
Definition: TView3D.cxx:864
virtual void Zoom()
Definition: TView3D.cxx:1985
Double_t fRmax[3]
Definition: TView3D.h:43
virtual void ShowAxis()
Definition: TView3D.cxx:1981
Double_t fTback[16]
Definition: TView3D.h:47
virtual void SetParallel()
Set the parallel option (default).
Definition: TView3D.cxx:1360
virtual Int_t ReadStaticArray(Bool_t *b)=0
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
virtual ~TView3D()
TView3D default destructor.
Definition: TView3D.cxx:275
void ResetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)
Set view direction (in spherical coordinates).
Definition: TView3D.cxx:1493
virtual void Delete(Option_t *option="")=0
Delete this object.
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:839
static const double x2[5]
Double_t x[n]
Definition: legend1.C:17
void Class()
Definition: Class.C:29
TView3D & operator=(const TView3D &)
Assignment operator.
Definition: TView3D.cxx:234
virtual Int_t GetVersionOwner() const =0
virtual void DefinePerspectiveView()
Define perspective view.
Definition: TView3D.cxx:458
unsigned int r3[N_CITIES]
Definition: simanTSP.cxx:323
virtual Int_t GetSystem()
Definition: TView3D.h:103
virtual void Centered3DImages(TVirtualPad *pad=0)
Move view into the center of the scene.
Definition: TView3D.cxx:1684
TText * th2
Definition: textalign.C:17
virtual void ZoomIn()
Zoom in.
Definition: TView3D.cxx:1871
virtual void SetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)
Set view parameters.
Definition: TView3D.cxx:1453
Double_t fX2[3]
Definition: TView3D.h:49
virtual void FindScope(Double_t *scale, Double_t *center, Int_t &irep)
Find centre of a MIN-MAX scope and scale factors.
Definition: TView3D.cxx:991
Double_t fLongitude
Definition: TView3D.h:35
Abstract 3D shapes viewer.
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Definition: TObject.cxx:102
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
virtual void TopView(TVirtualPad *pad=0)
Set to top view.
Definition: TView3D.cxx:1641
virtual void FrontView(TVirtualPad *pad=0)
Set to front view.
Definition: TView3D.cxx:1633
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:59
virtual void NDCtoWC(const Float_t *pn, Float_t *pw)
Transfer point from normalized to world coordinates.
Definition: TView3D.cxx:1128
virtual void GetWindow(Double_t &u0, Double_t &v0, Double_t &du, Double_t &dv) const
Get current window extent.
Definition: TView3D.cxx:1103
TText * th1
Definition: textalign.C:13
A doubly linked list.
Definition: TList.h:47
Double_t fDview
Definition: TView3D.h:37
static void DrawOutlineCube(TList *outline, Double_t *rmin, Double_t *rmax)
Draw cube outline with 3d polylines.
virtual void AdjustScales(TVirtualPad *pad=0)
Adjust all sides of view in respect of the biggest one.
Definition: TView3D.cxx:1666
float ymax
Definition: THbookFile.cxx:93
const Int_t kPOLAR
Definition: TView3D.cxx:33
SVector< double, 2 > v
Definition: Dict.h:5
Double_t fX1[3]
Definition: TView3D.h:48
virtual void ToggleRulers(TVirtualPad *pad=0)
Turn on /off 3D axis.
Definition: TView3D.cxx:1649
The 3D view class.
Definition: TView3D.h:31
unsigned int r1[N_CITIES]
Definition: simanTSP.cxx:321
virtual void FindThetaSectors(Int_t iopt, Double_t phi, Int_t &kth, Double_t *ath, Int_t &ith1, Int_t &ith2)
Find critical THETA sectors for given PHI sector.
Definition: TView3D.cxx:930
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Paint(Option_t *option="")
Paint all objects in this collection.
virtual void ExecuteRotateView(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TView3D.cxx:700
float xmax
Definition: THbookFile.cxx:93
virtual void Top()
Definition: TView3D.cxx:1983
Double_t fDproj
Definition: TView3D.h:38
virtual void Side()
Definition: TView3D.cxx:1982
#define gVirtualX
Definition: TVirtualX.h:362
Double_t Cos(Double_t)
Definition: TMath.h:424
Double_t fZ2[3]
Definition: TView3D.h:53
virtual void SetPerspective()
Set perspective option.
Definition: TView3D.cxx:1371
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual void Modified(Bool_t flag=1)=0
virtual void Front()
Definition: TView3D.cxx:1980
return c2
Definition: legend2.C:14
virtual void RotateView(Double_t phi, Double_t theta, TVirtualPad *pad=0)
API to rotate view and adjust the pad provided it the current one.
Definition: TView3D.cxx:1604
static const double x1[5]
virtual void DefineViewDirection(const Double_t *s, const Double_t *c, Double_t cosphi, Double_t sinphi, Double_t costhe, Double_t sinthe, Double_t cospsi, Double_t sinpsi, Double_t *tnorm, Double_t *tback)
Define view direction (in spherical coordinates)
Definition: TView3D.cxx:572
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
double Double_t
Definition: RtypesCore.h:55
virtual void SetDefaultWindow()
Set default viewing window.
Definition: TView3D.cxx:1308
const Double_t kRad
Definition: TView3D.cxx:34
Double_t y[n]
Definition: legend1.C:17
virtual void GetRange(Float_t *min, Float_t *max)
Get Range function.
Definition: TView3D.cxx:1087
virtual void SetWindow(Double_t u0, Double_t v0, Double_t du, Double_t dv)
Set viewing window.
Definition: TView3D.cxx:1442
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
virtual void SetPhi(Double_t phi=30)=0
virtual void SideView(TVirtualPad *pad=0)
Set to side view.
Definition: TView3D.cxx:1625
char Char_t
Definition: RtypesCore.h:29
TView3D()
Default constructor.
Definition: TView3D.cxx:108
TSeqCollection * fOutline
Definition: TView3D.h:55
virtual void MoveWindow(Char_t option)
Move view window :
Definition: TView3D.cxx:1836
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
Double_t fY1[3]
Definition: TView3D.h:50
Double_t fTnorm[16]
Definition: TView3D.h:46
Double_t Sin(Double_t)
Definition: TMath.h:421
virtual Double_t GetExtent() const
Get maximum view extent.
Definition: TView3D.cxx:1075
Double_t fUVcoord[4]
Definition: TView3D.h:45
virtual Int_t GetDistancetoAxis(Int_t axis, Int_t px, Int_t py, Double_t &ratio)
Return distance to axis from point px,py.
Definition: TView3D.cxx:1029
#define gPad
Definition: TVirtualPad.h:288
Double_t fY2[3]
Definition: TView3D.h:51
virtual void SetRange(const Double_t *min, const Double_t *max)
Set Range function.
Definition: TView3D.cxx:1383
virtual Bool_t IsClippedNDC(Double_t *p) const
Check if point is clipped in perspective view.
Definition: TView3D.cxx:1114
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual Bool_t IsPerspective() const
Definition: TView3D.h:111
const Int_t kCARTESIAN
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void UnzoomView(TVirtualPad *pad=0, Double_t unZoomFactor=1.25)
unZOOM this view.
Definition: TView3D.cxx:1700
return c3
Definition: legend3.C:15
virtual void AbsCoordinates(Bool_t set)=0
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
virtual void FindNormal(Double_t x, Double_t y, Double_t z, Double_t &zn)
Find Z component of NORMAL in normalized coordinates.
Definition: TView3D.cxx:844
static void AdjustPad(TVirtualPad *pad=0)
Force the current pad to be updated.
Definition: TView3D.cxx:1588
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
Bool_t fAutoRange
Definition: TView3D.h:57