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
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;
429 REveVector vec;
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);
450 if (fDisplaceOrigin) vec += fCenter;
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);
469 if (fDisplaceOrigin) vec += fCenter;
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);
490 if (fDisplaceOrigin) vec += fCenter;
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 fPlaneNormal.Set(0,1,0);
547}
548
549////////////////////////////////////////////////////////////////////////////////
550/// Project point.
551
553 Float_t d, EPProc_e proc)
554{
555 using namespace TMath;
556
557 if (fDisplaceOrigin) {
558 x -= fCenter.fX;
559 y -= fCenter.fY;
560 z -= fCenter.fZ;
561 }
562 if (proc == kPP_Plane || proc == kPP_Full)
563 {
564 // project
565 const Float_t side = fPlaneNormal.fX * x +
566 fPlaneNormal.fY * y +
567 fPlaneNormal.fZ * z;
568
569 y = TMath::Sign((Float_t)TMath::Sqrt(x * x + y * y), side);
570 x = z;
571 }
572 if (proc == kPP_Distort || proc == kPP_Full)
573 {
574 if (fUsePreScale)
575 PreScalePoint(y, x);
576
577
578 // distort
579
580 if (!fDisplaceOrigin) {
583 }
584
585 if (x > fFixZ)
586 x = fFixZ + fPastFixZScale*(x - fFixZ);
587 else if (x < -fFixZ)
588 x = -fFixZ + fPastFixZScale*(x + fFixZ);
589 else
590 x = x * fScaleZ / (1.0f + Abs(x)*fDistortion);
591
592 if (y > fFixR)
593 y = fFixR + fPastFixRScale*(y - fFixR);
594 else if (y < -fFixR)
595 y = -fFixR + fPastFixRScale*(y + fFixR);
596 else
597 y = y * fScaleR / (1.0f + Abs(y)*fDistortion);
598
599 if (!fDisplaceOrigin) {
602 }
603 }
604 z = d;
605}
606
607////////////////////////////////////////////////////////////////////////////////
608/// Set center of distortion (virtual method).
609
611{
612 fCenter = v;
613
614 if (fDisplaceOrigin)
615 {
616 fProjectedCenter.Set(0.f, 0.f, 0.f);
617 }
618 else
619 {
620 Float_t r = TMath::Sqrt(v.fX*v.fX + v.fY*v.fY);
624 }
625}
626
627////////////////////////////////////////////////////////////////////////////////
628/// Get direction in the unprojected space for axis index in the
629/// projected space.
630/// This is virtual method from base-class REveProjection.
631
633{
634 if (screenAxis == 0)
635 vec.Set(0.0f, 0.0f, 1.0f);
636 else if (screenAxis == 1)
637 vec.Set(0.0f, 1.0f, 0.0f);
638
639}
640
641////////////////////////////////////////////////////////////////////////////////
642/// Check if segment of two projected points is valid.
643///
644/// Move slightly one of the points if by shifting it by no more than
645/// tolerance the segment can become acceptable.
646
648 Float_t tolerance) const
649{
650 if (fYAxis == false)
651 AcceptSegmentRotatedPlane(v1, v2, tolerance);
652
654 Bool_t val = kTRUE;
655 if ((v1.fY < a && v2.fY > a) || (v1.fY > a && v2.fY < a))
656 {
657 val = kFALSE;
658 if (tolerance > 0)
659 {
660 Float_t a1 = TMath::Abs(v1.fY - a), a2 = TMath::Abs(v2.fY - a);
661 if (a1 < a2)
662 {
663 if (a1 < tolerance) { v1.fY = a; val = kTRUE; }
664 }
665 else
666 {
667 if (a2 < tolerance) { v2.fY = a; val = kTRUE; }
668 }
669 }
670 }
671 return val;
672}
673
674////////////////////////////////////////////////////////////////////////////////
675/// Check if segment of two projected points is valid on a rotated plane
676///
677/// Move slightly one of the points if by shifting it by no more than
678/// tolerance the segment can become acceptable.
679
681 Float_t tolerance) const
682{
685
686 Bool_t val = kTRUE;
687
688 if ((d1 < 0 && d2 > 0) || (d1 > 0 && d2 < 0))
689 {
690 val = kFALSE;
691
692 if (tolerance > 0)
693 {
694 const Float_t a1 = TMath::Abs(d1);
695 const Float_t a2 = TMath::Abs(d2);
696
697 if (a1 < a2)
698 {
699 if (a1 < tolerance)
700 {
701 // Move v1 to the plane intersection.
702 const Float_t t = d1 / (d1 - d2);
703 v1 += t * (v2 - v1);
704
705 val = kTRUE;
706 }
707 }
708 else
709 {
710 if (a2 < tolerance)
711 {
712 // Move v2 to the plane intersection.
713 const Float_t t = d1 / (d1 - d2);
714 v2 = v1 + t * (v2 - v1);
715
716 val = kTRUE;
717 }
718 }
719 }
720 }
721
722 return val;
723}
724
725////////////////////////////////////////////////////////////////////////////////
726/// Set normal of the projection plane
727/// Projection center must be on the plane
728/// The default plane normal value is Y axis (0, 1, 0)
729
731{
732 REveVector yAxis(0, 1, 0);
733 if (v != yAxis) {
734 fYAxis = false;
735 }
737}
738
739////////////////////////////////////////////////////////////////////////////////
740/// Return sub-space id for the point.
741/// 0 - upper half-space
742/// 1 - lower half-space
743
745{
746 return v.fY > fProjectedCenter.fY ? 0 : 1;
747}
748
749////////////////////////////////////////////////////////////////////////////////
750/// Checks if point is on sub-space boundary.
751
756
757/** \class REveRPhiProjection
758\ingroup REve
759XY projection with distortion around given center.
760*/
761
762////////////////////////////////////////////////////////////////////////////////
763/// Constructor.
764
772
773////////////////////////////////////////////////////////////////////////////////
774/// Project point.
775
777 Float_t d, EPProc_e proc)
778{
779 using namespace TMath;
780
781 if (fDisplaceOrigin)
782 {
783 x -= fCenter.fX;
784 y -= fCenter.fY;
785 z -= fCenter.fZ;
786 }
787
788 if (proc != kPP_Plane)
789 {
790 Float_t r, phi;
791 if (fUsePreScale)
792 {
793 r = Sqrt(x*x + y*y);
794 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
795 PreScalePoint(r, phi);
796 x = r*Cos(phi);
797 y = r*Sin(phi);
798 }
799
800 if (!fDisplaceOrigin)
801 {
802 x -= fCenter.fX;
803 y -= fCenter.fY;
804 }
805
806 r = Sqrt(x*x + y*y);
807 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
808
809 if (r > fFixR)
810 r = fFixR + fPastFixRScale*(r - fFixR);
811 else if (r < -fFixR)
812 r = -fFixR + fPastFixRScale*(r + fFixR);
813 else
814 r = r * fScaleR / (1.0f + r*fDistortion);
815
816 x = r*Cos(phi);
817 y = r*Sin(phi);
818
819 if (!fDisplaceOrigin)
820 {
821 x += fCenter.fX;
822 y += fCenter.fY;
823 }
824 }
825 z = d;
826}
827
828/** \class REveXZProjection
829\ingroup REve
830XZ projection with distortion around given center.
831*/
832
833////////////////////////////////////////////////////////////////////////////////
834/// Constructor.
835
843
844////////////////////////////////////////////////////////////////////////////////
845/// Project point.
846
848 Float_t d, EPProc_e proc)
849{
850 using namespace TMath;
851
852 if (fDisplaceOrigin)
853 {
854 x -= fCenter.fX;
855 y -= fCenter.fY;
856 z -= fCenter.fZ;
857 }
858
859 // projection
860 if (proc == kPP_Plane || proc == kPP_Full)
861 {
862 y = z;
863 z = d;
864 }
865 if (proc != kPP_Distort || proc == kPP_Full)
866 {
867 Float_t r, phi;
868 if (fUsePreScale)
869 {
870 r = Sqrt(x*x + y*y);
871 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
872 PreScalePoint(r, phi);
873 x = r*Cos(phi);
874 y = r*Sin(phi);
875 }
876
877 if (!fDisplaceOrigin)
878 {
881 }
882
883 r = Sqrt(x*x + y*y);
884 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
885
886 if (r > fFixR)
887 r = fFixR + fPastFixRScale*(r - fFixR);
888 else if (r < -fFixR)
889 r = -fFixR + fPastFixRScale*(r + fFixR);
890 else
891 r = r * fScaleR / (1.0f + r*fDistortion);
892
893 x = r*Cos(phi);
894 y = r*Sin(phi);
895
896 if (!fDisplaceOrigin)
897 {
900 }
901 }
902}
903
904////////////////////////////////////////////////////////////////////////////////
905/// Set center of distortion (virtual method).
906
908{
909 fCenter = v;
910
911 if (fDisplaceOrigin)
912 {
913 fProjectedCenter.Set(0.f, 0.f, 0.f);
914 }
915 else
916 {
920 }
921}
922
923////////////////////////////////////////////////////////////////////////////////
924/// Get direction in the unprojected space for axis index in the
925/// projected space.
926/// This is virtual method from base-class REveProjection.
927
929{
930 if (screenAxis == 0)
931 vec.Set(1.0f, 0.0f, 0.0f);
932 else if (screenAxis == 1)
933 vec.Set(0.0f, 0.0f, 1.0f);
934}
935
936
937/** \class REveYZProjection
938\ingroup REve
939YZ projection with distortion around given center.
940*/
941
942////////////////////////////////////////////////////////////////////////////////
943/// Constructor.
944
952
953////////////////////////////////////////////////////////////////////////////////
954/// Project point.
955
957 Float_t d, EPProc_e proc)
958{
959 using namespace TMath;
960
961 if (fDisplaceOrigin)
962 {
963 x -= fCenter.fX;
964 y -= fCenter.fY;
965 z -= fCenter.fZ;
966 }
967
968 // projection
969 if (proc == kPP_Plane || proc == kPP_Full)
970 {
971 x = y;
972 y = z;
973 z = d;
974 }
975 if (proc != kPP_Distort || proc == kPP_Full)
976 {
977 Float_t r, phi;
978 if (fUsePreScale)
979 {
980 r = Sqrt(x*x + y*y);
981 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
982 PreScalePoint(r, phi);
983 x = r*Cos(phi);
984 y = r*Sin(phi);
985 }
986
987 if (!fDisplaceOrigin)
988 {
991 }
992
993 r = Sqrt(x*x + y*y);
994 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
995
996 if (r > fFixR)
997 r = fFixR + fPastFixRScale*(r - fFixR);
998 else if (r < -fFixR)
999 r = -fFixR + fPastFixRScale*(r + fFixR);
1000 else
1001 r = r * fScaleR / (1.0f + r*fDistortion);
1002
1003 x = r*Cos(phi);
1004 y = r*Sin(phi);
1005
1006 if (!fDisplaceOrigin)
1007 {
1010 }
1011 }
1012}
1013
1014////////////////////////////////////////////////////////////////////////////////
1015/// Set center of distortion (virtual method).
1016
1018{
1019 fCenter = v;
1020
1021 if (fDisplaceOrigin)
1022 {
1023 fProjectedCenter.Set(0.f, 0.f, 0.f);
1024 }
1025 else
1026 {
1029 fProjectedCenter.fZ = 0;
1030 }
1031}
1032
1033////////////////////////////////////////////////////////////////////////////////
1034/// Get direction in the unprojected space for axis index in the
1035/// projected space.
1036/// This is virtual method from base-class REveProjection.
1037
1039{
1040 if (screenAxis == 0)
1041 vec.Set(0.0f, 1.0f, 0.0f);
1042 else if (screenAxis == 1)
1043 vec.Set(0.0f, 0.0f, 1.0f);
1044}
1045
1046/** \class REveZXProjection
1047\ingroup REve
1048ZX projection with distortion around given center.
1049*/
1050
1051////////////////////////////////////////////////////////////////////////////////
1052/// Constructor.
1053
1061
1062////////////////////////////////////////////////////////////////////////////////
1063/// Project point.
1064
1066 Float_t d, EPProc_e proc)
1067{
1068 using namespace TMath;
1069
1070 if (fDisplaceOrigin)
1071 {
1072 x -= fCenter.fX;
1073 y -= fCenter.fY;
1074 z -= fCenter.fZ;
1075 }
1076
1077 // projection
1078 if (proc == kPP_Plane || proc == kPP_Full)
1079 {
1080 y = x;
1081 x = z;
1082 z = d;
1083 }
1084 if (proc != kPP_Distort || proc == kPP_Full)
1085 {
1086 Float_t r, phi;
1087 if (fUsePreScale)
1088 {
1089 r = Sqrt(x*x + y*y);
1090 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1091 PreScalePoint(r, phi);
1092 x = r*Cos(phi);
1093 y = r*Sin(phi);
1094 }
1095
1096 if (!fDisplaceOrigin)
1097 {
1100 }
1101
1102 r = Sqrt(x*x + y*y);
1103 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1104
1105 if (r > fFixR)
1106 r = fFixR + fPastFixRScale*(r - fFixR);
1107 else if (r < -fFixR)
1108 r = -fFixR + fPastFixRScale*(r + fFixR);
1109 else
1110 r = r * fScaleR / (1.0f + r*fDistortion);
1111
1112 x = r*Cos(phi);
1113 y = r*Sin(phi);
1114
1115 if (!fDisplaceOrigin)
1116 {
1119 }
1120 }
1121}
1122
1123////////////////////////////////////////////////////////////////////////////////
1124/// Set center of distortion (virtual method).
1125
1127{
1128 fCenter = v;
1129
1130 if (fDisplaceOrigin)
1131 {
1132 fProjectedCenter.Set(0.f, 0.f, 0.f);
1133 }
1134 else
1135 {
1138 fProjectedCenter.fZ = 0;
1139 }
1140}
1141
1142////////////////////////////////////////////////////////////////////////////////
1143/// Get direction in the unprojected space for axis index in the
1144/// projected space.
1145/// This is virtual method from base-class REveProjection.
1146
1148{
1149 if (screenAxis == 0)
1150 vec.Set(0.0f, 0.0f, 1.0f);
1151 else if (screenAxis == 1)
1152 vec.Set(1.0f, 0.0f, 0.0f);
1153}
1154
1155
1156/** \class REveZYProjection
1157\ingroup REve
1158ZY projection with distortion around given center.
1159*/
1160
1161////////////////////////////////////////////////////////////////////////////////
1162/// Constructor.
1163
1171
1172////////////////////////////////////////////////////////////////////////////////
1173/// Project point.
1174
1176 Float_t d, EPProc_e proc)
1177{
1178 using namespace TMath;
1179
1180 if (fDisplaceOrigin)
1181 {
1182 x -= fCenter.fX;
1183 y -= fCenter.fY;
1184 z -= fCenter.fZ;
1185 }
1186
1187 // projection
1188 if (proc == kPP_Plane || proc == kPP_Full)
1189 {
1190 x = z;
1191 z = d;
1192 }
1193 if (proc != kPP_Distort || proc == kPP_Full)
1194 {
1195 Float_t r, phi;
1196 if (fUsePreScale)
1197 {
1198 r = Sqrt(x*x + y*y);
1199 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1200 PreScalePoint(r, phi);
1201 x = r*Cos(phi);
1202 y = r*Sin(phi);
1203 }
1204
1205 if (!fDisplaceOrigin)
1206 {
1209 }
1210
1211 r = Sqrt(x*x + y*y);
1212 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1213
1214 if (r > fFixR)
1215 r = fFixR + fPastFixRScale*(r - fFixR);
1216 else if (r < -fFixR)
1217 r = -fFixR + fPastFixRScale*(r + fFixR);
1218 else
1219 r = r * fScaleR / (1.0f + r*fDistortion);
1220
1221 x = r*Cos(phi);
1222 y = r*Sin(phi);
1223
1224 if (!fDisplaceOrigin)
1225 {
1228 }
1229 }
1230}
1231
1232////////////////////////////////////////////////////////////////////////////////
1233/// Set center of distortion (virtual method).
1234
1236{
1237 fCenter = v;
1238
1239 if (fDisplaceOrigin)
1240 {
1241 fProjectedCenter.Set(0.f, 0.f, 0.f);
1242 }
1243 else
1244 {
1247 fProjectedCenter.fZ = 0;
1248 }
1249}
1250
1251////////////////////////////////////////////////////////////////////////////////
1252/// Get direction in the unprojected space for axis index in the
1253/// projected space.
1254/// This is virtual method from base-class REveProjection.
1255
1257{
1258 if (screenAxis == 0)
1259 vec.Set(0.0f, 0.0f, 1.0f);
1260 else if (screenAxis == 1)
1261 vec.Set(0.0f, 1.0f, 0.0f);
1262}
1263
1264/** \class REve3DProjection
1265\ingroup REve
12663D scaling projection. One has to use pre-scaling to make any ise of this.
1267*/
1268
1269////////////////////////////////////////////////////////////////////////////////
1270/// Constructor.
1271
1274{
1275 fType = kPT_3D;
1277 fName = "3D";
1278}
1279
1280////////////////////////////////////////////////////////////////////////////////
1281/// Project point.
1282
1284 Float_t /*d*/, EPProc_e proc)
1285{
1286 using namespace TMath;
1287
1288 if (proc != kPP_Plane)
1289 {
1290 if (fUsePreScale)
1291 {
1292 PreScalePoint(x, y, z);
1293 }
1294
1295 x -= fCenter.fX;
1296 y -= fCenter.fY;
1297 z -= fCenter.fZ;
1298 }
1299}
#define d(i)
Definition RSha256.hxx:102
#define a(i)
Definition RSha256.hxx:99
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
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:2571
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
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 SetPlaneNormal(REveVector &v)
Set normal of the projection plane Projection center must be on the plane The default plane normal va...
void SetCenter(REveVector &v) override
Set center of distortion (virtual method).
Bool_t AcceptSegmentRotatedPlane(REveVector &v1, REveVector &v2, Float_t tolerance) const
Check if segment of two projected points is valid on a rotated plane.
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
Namespace for ROOT features in testing.
Definition TROOT.h:100
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 Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:675
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:734
Int_t CeilNint(Double_t x)
Returns the nearest integer of TMath::Ceil(x).
Definition TMath.h:687
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122