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