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