Logo ROOT  
Reference Guide
REveProjections.cxx
Go to the documentation of this file.
1// @(#)root/eve7:$Id$
2// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2019, 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 "TError.h"
13
15#include <ROOT/REveTrans.hxx>
16#include <ROOT/REveUtil.hxx>
17
18#include <limits>
19
20using namespace ROOT::Experimental;
21
22/** \class REveProjection
23\ingroup REve
24Base-class for non-linear projections.
25
26Enables to define an external center of distortion and a scale to
27fixate a bounding box of a projected point.
28*/
29
30Float_t REveProjection::fgEps = 0.005f;
31Float_t REveProjection::fgEpsSqr = 0.000025f;
32
33////////////////////////////////////////////////////////////////////////////////
34/// Constructor.
35
36REveProjection::REveProjection() :
37 fType (kPT_Unknown),
38 fGeoMode (kGM_Unknown),
39 fName (),
40 fCenter (),
41 fDisplaceOrigin (kFALSE),
42 fUsePreScale (kFALSE),
43 fDistortion (0.0f),
44 fFixR (300), fFixZ (400),
45 fPastFixRFac (0), fPastFixZFac (0),
46 fScaleR (1), fScaleZ (1),
47 fPastFixRScale (1), fPastFixZScale (1),
48 fMaxTrackStep (25) // XXXXX This is STOOPID ... see also comment in REveTrackProjected::MakeTrack()
49{
50}
51
52////////////////////////////////////////////////////////////////////////////////
53/// Project float array.
54
56{
57 ProjectPoint(v[0], v[1], v[2], d);
58}
59
60////////////////////////////////////////////////////////////////////////////////
61/// Project double array.
62/// This is a bit piggish as we convert the doubles to floats and back.
63
65{
66 Float_t x = v[0], y = v[1], z = v[2];
67 ProjectPoint(x, y, z, d);
68 v[0] = x; v[1] = y; v[2] = z;
69}
70
71////////////////////////////////////////////////////////////////////////////////
72/// Project REveVector.
73
75{
76 ProjectPoint(v.fX, v.fY, v.fZ, d);
77}
78
79////////////////////////////////////////////////////////////////////////////////
80/// Project float array, converting it to global coordinate system first if
81/// transformation matrix is set.
82
84{
85 v[0] = p[0]; v[1] = p[1]; v[2] = p[2];
86 if (t)
87 {
88 t->MultiplyIP(v);
89 }
90 ProjectPoint(v[0], v[1], v[2], d);
91}
92
93////////////////////////////////////////////////////////////////////////////////
94/// Project double array, converting it to global coordinate system first if
95/// transformation matrix is set.
96/// This is a bit piggish as we convert the doubles to floats and back.
97
99{
100 Float_t x, y, z;
101 if (t)
102 {
103 t->Multiply(p, v);
104 x = v[0]; y = v[1]; z = v[2];
105 }
106 else
107 {
108 x = p[0]; y = p[1]; z = p[2];
109 }
110 ProjectPoint(x, y, z, d);
111 v[0] = x; v[1] = y; v[2] = z;
112}
113
114////////////////////////////////////////////////////////////////////////////////
115/// Project REveVector, converting it to global coordinate system first if
116/// transformation matrix is set.
117
119{
120 if (t)
121 {
122 t->MultiplyIP(v);
123 }
124 ProjectPoint(v.fX, v.fY, v.fZ, d);
125}
126
127////////////////////////////////////////////////////////////////////////////////
128/// Pre-scale single variable with pre-scale entry dim.
129
131{
132 if (!fPreScales[dim].empty())
133 {
134 Bool_t invp = kFALSE;
135 if (v < 0) {
136 v = -v;
137 invp = kTRUE;
138 }
139 auto i = fPreScales[dim].begin();
140 while (v > i->fMax)
141 ++i;
142 v = i->fOffset + (v - i->fMin)*i->fScale;
143 if (invp)
144 v = -v;
145 }
146}
147
148////////////////////////////////////////////////////////////////////////////////
149/// Pre-scale point (x, y) in projected coordinates for 2D projections:
150/// - RhoZ ~ (rho, z)
151/// - RPhi ~ (r, phi), scaling phi doesn't make much sense.
152
154{
157}
158
159////////////////////////////////////////////////////////////////////////////////
160/// Pre-scale point (x, y, z) in projected coordinates for 3D projection.
161
163{
166 PreScaleVariable(2, z);
167}
168
169////////////////////////////////////////////////////////////////////////////////
170/// Add new scaling range for given coordinate.
171/// Arguments:
172/// - coord 0 ~ x, 1 ~ y, 2 ~ z
173/// - value value of input coordinate from which to apply this scale;
174/// - scale the scale to apply from value onwards.
175///
176/// NOTE: If pre-scaling is combined with center-displaced then
177/// the scale of the central region should be 1. This limitation
178/// can be removed but will cost CPU.
179
181{
182 static const REveException eh("REveProjection::AddPreScaleEntry ");
183
184 if (coord < 0 || coord > 2)
185 throw (eh + "coordinate out of range.");
186
187 const Float_t infty = std::numeric_limits<Float_t>::infinity();
188
189 vPreScale_t& vec = fPreScales[coord];
190
191 if (vec.empty())
192 {
193 if (value == 0)
194 {
195 vec.emplace_back(0, infty, 0, scale);
196 }
197 else
198 {
199 vec.emplace_back(0, value, 0, 1);
200 vec.emplace_back(value, infty, value, scale);
201 }
202 }
203 else
204 {
205 PreScaleEntry_t& prev = vec.back();
206 if (value <= prev.fMin)
207 throw (eh + "minimum value not larger than previous one.");
208
209 prev.fMax = value;
210 Float_t offset = prev.fOffset + (prev.fMax - prev.fMin)*prev.fScale;
211 vec.emplace_back(value, infty, offset, scale);
212 }
213}
214
215////////////////////////////////////////////////////////////////////////////////
216/// Change scale for given entry and coordinate.
217///
218/// NOTE: If the first entry you created used other value than 0,
219/// one entry (covering range from 0 to this value) was created
220/// automatically.
221
223 Float_t new_scale)
224{
225 static const REveException eh("REveProjection::ChangePreScaleEntry ");
226
227 if (coord < 0 || coord > 2)
228 throw (eh + "coordinate out of range.");
229
230 vPreScale_t& vec = fPreScales[coord];
231 Int_t vs = vec.size();
232 if (entry < 0 || entry >= vs)
233 throw (eh + "entry out of range.");
234
235 vec[entry].fScale = new_scale;
236 Int_t i0 = entry, i1 = entry + 1;
237 while (i1 < vs)
238 {
239 PreScaleEntry_t e0 = vec[i0];
240 vec[i1].fOffset = e0.fOffset + (e0.fMax - e0.fMin)*e0.fScale;
241 i0 = i1++;
242 }
243}
244
245////////////////////////////////////////////////////////////////////////////////
246/// Clear all pre-scaling information.
247
249{
250 fPreScales[0].clear();
251 fPreScales[1].clear();
252 fPreScales[2].clear();
253}
254
255////////////////////////////////////////////////////////////////////////////////
256/// Set distortion.
257
259{
260 fDistortion = d;
261 fScaleR = 1.0f + fFixR*fDistortion;
262 fScaleZ = 1.0f + fFixZ*fDistortion;
265}
266
267////////////////////////////////////////////////////////////////////////////////
268/// Set fixed radius.
269
271{
272 fFixR = r;
275}
276
277////////////////////////////////////////////////////////////////////////////////
278/// Set fixed radius.
279
281{
282 fFixZ = z;
285}
286
287////////////////////////////////////////////////////////////////////////////////
288/// Set 2's-exponent for relative scaling beyond FixR.
289
291{
292 fPastFixRFac = x;
294}
295
296////////////////////////////////////////////////////////////////////////////////
297/// Get projected center.
298
300{
301 static REveVector zero;
302
303 if (fDisplaceOrigin)
304 return zero.Arr();
305 else
306 return fCenter.Arr();
307}
308
309////////////////////////////////////////////////////////////////////////////////
310/// Set flag to displace for center.
311/// This options is useful if want to have projected center
312/// at (0, 0) position in projected coordinates and want to dismiss
313/// gap around projected center in RhoZ projection.
314
316{
318 // update projected center
320}
321
322////////////////////////////////////////////////////////////////////////////////
323/// Set 2's-exponent for relative scaling beyond FixZ.
324
326{
327 fPastFixZFac = x;
329}
330
331////////////////////////////////////////////////////////////////////////////////
332/// Find break-point on both sides of the discontinuity.
333/// They still need to be projected after the call.
334/// This is an obsolete version of the method that required manual
335/// specification of precision -- this lead to (infrequent) infinite loops.
336
338{
339 static Bool_t warnedp = kFALSE;
340
341 if (!warnedp)
342 {
343 Warning("BisectBreakPoint", "call with eps_sqr argument is obsolete - please use the new signature.");
344 warnedp = kTRUE;
345 }
346
347 BisectBreakPoint(vL, vR, kFALSE);
348}
349
350////////////////////////////////////////////////////////////////////////////////
351/// Find break-point on both sides of the discontinuity.
352/// If project_result is true, the resulting break points will be projected
353/// with given depth value.
354
356 Bool_t project_result, Float_t depth)
357{
358 REveVector vM, vLP, vMP;
359 Int_t n_loops = TMath::CeilNint(TMath::Log2(1e12 * (vL-vR).Mag2() / (0.5f*(vL+vR)).Mag2()) / 2);
360 while (--n_loops >= 0)
361 {
362 vM.Mult(vL + vR, 0.5f);
363 vLP.Set(vL); ProjectPoint(vLP.fX, vLP.fY, vLP.fZ, 0);
364 vMP.Set(vM); ProjectPoint(vMP.fX, vMP.fY, vMP.fZ, 0);
365
366 if (IsOnSubSpaceBoundrary(vMP))
367 {
368 vL.Set(vM);
369 vR.Set(vM);
370 break;
371 }
372
373 if (AcceptSegment(vLP, vMP, 0.0f))
374 {
375 vL.Set(vM);
376 }
377 else
378 {
379 vR.Set(vM);
380 }
381 }
382
383 if (project_result)
384 {
385 ProjectVector(vL, depth);
386 ProjectVector(vR, depth);
387 }
388}
389
390////////////////////////////////////////////////////////////////////////////////
391/// Get vector for axis in a projected space.
392
394{
395 for (Int_t i=0; i<3; i++)
396 {
397 vec[i] = (i==screenAxis) ? 1.0f : 0.0f;
398 }
399}
400
401////////////////////////////////////////////////////////////////////////////////
402/// Get center ortogonal to given axis index.
403
405{
406 REveVector dirVec;
407 SetDirectionalVector(i, dirVec);
408
409 REveVector dirCenter;
410 dirCenter.Mult(dirVec, fCenter.Dot(dirVec));
411 centerOO = fCenter - dirCenter;
412
413
414 return centerOO;
415}
416
417////////////////////////////////////////////////////////////////////////////////
418/// Inverse projection.
419
421{
422 static const REveException eH("REveProjection::GetValForScreenPos ");
423
424 static const int kMaxSteps = 5000;
425 static const int kMaxVal = 10;
426
427 Float_t xL, xM, xR;
429
430 REveVector dirVec;
431 SetDirectionalVector(axisIdx, dirVec);
432
433 REveVector zero;
434 if (fDisplaceOrigin) zero = fCenter;
435
436 REveVector zeroProjected = zero;
437 ProjectVector(zeroProjected, 0.f);
438
439 // search from -/+ infinity according to sign of screen value
440 if (sv > zeroProjected[axisIdx])
441 {
442 xL = 0;
443 xR = kMaxVal;
444
445 int cnt = 0;
446 while (cnt < kMaxSteps)
447 {
448 vec.Mult(dirVec, xR);
450
451 ProjectVector(vec, 0);
452 if (vec[axisIdx] >= sv) break;
453 xL = xR; xR *= 2;
454
455 if (++cnt >= kMaxSteps)
456 throw eH + Form("positive projected %f, value %f,xL, xR ( %f, %f)\n", vec[axisIdx], sv, xL, xR);
457 }
458 }
459 else if (sv < zeroProjected[axisIdx])
460 {
461 xR = 0;
462 xL = -kMaxVal;
463
464 int cnt = 0;
465 while (cnt < kMaxSteps)
466 {
467 vec.Mult(dirVec, xL);
469
470 ProjectVector(vec, 0);
471 if (vec[axisIdx] <= sv) break;
472 xR = xL; xL *= 2;
473 if (++cnt >= kMaxSteps)
474 throw eH + Form("negative projected %f, value %f,xL, xR ( %f, %f)\n", vec[axisIdx], sv, xL, xR);
475 }
476 }
477 else
478 {
479 return 0.0f;
480 }
481
482 // printf("search for value %f in rng[%f, %f] \n", sv, xL, xR);
483 int cnt = 0;
484 do
485 {
486 //printf("search value with bisection xL=%f, xR=%f; vec[axisIdx]=%f, sv=%f\n", xL, xR, vec[axisIdx], sv);
487 xM = 0.5f * (xL + xR);
488 vec.Mult(dirVec, xM);
490 ProjectVector(vec, 0);
491 if (vec[axisIdx] > sv)
492 xR = xM;
493 else
494 xL = xM;
495 if (++cnt >= kMaxSteps)
496 throw eH + Form("can't converge %f %f, l/r %f/%f, idx=%d\n", vec[axisIdx], sv, xL, xR, axisIdx);
497
498 } while (TMath::Abs(vec[axisIdx] - sv) >= fgEps);
499
500
501 return xM;
502}
503
504////////////////////////////////////////////////////////////////////////////////
505/// Project point on given axis and return projected value.
506
508{
509 REveVector pos = dirVec*x;
510
511 if (fDisplaceOrigin)
512 pos += fCenter;
513
514 ProjectVector(pos , 0.f);
515
516 return pos[i];
517}
518
519////////////////////////////////////////////////////////////////////////////////
520/// Project point on given axis and return projected value.
521
523{
524 REveVector dirVec;
525 SetDirectionalVector(i, dirVec);
526 REveVector oCenter;
527 // GetOrthogonalCenter(i, oCenter);
528 return GetScreenVal(i, x, dirVec, oCenter);
529}
530
531/** \class REveRhoZProjection
532\ingroup REve
533Transformation from 3D to 2D. X axis represent Z coordinate. Y axis have value of
534radius with a sign of Y coordinate.
535*/
536
537////////////////////////////////////////////////////////////////////////////////
538/// Constructor.
539
542{
543 fType = kPT_RhoZ;
544 fName = "RhoZ";
545}
546
547////////////////////////////////////////////////////////////////////////////////
548/// Project point.
549
551 Float_t d, EPProc_e proc)
552{
553 using namespace TMath;
554
555 if (fDisplaceOrigin) {
556 x -= fCenter.fX;
557 y -= fCenter.fY;
558 z -= fCenter.fZ;
559 }
560 if (proc == kPP_Plane || proc == kPP_Full)
561 {
562 // project
563 y = Sign((Float_t)Sqrt(x*x+y*y), y);
564 x = z;
565 }
566 if (proc == kPP_Distort || proc == kPP_Full)
567 {
568 if (fUsePreScale)
569 PreScalePoint(y, x);
570
571
572 // distort
573
574 if (!fDisplaceOrigin) {
577 }
578
579 if (x > fFixZ)
580 x = fFixZ + fPastFixZScale*(x - fFixZ);
581 else if (x < -fFixZ)
582 x = -fFixZ + fPastFixZScale*(x + fFixZ);
583 else
584 x = x * fScaleZ / (1.0f + Abs(x)*fDistortion);
585
586 if (y > fFixR)
587 y = fFixR + fPastFixRScale*(y - fFixR);
588 else if (y < -fFixR)
589 y = -fFixR + fPastFixRScale*(y + fFixR);
590 else
591 y = y * fScaleR / (1.0f + Abs(y)*fDistortion);
592
593 if (!fDisplaceOrigin) {
596 }
597 }
598 z = d;
599}
600
601////////////////////////////////////////////////////////////////////////////////
602/// Set center of distortion (virtual method).
603
605{
606 fCenter = v;
607
608 if (fDisplaceOrigin)
609 {
610 fProjectedCenter.Set(0.f, 0.f, 0.f);
611 }
612 else
613 {
614 Float_t r = TMath::Sqrt(v.fX*v.fX + v.fY*v.fY);
618 }
619}
620
621////////////////////////////////////////////////////////////////////////////////
622/// Get direction in the unprojected space for axis index in the
623/// projected space.
624/// This is virtual method from base-class REveProjection.
625
627{
628 if (screenAxis == 0)
629 vec.Set(0.0f, 0.0f, 1.0f);
630 else if (screenAxis == 1)
631 vec.Set(0.0f, 1.0f, 0.0f);
632
633}
634
635////////////////////////////////////////////////////////////////////////////////
636/// Check if segment of two projected points is valid.
637///
638/// Move slightly one of the points if by shifting it by no more than
639/// tolerance the segment can become acceptable.
640
642 Float_t tolerance) const
643{
645 Bool_t val = kTRUE;
646 if ((v1.fY < a && v2.fY > a) || (v1.fY > a && v2.fY < a))
647 {
648 val = kFALSE;
649 if (tolerance > 0)
650 {
651 Float_t a1 = TMath::Abs(v1.fY - a), a2 = TMath::Abs(v2.fY - a);
652 if (a1 < a2)
653 {
654 if (a1 < tolerance) { v1.fY = a; val = kTRUE; }
655 }
656 else
657 {
658 if (a2 < tolerance) { v2.fY = a; val = kTRUE; }
659 }
660 }
661 }
662 return val;
663}
664
665////////////////////////////////////////////////////////////////////////////////
666/// Return sub-space id for the point.
667/// 0 - upper half-space
668/// 1 - lower half-space
669
671{
672 return v.fY > fProjectedCenter.fY ? 0 : 1;
673}
674
675////////////////////////////////////////////////////////////////////////////////
676/// Checks if point is on sub-space boundary.
677
679{
680 return v.fY == fProjectedCenter.fY;
681}
682
683/** \class REveRPhiProjection
684\ingroup REve
685XY projection with distortion around given center.
686*/
687
688////////////////////////////////////////////////////////////////////////////////
689/// Constructor.
690
693{
694 fType = kPT_RPhi;
696 fName = "RhoPhi";
697}
698
699////////////////////////////////////////////////////////////////////////////////
700/// Project point.
701
703 Float_t d, EPProc_e proc)
704{
705 using namespace TMath;
706
707 if (fDisplaceOrigin)
708 {
709 x -= fCenter.fX;
710 y -= fCenter.fY;
711 z -= fCenter.fZ;
712 }
713
714 if (proc != kPP_Plane)
715 {
716 Float_t r, phi;
717 if (fUsePreScale)
718 {
719 r = Sqrt(x*x + y*y);
720 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
721 PreScalePoint(r, phi);
722 x = r*Cos(phi);
723 y = r*Sin(phi);
724 }
725
726 if (!fDisplaceOrigin)
727 {
728 x -= fCenter.fX;
729 y -= fCenter.fY;
730 }
731
732 r = Sqrt(x*x + y*y);
733 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
734
735 if (r > fFixR)
736 r = fFixR + fPastFixRScale*(r - fFixR);
737 else if (r < -fFixR)
738 r = -fFixR + fPastFixRScale*(r + fFixR);
739 else
740 r = r * fScaleR / (1.0f + r*fDistortion);
741
742 x = r*Cos(phi);
743 y = r*Sin(phi);
744
745 if (!fDisplaceOrigin)
746 {
747 x += fCenter.fX;
748 y += fCenter.fY;
749 }
750 }
751 z = d;
752}
753
754/** \class REveXZProjection
755\ingroup REve
756XZ projection with distortion around given center.
757*/
758
759////////////////////////////////////////////////////////////////////////////////
760/// Constructor.
761
764{
765 fType = kPT_XZ;
767 fName = "XZ";
768}
769
770////////////////////////////////////////////////////////////////////////////////
771/// Project point.
772
774 Float_t d, EPProc_e proc)
775{
776 using namespace TMath;
777
778 if (fDisplaceOrigin)
779 {
780 x -= fCenter.fX;
781 y -= fCenter.fY;
782 z -= fCenter.fZ;
783 }
784
785 // projection
786 if (proc == kPP_Plane || proc == kPP_Full)
787 {
788 y = z;
789 z = d;
790 }
791 if (proc != kPP_Distort || proc == kPP_Full)
792 {
793 Float_t r, phi;
794 if (fUsePreScale)
795 {
796 r = Sqrt(x*x + y*y);
797 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
798 PreScalePoint(r, phi);
799 x = r*Cos(phi);
800 y = r*Sin(phi);
801 }
802
803 if (!fDisplaceOrigin)
804 {
807 }
808
809 r = Sqrt(x*x + y*y);
810 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
811
812 if (r > fFixR)
813 r = fFixR + fPastFixRScale*(r - fFixR);
814 else if (r < -fFixR)
815 r = -fFixR + fPastFixRScale*(r + fFixR);
816 else
817 r = r * fScaleR / (1.0f + r*fDistortion);
818
819 x = r*Cos(phi);
820 y = r*Sin(phi);
821
822 if (!fDisplaceOrigin)
823 {
826 }
827 }
828}
829
830////////////////////////////////////////////////////////////////////////////////
831/// Set center of distortion (virtual method).
832
834{
835 fCenter = v;
836
837 if (fDisplaceOrigin)
838 {
839 fProjectedCenter.Set(0.f, 0.f, 0.f);
840 }
841 else
842 {
846 }
847}
848
849////////////////////////////////////////////////////////////////////////////////
850/// Get direction in the unprojected space for axis index in the
851/// projected space.
852/// This is virtual method from base-class REveProjection.
853
855{
856 if (screenAxis == 0)
857 vec.Set(1.0f, 0.0f, 0.0f);
858 else if (screenAxis == 1)
859 vec.Set(0.0f, 0.0f, 1.0f);
860}
861
862
863/** \class REveYZProjection
864\ingroup REve
865YZ projection with distortion around given center.
866*/
867
868////////////////////////////////////////////////////////////////////////////////
869/// Constructor.
870
873{
874 fType = kPT_YZ;
876 fName = "YZ";
877}
878
879////////////////////////////////////////////////////////////////////////////////
880/// Project point.
881
883 Float_t d, EPProc_e proc)
884{
885 using namespace TMath;
886
887 if (fDisplaceOrigin)
888 {
889 x -= fCenter.fX;
890 y -= fCenter.fY;
891 z -= fCenter.fZ;
892 }
893
894 // projection
895 if (proc == kPP_Plane || proc == kPP_Full)
896 {
897 x = y;
898 y = z;
899 z = d;
900 }
901 if (proc != kPP_Distort || proc == kPP_Full)
902 {
903 Float_t r, phi;
904 if (fUsePreScale)
905 {
906 r = Sqrt(x*x + y*y);
907 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
908 PreScalePoint(r, phi);
909 x = r*Cos(phi);
910 y = r*Sin(phi);
911 }
912
913 if (!fDisplaceOrigin)
914 {
917 }
918
919 r = Sqrt(x*x + y*y);
920 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
921
922 if (r > fFixR)
923 r = fFixR + fPastFixRScale*(r - fFixR);
924 else if (r < -fFixR)
925 r = -fFixR + fPastFixRScale*(r + fFixR);
926 else
927 r = r * fScaleR / (1.0f + r*fDistortion);
928
929 x = r*Cos(phi);
930 y = r*Sin(phi);
931
932 if (!fDisplaceOrigin)
933 {
936 }
937 }
938}
939
940////////////////////////////////////////////////////////////////////////////////
941/// Set center of distortion (virtual method).
942
944{
945 fCenter = v;
946
947 if (fDisplaceOrigin)
948 {
949 fProjectedCenter.Set(0.f, 0.f, 0.f);
950 }
951 else
952 {
956 }
957}
958
959////////////////////////////////////////////////////////////////////////////////
960/// Get direction in the unprojected space for axis index in the
961/// projected space.
962/// This is virtual method from base-class REveProjection.
963
965{
966 if (screenAxis == 0)
967 vec.Set(0.0f, 1.0f, 0.0f);
968 else if (screenAxis == 1)
969 vec.Set(0.0f, 0.0f, 1.0f);
970}
971
972/** \class REveZXProjection
973\ingroup REve
974ZX projection with distortion around given center.
975*/
976
977////////////////////////////////////////////////////////////////////////////////
978/// Constructor.
979
982{
983 fType = kPT_ZX;
985 fName = "ZX";
986}
987
988////////////////////////////////////////////////////////////////////////////////
989/// Project point.
990
992 Float_t d, EPProc_e proc)
993{
994 using namespace TMath;
995
996 if (fDisplaceOrigin)
997 {
998 x -= fCenter.fX;
999 y -= fCenter.fY;
1000 z -= fCenter.fZ;
1001 }
1002
1003 // projection
1004 if (proc == kPP_Plane || proc == kPP_Full)
1005 {
1006 y = x;
1007 x = z;
1008 z = d;
1009 }
1010 if (proc != kPP_Distort || proc == kPP_Full)
1011 {
1012 Float_t r, phi;
1013 if (fUsePreScale)
1014 {
1015 r = Sqrt(x*x + y*y);
1016 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1017 PreScalePoint(r, phi);
1018 x = r*Cos(phi);
1019 y = r*Sin(phi);
1020 }
1021
1022 if (!fDisplaceOrigin)
1023 {
1026 }
1027
1028 r = Sqrt(x*x + y*y);
1029 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1030
1031 if (r > fFixR)
1032 r = fFixR + fPastFixRScale*(r - fFixR);
1033 else if (r < -fFixR)
1034 r = -fFixR + fPastFixRScale*(r + fFixR);
1035 else
1036 r = r * fScaleR / (1.0f + r*fDistortion);
1037
1038 x = r*Cos(phi);
1039 y = r*Sin(phi);
1040
1041 if (!fDisplaceOrigin)
1042 {
1045 }
1046 }
1047}
1048
1049////////////////////////////////////////////////////////////////////////////////
1050/// Set center of distortion (virtual method).
1051
1053{
1054 fCenter = v;
1055
1056 if (fDisplaceOrigin)
1057 {
1058 fProjectedCenter.Set(0.f, 0.f, 0.f);
1059 }
1060 else
1061 {
1064 fProjectedCenter.fZ = 0;
1065 }
1066}
1067
1068////////////////////////////////////////////////////////////////////////////////
1069/// Get direction in the unprojected space for axis index in the
1070/// projected space.
1071/// This is virtual method from base-class REveProjection.
1072
1074{
1075 if (screenAxis == 0)
1076 vec.Set(0.0f, 0.0f, 1.0f);
1077 else if (screenAxis == 1)
1078 vec.Set(1.0f, 0.0f, 0.0f);
1079}
1080
1081
1082/** \class REveZYProjection
1083\ingroup REve
1084ZY projection with distortion around given center.
1085*/
1086
1087////////////////////////////////////////////////////////////////////////////////
1088/// Constructor.
1089
1092{
1093 fType = kPT_ZY;
1095 fName = "ZY";
1096}
1097
1098////////////////////////////////////////////////////////////////////////////////
1099/// Project point.
1100
1102 Float_t d, EPProc_e proc)
1103{
1104 using namespace TMath;
1105
1106 if (fDisplaceOrigin)
1107 {
1108 x -= fCenter.fX;
1109 y -= fCenter.fY;
1110 z -= fCenter.fZ;
1111 }
1112
1113 // projection
1114 if (proc == kPP_Plane || proc == kPP_Full)
1115 {
1116 x = z;
1117 z = d;
1118 }
1119 if (proc != kPP_Distort || proc == kPP_Full)
1120 {
1121 Float_t r, phi;
1122 if (fUsePreScale)
1123 {
1124 r = Sqrt(x*x + y*y);
1125 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1126 PreScalePoint(r, phi);
1127 x = r*Cos(phi);
1128 y = r*Sin(phi);
1129 }
1130
1131 if (!fDisplaceOrigin)
1132 {
1135 }
1136
1137 r = Sqrt(x*x + y*y);
1138 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1139
1140 if (r > fFixR)
1141 r = fFixR + fPastFixRScale*(r - fFixR);
1142 else if (r < -fFixR)
1143 r = -fFixR + fPastFixRScale*(r + fFixR);
1144 else
1145 r = r * fScaleR / (1.0f + r*fDistortion);
1146
1147 x = r*Cos(phi);
1148 y = r*Sin(phi);
1149
1150 if (!fDisplaceOrigin)
1151 {
1154 }
1155 }
1156}
1157
1158////////////////////////////////////////////////////////////////////////////////
1159/// Set center of distortion (virtual method).
1160
1162{
1163 fCenter = v;
1164
1165 if (fDisplaceOrigin)
1166 {
1167 fProjectedCenter.Set(0.f, 0.f, 0.f);
1168 }
1169 else
1170 {
1173 fProjectedCenter.fZ = 0;
1174 }
1175}
1176
1177////////////////////////////////////////////////////////////////////////////////
1178/// Get direction in the unprojected space for axis index in the
1179/// projected space.
1180/// This is virtual method from base-class REveProjection.
1181
1183{
1184 if (screenAxis == 0)
1185 vec.Set(0.0f, 0.0f, 1.0f);
1186 else if (screenAxis == 1)
1187 vec.Set(0.0f, 1.0f, 0.0f);
1188}
1189
1190/** \class REve3DProjection
1191\ingroup REve
11923D scaling projection. One has to use pre-scaling to make any ise of this.
1193*/
1194
1195////////////////////////////////////////////////////////////////////////////////
1196/// Constructor.
1197
1200{
1201 fType = kPT_3D;
1203 fName = "3D";
1204}
1205
1206////////////////////////////////////////////////////////////////////////////////
1207/// Project point.
1208
1210 Float_t /*d*/, EPProc_e proc)
1211{
1212 using namespace TMath;
1213
1214 if (proc != kPP_Plane)
1215 {
1216 if (fUsePreScale)
1217 {
1218 PreScalePoint(x, y, z);
1219 }
1220
1221 x -= fCenter.fX;
1222 y -= fCenter.fY;
1223 z -= fCenter.fZ;
1224 }
1225}
ROOT::R::TRInterface & r
Definition: Object.C:4
#define d(i)
Definition: RSha256.hxx:102
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
double Double_t
Definition: RtypesCore.h:59
float Float_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:100
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition: TError.cxx:231
char * Form(const char *fmt,...)
void ProjectPoint(Float_t &x, Float_t &y, Float_t &z, Float_t d, EPProc_e proc=kPP_Full) override
Project point.
REveException Exception-type thrown by Eve classes.
Definition: REveTypes.hxx:41
REveProjection Base for specific classes that implement non-linear projections.
virtual Float_t GetValForScreenPos(Int_t ax, Float_t value)
Inverse projection.
virtual Float_t GetScreenVal(Int_t ax, Float_t value)
Project point on given axis and return projected value.
std::vector< PreScaleEntry_t > vPreScale_t
REveVector GetOrthogonalCenter(int idx, REveVector &out)
Get center ortogonal to given axis index.
void ProjectPointfv(Float_t *v, Float_t d)
Project float array.
void ProjectPointdv(Double_t *v, Float_t d)
Project double array.
void ProjectVector(REveVector &v, Float_t d)
Project REveVector.
void PreScaleVariable(Int_t dim, Float_t &v)
Pre-scale single variable with pre-scale entry dim.
virtual void ProjectPoint(Float_t &x, Float_t &y, Float_t &z, Float_t d, EPProc_e p=kPP_Full)=0
virtual void SetCenter(REveVector &v)
void SetDistortion(Float_t d)
Set distortion.
virtual void SetDirectionalVector(Int_t screenAxis, REveVector &vec)
Get vector for axis in a projected space.
void ChangePreScaleEntry(Int_t coord, Int_t entry, Float_t new_scale)
Change scale for given entry and coordinate.
void PreScalePoint(Float_t &x, Float_t &y)
Pre-scale point (x, y) in projected coordinates for 2D projections:
void SetPastFixRFac(Float_t x)
Set 2's-exponent for relative scaling beyond FixR.
void AddPreScaleEntry(Int_t coord, Float_t max_val, Float_t scale)
Add new scaling range for given coordinate.
void SetFixZ(Float_t x)
Set fixed radius.
virtual Bool_t AcceptSegment(REveVector &, REveVector &, Float_t) const
void SetDisplaceOrigin(bool)
Set flag to displace for center.
virtual void BisectBreakPoint(REveVector &vL, REveVector &vR, Float_t eps_sqr)
Find break-point on both sides of the discontinuity.
virtual Float_t * GetProjectedCenter()
Get projected center.
virtual Bool_t IsOnSubSpaceBoundrary(const REveVector &) const
void SetPastFixZFac(Float_t x)
Set 2's-exponent for relative scaling beyond FixZ.
void SetFixR(Float_t x)
Set fixed radius.
void ClearPreScales()
Clear all pre-scaling information.
void ProjectPoint(Float_t &x, Float_t &y, Float_t &z, Float_t d, EPProc_e proc=kPP_Full) override
Project point.
Bool_t IsOnSubSpaceBoundrary(const REveVector &v) const override
Checks if point is on sub-space boundary.
void SetDirectionalVector(Int_t screenAxis, REveVector &vec) override
Get direction in the unprojected space for axis index in the projected space.
void ProjectPoint(Float_t &x, Float_t &y, Float_t &z, Float_t d, EPProc_e proc=kPP_Full) override
Project point.
Int_t SubSpaceId(const REveVector &v) const override
Return sub-space id for the point.
Bool_t AcceptSegment(REveVector &v1, REveVector &v2, Float_t tolerance) const override
Check if segment of two projected points is valid.
void SetCenter(REveVector &v) override
Set center of distortion (virtual method).
void MultiplyIP(TVector3 &v, Double_t w=1) const
Multiply vector in-place.
Definition: REveTrans.cxx:727
TVector3 Multiply(const TVector3 &v, Double_t w=1) const
Multiply vector and return it.
Definition: REveTrans.cxx:759
REveVectorT & Mult(const REveVectorT &a, TT af)
Definition: REveVector.hxx:192
void Set(const Float_t *v)
Definition: REveVector.hxx:80
TT Dot(const REveVectorT &a) const
Definition: REveVector.hxx:164
void ProjectPoint(Float_t &x, Float_t &y, Float_t &z, Float_t d, EPProc_e proc=kPP_Full) override
Project point.
void SetCenter(REveVector &v) override
Set center of distortion (virtual method).
void SetDirectionalVector(Int_t screenAxis, REveVector &vec) override
Get direction in the unprojected space for axis index in the projected space.
void SetDirectionalVector(Int_t screenAxis, REveVector &vec) override
Get direction in the unprojected space for axis index in the projected space.
void ProjectPoint(Float_t &x, Float_t &y, Float_t &z, Float_t d, EPProc_e proc=kPP_Full) override
Project point.
void SetCenter(REveVector &v) override
Set center of distortion (virtual method).
void ProjectPoint(Float_t &x, Float_t &y, Float_t &z, Float_t d, EPProc_e proc=kPP_Full) override
Project point.
void SetCenter(REveVector &v) override
Set center of distortion (virtual method).
void SetDirectionalVector(Int_t screenAxis, REveVector &vec) override
Get direction in the unprojected space for axis index in the projected space.
void SetCenter(REveVector &v) override
Set center of distortion (virtual method).
void ProjectPoint(Float_t &x, Float_t &y, Float_t &z, Float_t d, EPProc_e proc=kPP_Full) override
Project point.
void SetDirectionalVector(Int_t screenAxis, REveVector &vec) override
Get direction in the unprojected space for axis index in the projected space.
T Mag2(const SVector< T, D > &rhs)
Vector magnitude square Template to compute .
Definition: Functions.h:230
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
Double_t Sqrt(Double_t x)
TMath.
Definition: TMathBase.h:35
Double_t Log2(Double_t x)
Definition: TMath.cxx:101
T1 Sign(T1 a, T2 b)
Definition: TMathBase.h:161
Double_t ATan2(Double_t y, Double_t x)
Definition: TMath.h:679
Double_t Sqrt(Double_t x)
Definition: TMath.h:691
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:735
Int_t CeilNint(Double_t x)
Definition: TMath.h:699
Double_t Cos(Double_t)
Definition: TMath.h:643
Double_t Sin(Double_t)
Definition: TMath.h:639
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
const char * cnt
Definition: TXMLSetup.cxx:75
Definition: civetweb.c:2228
auto * a
Definition: textangle.C:12