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. `p` and `v` may be the same array.
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 Double_t buf[3];
105 t->Multiply(p, buf);
106 x = buf[0];
107 y = buf[1];
108 z = buf[2];
109 }
110 else
111 {
112 x = p[0]; y = p[1]; z = p[2];
113 }
114 ProjectPoint(x, y, z, d);
115 v[0] = x; v[1] = y; v[2] = z;
116}
117
118////////////////////////////////////////////////////////////////////////////////
119/// Project REveVector, converting it to global coordinate system first if
120/// transformation matrix is set.
121
123{
124 if (t)
125 {
126 t->MultiplyIP(v);
127 }
128 ProjectPoint(v.fX, v.fY, v.fZ, d);
129}
130
131////////////////////////////////////////////////////////////////////////////////
132/// Pre-scale single variable with pre-scale entry dim.
133
135{
136 if (!fPreScales[dim].empty())
137 {
138 Bool_t invp = kFALSE;
139 if (v < 0) {
140 v = -v;
141 invp = kTRUE;
142 }
143 auto i = fPreScales[dim].begin();
144 while (v > i->fMax)
145 ++i;
146 v = i->fOffset + (v - i->fMin)*i->fScale;
147 if (invp)
148 v = -v;
149 }
150}
151
152////////////////////////////////////////////////////////////////////////////////
153/// Pre-scale point (x, y) in projected coordinates for 2D projections:
154/// - RhoZ ~ (rho, z)
155/// - RPhi ~ (r, phi), scaling phi doesn't make much sense.
156
162
163////////////////////////////////////////////////////////////////////////////////
164/// Pre-scale point (x, y, z) in projected coordinates for 3D projection.
165
172
173////////////////////////////////////////////////////////////////////////////////
174/// Add new scaling range for given coordinate.
175/// Arguments:
176/// - coord 0 ~ x, 1 ~ y, 2 ~ z
177/// - value value of input coordinate from which to apply this scale;
178/// - scale the scale to apply from value onwards.
179///
180/// NOTE: If pre-scaling is combined with center-displaced then
181/// the scale of the central region should be 1. This limitation
182/// can be removed but will cost CPU.
183
185{
186 static const REveException eh("REveProjection::AddPreScaleEntry ");
187
188 if (coord < 0 || coord > 2)
189 throw (eh + "coordinate out of range.");
190
191 const Float_t infty = std::numeric_limits<Float_t>::infinity();
192
193 vPreScale_t& vec = fPreScales[coord];
194
195 if (vec.empty())
196 {
197 if (value == 0)
198 {
199 vec.emplace_back(0, infty, 0, scale);
200 }
201 else
202 {
203 vec.emplace_back(0, value, 0, 1);
204 vec.emplace_back(value, infty, value, scale);
205 }
206 }
207 else
208 {
209 PreScaleEntry_t& prev = vec.back();
210 if (value <= prev.fMin)
211 throw (eh + "minimum value not larger than previous one.");
212
213 prev.fMax = value;
214 Float_t offset = prev.fOffset + (prev.fMax - prev.fMin)*prev.fScale;
215 vec.emplace_back(value, infty, offset, scale);
216 }
217}
218
219////////////////////////////////////////////////////////////////////////////////
220/// Change scale for given entry and coordinate.
221///
222/// NOTE: If the first entry you created used other value than 0,
223/// one entry (covering range from 0 to this value) was created
224/// automatically.
225
227 Float_t new_scale)
228{
229 static const REveException eh("REveProjection::ChangePreScaleEntry ");
230
231 if (coord < 0 || coord > 2)
232 throw (eh + "coordinate out of range.");
233
234 vPreScale_t& vec = fPreScales[coord];
235 Int_t vs = vec.size();
236 if (entry < 0 || entry >= vs)
237 throw (eh + "entry out of range.");
238
239 vec[entry].fScale = new_scale;
240 Int_t i0 = entry, i1 = entry + 1;
241 while (i1 < vs)
242 {
243 PreScaleEntry_t e0 = vec[i0];
244 vec[i1].fOffset = e0.fOffset + (e0.fMax - e0.fMin)*e0.fScale;
245 i0 = i1++;
246 }
247}
248
249////////////////////////////////////////////////////////////////////////////////
250/// Clear all pre-scaling information.
251
253{
254 fPreScales[0].clear();
255 fPreScales[1].clear();
256 fPreScales[2].clear();
257}
258
259////////////////////////////////////////////////////////////////////////////////
260/// Set distortion.
261
270
271////////////////////////////////////////////////////////////////////////////////
272/// Set fixed radius.
273
280
281////////////////////////////////////////////////////////////////////////////////
282/// Set fixed radius.
283
290
291////////////////////////////////////////////////////////////////////////////////
292/// Set 2's-exponent for relative scaling beyond FixR.
293
299
300////////////////////////////////////////////////////////////////////////////////
301/// Get projected center.
302
304{
305 static REveVector zero;
306
307 if (fDisplaceOrigin)
308 return zero.Arr();
309 else
310 return fCenter.Arr();
311}
312
313////////////////////////////////////////////////////////////////////////////////
314/// Set flag to displace for center.
315/// This options is useful if want to have projected center
316/// at (0, 0) position in projected coordinates and want to dismiss
317/// gap around projected center in RhoZ projection.
318
320{
322 // update projected center
324}
325
326////////////////////////////////////////////////////////////////////////////////
327/// Set 2's-exponent for relative scaling beyond FixZ.
328
334
335////////////////////////////////////////////////////////////////////////////////
336/// Find break-point on both sides of the discontinuity.
337/// They still need to be projected after the call.
338/// This is an obsolete version of the method that required manual
339/// specification of precision -- this lead to (infrequent) infinite loops.
340
342{
343 static Bool_t warnedp = kFALSE;
344
345 if (!warnedp)
346 {
347 Warning("BisectBreakPoint", "call with eps_sqr argument is obsolete - please use the new signature.");
348 warnedp = kTRUE;
349 }
350
351 BisectBreakPoint(vL, vR, kFALSE);
352}
353
354////////////////////////////////////////////////////////////////////////////////
355/// Find break-point on both sides of the discontinuity.
356/// If project_result is true, the resulting break points will be projected
357/// with given depth value.
358
360 Bool_t project_result, Float_t depth)
361{
362 REveVector vM, vLP, vMP;
363 Int_t n_loops = TMath::CeilNint(TMath::Log2(1e12 * (vL-vR).Mag2() / (0.5f*(vL+vR)).Mag2()) / 2);
364 while (--n_loops >= 0)
365 {
366 vM.Mult(vL + vR, 0.5f);
367 vLP.Set(vL); ProjectPoint(vLP.fX, vLP.fY, vLP.fZ, 0);
368 vMP.Set(vM); ProjectPoint(vMP.fX, vMP.fY, vMP.fZ, 0);
369
370 if (IsOnSubSpaceBoundrary(vMP))
371 {
372 vL.Set(vM);
373 vR.Set(vM);
374 break;
375 }
376
377 if (AcceptSegment(vLP, vMP, 0.0f))
378 {
379 vL.Set(vM);
380 }
381 else
382 {
383 vR.Set(vM);
384 }
385 }
386
387 if (project_result)
388 {
389 ProjectVector(vL, depth);
390 ProjectVector(vR, depth);
391 }
392}
393
394////////////////////////////////////////////////////////////////////////////////
395/// Get vector for axis in a projected space.
396
398{
399 for (Int_t i=0; i<3; i++)
400 {
401 vec[i] = (i==screenAxis) ? 1.0f : 0.0f;
402 }
403}
404
405////////////////////////////////////////////////////////////////////////////////
406/// Get center ortogonal to given axis index.
407
409{
410 REveVector dirVec;
411 SetDirectionalVector(i, dirVec);
412
413 REveVector dirCenter;
414 dirCenter.Mult(dirVec, fCenter.Dot(dirVec));
415 centerOO = fCenter - dirCenter;
416
417
418 return centerOO;
419}
420
421////////////////////////////////////////////////////////////////////////////////
422/// Inverse projection.
423
425{
426 static const REveException eH("REveProjection::GetValForScreenPos ");
427
428 static const int kMaxSteps = 5000;
429 static const int kMaxVal = 10;
430
431 Float_t xL, xM, xR;
432 REveVector vec;
433
434 REveVector dirVec;
435 SetDirectionalVector(axisIdx, dirVec);
436
437 REveVector zero;
438 if (fDisplaceOrigin) zero = fCenter;
439
440 REveVector zeroProjected = zero;
441 ProjectVector(zeroProjected, 0.f);
442
443 // search from -/+ infinity according to sign of screen value
444 if (sv > zeroProjected[axisIdx])
445 {
446 xL = 0;
447 xR = kMaxVal;
448
449 int cnt = 0;
450 while (cnt < kMaxSteps)
451 {
452 vec.Mult(dirVec, xR);
453 if (fDisplaceOrigin) vec += fCenter;
454
455 ProjectVector(vec, 0);
456 if (vec[axisIdx] >= sv) break;
457 xL = xR; xR *= 2;
458
459 if (++cnt >= kMaxSteps)
460 throw eH + Form("positive projected %f, value %f,xL, xR ( %f, %f)\n", vec[axisIdx], sv, xL, xR);
461 }
462 }
463 else if (sv < zeroProjected[axisIdx])
464 {
465 xR = 0;
466 xL = -kMaxVal;
467
468 int cnt = 0;
469 while (cnt < kMaxSteps)
470 {
471 vec.Mult(dirVec, xL);
472 if (fDisplaceOrigin) vec += fCenter;
473
474 ProjectVector(vec, 0);
475 if (vec[axisIdx] <= sv) break;
476 xR = xL; xL *= 2;
477 if (++cnt >= kMaxSteps)
478 throw eH + Form("negative projected %f, value %f,xL, xR ( %f, %f)\n", vec[axisIdx], sv, xL, xR);
479 }
480 }
481 else
482 {
483 return 0.0f;
484 }
485
486 // printf("search for value %f in rng[%f, %f] \n", sv, xL, xR);
487 int cnt = 0;
488 do
489 {
490 //printf("search value with bisection xL=%f, xR=%f; vec[axisIdx]=%f, sv=%f\n", xL, xR, vec[axisIdx], sv);
491 xM = 0.5f * (xL + xR);
492 vec.Mult(dirVec, xM);
493 if (fDisplaceOrigin) vec += fCenter;
494 ProjectVector(vec, 0);
495 if (vec[axisIdx] > sv)
496 xR = xM;
497 else
498 xL = xM;
499 if (++cnt >= kMaxSteps)
500 throw eH + Form("can't converge %f %f, l/r %f/%f, idx=%d\n", vec[axisIdx], sv, xL, xR, axisIdx);
501
502 } while (TMath::Abs(vec[axisIdx] - sv) >= fgEps);
503
504
505 return xM;
506}
507
508////////////////////////////////////////////////////////////////////////////////
509/// Project point on given axis and return projected value.
510
512{
513 REveVector pos = dirVec*x;
514
515 if (fDisplaceOrigin)
516 pos += fCenter;
517
518 ProjectVector(pos , 0.f);
519
520 return pos[i];
521}
522
523////////////////////////////////////////////////////////////////////////////////
524/// Project point on given axis and return projected value.
525
527{
528 REveVector dirVec;
529 SetDirectionalVector(i, dirVec);
530 REveVector oCenter;
531 // GetOrthogonalCenter(i, oCenter);
532 return GetScreenVal(i, x, dirVec, oCenter);
533}
534
535/** \class REveRhoZProjection
536\ingroup REve
537Transformation from 3D to 2D. X axis represent Z coordinate. Y axis have value of
538radius with a sign of Y coordinate.
539*/
540
541////////////////////////////////////////////////////////////////////////////////
542/// Constructor.
543
546{
547 fType = kPT_RhoZ;
548 fName = "RhoZ";
549 fPlaneNormal.Set(0,1,0);
550}
551
552////////////////////////////////////////////////////////////////////////////////
553/// Project point.
554
556 Float_t d, EPProc_e proc)
557{
558 using namespace TMath;
559
560 if (fDisplaceOrigin) {
561 x -= fCenter.fX;
562 y -= fCenter.fY;
563 z -= fCenter.fZ;
564 }
565 if (proc == kPP_Plane || proc == kPP_Full)
566 {
567 // project
568 const Float_t side = fPlaneNormal.fX * x +
569 fPlaneNormal.fY * y +
570 fPlaneNormal.fZ * z;
571
572 y = TMath::Sign((Float_t)TMath::Sqrt(x * x + y * y), side);
573 x = z;
574 }
575 if (proc == kPP_Distort || proc == kPP_Full)
576 {
577 if (fUsePreScale)
578 PreScalePoint(y, x);
579
580
581 // distort
582
583 if (!fDisplaceOrigin) {
586 }
587
588 if (x > fFixZ)
589 x = fFixZ + fPastFixZScale*(x - fFixZ);
590 else if (x < -fFixZ)
591 x = -fFixZ + fPastFixZScale*(x + fFixZ);
592 else
593 x = x * fScaleZ / (1.0f + Abs(x)*fDistortion);
594
595 if (y > fFixR)
596 y = fFixR + fPastFixRScale*(y - fFixR);
597 else if (y < -fFixR)
598 y = -fFixR + fPastFixRScale*(y + fFixR);
599 else
600 y = y * fScaleR / (1.0f + Abs(y)*fDistortion);
601
602 if (!fDisplaceOrigin) {
605 }
606 }
607 z = d;
608}
609
610////////////////////////////////////////////////////////////////////////////////
611/// Set center of distortion (virtual method).
612
614{
615 fCenter = v;
616
617 if (fDisplaceOrigin)
618 {
619 fProjectedCenter.Set(0.f, 0.f, 0.f);
620 }
621 else
622 {
623 Float_t r = TMath::Sqrt(v.fX*v.fX + v.fY*v.fY);
627 }
628}
629
630////////////////////////////////////////////////////////////////////////////////
631/// Get direction in the unprojected space for axis index in the
632/// projected space.
633/// This is virtual method from base-class REveProjection.
634
636{
637 if (screenAxis == 0)
638 vec.Set(0.0f, 0.0f, 1.0f);
639 else if (screenAxis == 1)
640 vec.Set(0.0f, 1.0f, 0.0f);
641
642}
643
644////////////////////////////////////////////////////////////////////////////////
645/// Check if segment of two projected points is valid.
646///
647/// Move slightly one of the points if by shifting it by no more than
648/// tolerance the segment can become acceptable.
649
651 Float_t tolerance) const
652{
653 if (fYAxis == false)
654 AcceptSegmentRotatedPlane(v1, v2, tolerance);
655
657 Bool_t val = kTRUE;
658 if ((v1.fY < a && v2.fY > a) || (v1.fY > a && v2.fY < a))
659 {
660 val = kFALSE;
661 if (tolerance > 0)
662 {
663 Float_t a1 = TMath::Abs(v1.fY - a), a2 = TMath::Abs(v2.fY - a);
664 if (a1 < a2)
665 {
666 if (a1 < tolerance) { v1.fY = a; val = kTRUE; }
667 }
668 else
669 {
670 if (a2 < tolerance) { v2.fY = a; val = kTRUE; }
671 }
672 }
673 }
674 return val;
675}
676
677////////////////////////////////////////////////////////////////////////////////
678/// Check if segment of two projected points is valid on a rotated plane
679///
680/// Move slightly one of the points if by shifting it by no more than
681/// tolerance the segment can become acceptable.
682
684 Float_t tolerance) const
685{
688
689 Bool_t val = kTRUE;
690
691 if ((d1 < 0 && d2 > 0) || (d1 > 0 && d2 < 0))
692 {
693 val = kFALSE;
694
695 if (tolerance > 0)
696 {
697 const Float_t a1 = TMath::Abs(d1);
698 const Float_t a2 = TMath::Abs(d2);
699
700 if (a1 < a2)
701 {
702 if (a1 < tolerance)
703 {
704 // Move v1 to the plane intersection.
705 const Float_t t = d1 / (d1 - d2);
706 v1 += t * (v2 - v1);
707
708 val = kTRUE;
709 }
710 }
711 else
712 {
713 if (a2 < tolerance)
714 {
715 // Move v2 to the plane intersection.
716 const Float_t t = d1 / (d1 - d2);
717 v2 = v1 + t * (v2 - v1);
718
719 val = kTRUE;
720 }
721 }
722 }
723 }
724
725 return val;
726}
727
728////////////////////////////////////////////////////////////////////////////////
729/// Set normal of the projection plane
730/// Projection center must be on the plane
731/// The default plane normal value is Y axis (0, 1, 0)
732
734{
735 REveVector yAxis(0, 1, 0);
736 if (v != yAxis) {
737 fYAxis = false;
738 }
740}
741
742////////////////////////////////////////////////////////////////////////////////
743/// Return sub-space id for the point.
744/// 0 - upper half-space
745/// 1 - lower half-space
746
748{
749 return v.fY > fProjectedCenter.fY ? 0 : 1;
750}
751
752////////////////////////////////////////////////////////////////////////////////
753/// Checks if point is on sub-space boundary.
754
759
760/** \class REveRPhiProjection
761\ingroup REve
762XY projection with distortion around given center.
763*/
764
765////////////////////////////////////////////////////////////////////////////////
766/// Constructor.
767
775
776////////////////////////////////////////////////////////////////////////////////
777/// Project point.
778
780 Float_t d, EPProc_e proc)
781{
782 using namespace TMath;
783
784 if (fDisplaceOrigin)
785 {
786 x -= fCenter.fX;
787 y -= fCenter.fY;
788 z -= fCenter.fZ;
789 }
790
791 if (proc != kPP_Plane)
792 {
793 Float_t r, phi;
794 if (fUsePreScale)
795 {
796 r = Sqrt(x*x + y*y);
797 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
798 PreScalePoint(r, phi);
799 x = r*Cos(phi);
800 y = r*Sin(phi);
801 }
802
803 if (!fDisplaceOrigin)
804 {
805 x -= fCenter.fX;
806 y -= fCenter.fY;
807 }
808
809 r = Sqrt(x*x + y*y);
810 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
811
812 if (r > fFixR)
813 r = fFixR + fPastFixRScale*(r - fFixR);
814 else if (r < -fFixR)
815 r = -fFixR + fPastFixRScale*(r + fFixR);
816 else
817 r = r * fScaleR / (1.0f + r*fDistortion);
818
819 x = r*Cos(phi);
820 y = r*Sin(phi);
821
822 if (!fDisplaceOrigin)
823 {
824 x += fCenter.fX;
825 y += fCenter.fY;
826 }
827 }
828 z = d;
829}
830
831/** \class REveXZProjection
832\ingroup REve
833XZ projection with distortion around given center.
834*/
835
836////////////////////////////////////////////////////////////////////////////////
837/// Constructor.
838
846
847////////////////////////////////////////////////////////////////////////////////
848/// Project point.
849
851 Float_t d, EPProc_e proc)
852{
853 using namespace TMath;
854
855 if (fDisplaceOrigin)
856 {
857 x -= fCenter.fX;
858 y -= fCenter.fY;
859 z -= fCenter.fZ;
860 }
861
862 // projection
863 if (proc == kPP_Plane || proc == kPP_Full)
864 {
865 y = z;
866 z = d;
867 }
868 if (proc != kPP_Distort || proc == kPP_Full)
869 {
870 Float_t r, phi;
871 if (fUsePreScale)
872 {
873 r = Sqrt(x*x + y*y);
874 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
875 PreScalePoint(r, phi);
876 x = r*Cos(phi);
877 y = r*Sin(phi);
878 }
879
880 if (!fDisplaceOrigin)
881 {
884 }
885
886 r = Sqrt(x*x + y*y);
887 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
888
889 if (r > fFixR)
890 r = fFixR + fPastFixRScale*(r - fFixR);
891 else if (r < -fFixR)
892 r = -fFixR + fPastFixRScale*(r + fFixR);
893 else
894 r = r * fScaleR / (1.0f + r*fDistortion);
895
896 x = r*Cos(phi);
897 y = r*Sin(phi);
898
899 if (!fDisplaceOrigin)
900 {
903 }
904 }
905}
906
907////////////////////////////////////////////////////////////////////////////////
908/// Set center of distortion (virtual method).
909
911{
912 fCenter = v;
913
914 if (fDisplaceOrigin)
915 {
916 fProjectedCenter.Set(0.f, 0.f, 0.f);
917 }
918 else
919 {
923 }
924}
925
926////////////////////////////////////////////////////////////////////////////////
927/// Get direction in the unprojected space for axis index in the
928/// projected space.
929/// This is virtual method from base-class REveProjection.
930
932{
933 if (screenAxis == 0)
934 vec.Set(1.0f, 0.0f, 0.0f);
935 else if (screenAxis == 1)
936 vec.Set(0.0f, 0.0f, 1.0f);
937}
938
939
940/** \class REveYZProjection
941\ingroup REve
942YZ projection with distortion around given center.
943*/
944
945////////////////////////////////////////////////////////////////////////////////
946/// Constructor.
947
955
956////////////////////////////////////////////////////////////////////////////////
957/// Project point.
958
960 Float_t d, EPProc_e proc)
961{
962 using namespace TMath;
963
964 if (fDisplaceOrigin)
965 {
966 x -= fCenter.fX;
967 y -= fCenter.fY;
968 z -= fCenter.fZ;
969 }
970
971 // projection
972 if (proc == kPP_Plane || proc == kPP_Full)
973 {
974 x = y;
975 y = z;
976 z = d;
977 }
978 if (proc != kPP_Distort || proc == kPP_Full)
979 {
980 Float_t r, phi;
981 if (fUsePreScale)
982 {
983 r = Sqrt(x*x + y*y);
984 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
985 PreScalePoint(r, phi);
986 x = r*Cos(phi);
987 y = r*Sin(phi);
988 }
989
990 if (!fDisplaceOrigin)
991 {
994 }
995
996 r = Sqrt(x*x + y*y);
997 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
998
999 if (r > fFixR)
1000 r = fFixR + fPastFixRScale*(r - fFixR);
1001 else if (r < -fFixR)
1002 r = -fFixR + fPastFixRScale*(r + fFixR);
1003 else
1004 r = r * fScaleR / (1.0f + r*fDistortion);
1005
1006 x = r*Cos(phi);
1007 y = r*Sin(phi);
1008
1009 if (!fDisplaceOrigin)
1010 {
1013 }
1014 }
1015}
1016
1017////////////////////////////////////////////////////////////////////////////////
1018/// Set center of distortion (virtual method).
1019
1021{
1022 fCenter = v;
1023
1024 if (fDisplaceOrigin)
1025 {
1026 fProjectedCenter.Set(0.f, 0.f, 0.f);
1027 }
1028 else
1029 {
1032 fProjectedCenter.fZ = 0;
1033 }
1034}
1035
1036////////////////////////////////////////////////////////////////////////////////
1037/// Get direction in the unprojected space for axis index in the
1038/// projected space.
1039/// This is virtual method from base-class REveProjection.
1040
1042{
1043 if (screenAxis == 0)
1044 vec.Set(0.0f, 1.0f, 0.0f);
1045 else if (screenAxis == 1)
1046 vec.Set(0.0f, 0.0f, 1.0f);
1047}
1048
1049/** \class REveZXProjection
1050\ingroup REve
1051ZX projection with distortion around given center.
1052*/
1053
1054////////////////////////////////////////////////////////////////////////////////
1055/// Constructor.
1056
1064
1065////////////////////////////////////////////////////////////////////////////////
1066/// Project point.
1067
1069 Float_t d, EPProc_e proc)
1070{
1071 using namespace TMath;
1072
1073 if (fDisplaceOrigin)
1074 {
1075 x -= fCenter.fX;
1076 y -= fCenter.fY;
1077 z -= fCenter.fZ;
1078 }
1079
1080 // projection
1081 if (proc == kPP_Plane || proc == kPP_Full)
1082 {
1083 y = x;
1084 x = z;
1085 z = d;
1086 }
1087 if (proc != kPP_Distort || proc == kPP_Full)
1088 {
1089 Float_t r, phi;
1090 if (fUsePreScale)
1091 {
1092 r = Sqrt(x*x + y*y);
1093 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1094 PreScalePoint(r, phi);
1095 x = r*Cos(phi);
1096 y = r*Sin(phi);
1097 }
1098
1099 if (!fDisplaceOrigin)
1100 {
1103 }
1104
1105 r = Sqrt(x*x + y*y);
1106 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1107
1108 if (r > fFixR)
1109 r = fFixR + fPastFixRScale*(r - fFixR);
1110 else if (r < -fFixR)
1111 r = -fFixR + fPastFixRScale*(r + fFixR);
1112 else
1113 r = r * fScaleR / (1.0f + r*fDistortion);
1114
1115 x = r*Cos(phi);
1116 y = r*Sin(phi);
1117
1118 if (!fDisplaceOrigin)
1119 {
1122 }
1123 }
1124}
1125
1126////////////////////////////////////////////////////////////////////////////////
1127/// Set center of distortion (virtual method).
1128
1130{
1131 fCenter = v;
1132
1133 if (fDisplaceOrigin)
1134 {
1135 fProjectedCenter.Set(0.f, 0.f, 0.f);
1136 }
1137 else
1138 {
1141 fProjectedCenter.fZ = 0;
1142 }
1143}
1144
1145////////////////////////////////////////////////////////////////////////////////
1146/// Get direction in the unprojected space for axis index in the
1147/// projected space.
1148/// This is virtual method from base-class REveProjection.
1149
1151{
1152 if (screenAxis == 0)
1153 vec.Set(0.0f, 0.0f, 1.0f);
1154 else if (screenAxis == 1)
1155 vec.Set(1.0f, 0.0f, 0.0f);
1156}
1157
1158
1159/** \class REveZYProjection
1160\ingroup REve
1161ZY projection with distortion around given center.
1162*/
1163
1164////////////////////////////////////////////////////////////////////////////////
1165/// Constructor.
1166
1174
1175////////////////////////////////////////////////////////////////////////////////
1176/// Project point.
1177
1179 Float_t d, EPProc_e proc)
1180{
1181 using namespace TMath;
1182
1183 if (fDisplaceOrigin)
1184 {
1185 x -= fCenter.fX;
1186 y -= fCenter.fY;
1187 z -= fCenter.fZ;
1188 }
1189
1190 // projection
1191 if (proc == kPP_Plane || proc == kPP_Full)
1192 {
1193 x = z;
1194 z = d;
1195 }
1196 if (proc != kPP_Distort || proc == kPP_Full)
1197 {
1198 Float_t r, phi;
1199 if (fUsePreScale)
1200 {
1201 r = Sqrt(x*x + y*y);
1202 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1203 PreScalePoint(r, phi);
1204 x = r*Cos(phi);
1205 y = r*Sin(phi);
1206 }
1207
1208 if (!fDisplaceOrigin)
1209 {
1212 }
1213
1214 r = Sqrt(x*x + y*y);
1215 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
1216
1217 if (r > fFixR)
1218 r = fFixR + fPastFixRScale*(r - fFixR);
1219 else if (r < -fFixR)
1220 r = -fFixR + fPastFixRScale*(r + fFixR);
1221 else
1222 r = r * fScaleR / (1.0f + r*fDistortion);
1223
1224 x = r*Cos(phi);
1225 y = r*Sin(phi);
1226
1227 if (!fDisplaceOrigin)
1228 {
1231 }
1232 }
1233}
1234
1235////////////////////////////////////////////////////////////////////////////////
1236/// Set center of distortion (virtual method).
1237
1239{
1240 fCenter = v;
1241
1242 if (fDisplaceOrigin)
1243 {
1244 fProjectedCenter.Set(0.f, 0.f, 0.f);
1245 }
1246 else
1247 {
1250 fProjectedCenter.fZ = 0;
1251 }
1252}
1253
1254////////////////////////////////////////////////////////////////////////////////
1255/// Get direction in the unprojected space for axis index in the
1256/// projected space.
1257/// This is virtual method from base-class REveProjection.
1258
1260{
1261 if (screenAxis == 0)
1262 vec.Set(0.0f, 0.0f, 1.0f);
1263 else if (screenAxis == 1)
1264 vec.Set(0.0f, 1.0f, 0.0f);
1265}
1266
1267/** \class REve3DProjection
1268\ingroup REve
12693D scaling projection. One has to use pre-scaling to make any ise of this.
1270*/
1271
1272////////////////////////////////////////////////////////////////////////////////
1273/// Constructor.
1274
1277{
1278 fType = kPT_3D;
1280 fName = "3D";
1281}
1282
1283////////////////////////////////////////////////////////////////////////////////
1284/// Project point.
1285
1287 Float_t /*d*/, EPProc_e proc)
1288{
1289 using namespace TMath;
1290
1291 if (proc != kPP_Plane)
1292 {
1293 if (fUsePreScale)
1294 {
1295 PreScalePoint(x, y, z);
1296 }
1297
1298 x -= fCenter.fX;
1299 y -= fCenter.fY;
1300 z -= fCenter.fZ;
1301 }
1302}
#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