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
31Float_t REveProjection::fgEps = 0.005f;
32Float_t REveProjection::fgEpsSqr = 0.000025f;
33
34////////////////////////////////////////////////////////////////////////////////
35/// Constructor.
36
37REveProjection::REveProjection() :
38 fType (kPT_Unknown),
39 fGeoMode (kGM_Unknown),
40 fName (),
41 fCenter (),
42 fDisplaceOrigin (kFALSE),
43 fUsePreScale (kFALSE),
44 fDistortion (0.0f),
45 fFixR (300), fFixZ (400),
46 fPastFixRFac (0), fPastFixZFac (0),
47 fScaleR (1), fScaleZ (1),
48 fPastFixRScale (1), fPastFixZScale (1),
49 fMaxTrackStep (25) // XXXXX This is STOOPID ... see also comment in REveTrackProjected::MakeTrack()
50{
51}
52
53////////////////////////////////////////////////////////////////////////////////
54/// Project float array.
55
57{
58 ProjectPoint(v[0], v[1], v[2], d);
59}
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
76{
77 ProjectPoint(v.fX, v.fY, v.fZ, d);
78}
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
155{
158}
159
160////////////////////////////////////////////////////////////////////////////////
161/// Pre-scale point (x, y, z) in projected coordinates for 3D projection.
162
164{
167 PreScaleVariable(2, z);
168}
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
260{
261 fDistortion = d;
262 fScaleR = 1.0f + fFixR*fDistortion;
263 fScaleZ = 1.0f + fFixZ*fDistortion;
266}
267
268////////////////////////////////////////////////////////////////////////////////
269/// Set fixed radius.
270
272{
273 fFixR = r;
276}
277
278////////////////////////////////////////////////////////////////////////////////
279/// Set fixed radius.
280
282{
283 fFixZ = z;
286}
287
288////////////////////////////////////////////////////////////////////////////////
289/// Set 2's-exponent for relative scaling beyond FixR.
290
292{
293 fPastFixRFac = x;
295}
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
327{
328 fPastFixZFac = x;
330}
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
543{
544 fType = kPT_RhoZ;
545 fName = "RhoZ";
546}
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) {
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) {
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);
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
680{
681 return v.fY == fProjectedCenter.fY;
682}
683
684/** \class REveRPhiProjection
685\ingroup REve
686XY projection with distortion around given center.
687*/
688
689////////////////////////////////////////////////////////////////////////////////
690/// Constructor.
691
694{
695 fType = kPT_RPhi;
697 fName = "RhoPhi";
698}
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
765{
766 fType = kPT_XZ;
768 fName = "XZ";
769}
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 {
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 {
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 {
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
874{
875 fType = kPT_YZ;
877 fName = "YZ";
878}
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 {
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 {
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 {
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
983{
984 fType = kPT_ZX;
986 fName = "ZX";
987}
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 {
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 {
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 {
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
1093{
1094 fType = kPT_ZY;
1096 fName = "ZY";
1097}
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 {
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 {
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 {
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}
#define d(i)
Definition RSha256.hxx:102
#define a(i)
Definition RSha256.hxx:99
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
winID h TVirtualViewer3D TVirtualGLPainter p
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 TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
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 r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
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:43
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.
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)
TT Dot(const REveVectorT &a) const
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
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:175
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:662
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:721
Int_t CeilNint(Double_t x)
Returns the nearest integer of TMath::Ceil(x).
Definition TMath.h:674
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123