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