20 using namespace ROOT::Experimental;
21 namespace REX = ROOT::Experimental;
31 Float_t REX::REveProjection::fgEps = 0.005f;
32 Float_t REX::REveProjection::fgEpsSqr = 0.000025f;
37 REveProjection::REveProjection() :
39 fGeoMode (kGM_Unknown),
42 fDisplaceOrigin (kFALSE),
43 fUsePreScale (kFALSE),
45 fFixR (300), fFixZ (400),
46 fPastFixRFac (0), fPastFixZFac (0),
47 fScaleR (1), fScaleZ (1),
48 fPastFixRScale (1), fPastFixZScale (1),
56 void REveProjection::ProjectPointfv(Float_t* v, Float_t d)
58 ProjectPoint(v[0], v[1], v[2], d);
65 void REveProjection::ProjectPointdv(Double_t* v, Float_t d)
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;
75 void REveProjection::ProjectVector(REveVector& v, Float_t d)
77 ProjectPoint(v.fX, v.fY, v.fZ, d);
84 void REveProjection::ProjectPointfv(
const REveTrans* t,
const Float_t* p, Float_t* v, Float_t d)
86 v[0] = p[0]; v[1] = p[1]; v[2] = p[2];
91 ProjectPoint(v[0], v[1], v[2], d);
99 void REveProjection::ProjectPointdv(
const REveTrans* t,
const Double_t* p, Double_t* v, Float_t d)
105 x = v[0]; y = v[1]; z = v[2];
109 x = p[0]; y = p[1]; z = p[2];
111 ProjectPoint(x, y, z, d);
112 v[0] = x; v[1] = y; v[2] = z;
119 void REveProjection::ProjectVector(
const REveTrans* t, REveVector& v, Float_t d)
125 ProjectPoint(v.fX, v.fY, v.fZ, d);
131 void REveProjection::PreScaleVariable(Int_t dim, Float_t& v)
133 if (!fPreScales[dim].empty())
135 Bool_t invp = kFALSE;
140 auto i = fPreScales[dim].begin();
143 v = i->fOffset + (v - i->fMin)*i->fScale;
154 void REveProjection::PreScalePoint(Float_t& x, Float_t& y)
156 PreScaleVariable(0, x);
157 PreScaleVariable(1, y);
163 void REveProjection::PreScalePoint(Float_t& x, Float_t& y, Float_t& z)
165 PreScaleVariable(0, x);
166 PreScaleVariable(1, y);
167 PreScaleVariable(2, z);
181 void REveProjection::AddPreScaleEntry(Int_t coord, Float_t value, Float_t scale)
183 static const REveException eh(
"REveProjection::AddPreScaleEntry ");
185 if (coord < 0 || coord > 2)
186 throw (eh +
"coordinate out of range.");
188 const Float_t infty = std::numeric_limits<Float_t>::infinity();
190 vPreScale_t& vec = fPreScales[coord];
196 vec.emplace_back(0, infty, 0, scale);
200 vec.emplace_back(0, value, 0, 1);
201 vec.emplace_back(value, infty, value, scale);
206 PreScaleEntry_t& prev = vec.back();
207 if (value <= prev.fMin)
208 throw (eh +
"minimum value not larger than previous one.");
211 Float_t offset = prev.fOffset + (prev.fMax - prev.fMin)*prev.fScale;
212 vec.emplace_back(value, infty, offset, scale);
223 void REveProjection::ChangePreScaleEntry(Int_t coord, Int_t entry,
226 static const REveException eh(
"REveProjection::ChangePreScaleEntry ");
228 if (coord < 0 || coord > 2)
229 throw (eh +
"coordinate out of range.");
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.");
236 vec[entry].fScale = new_scale;
237 Int_t i0 = entry, i1 = entry + 1;
240 PreScaleEntry_t e0 = vec[i0];
241 vec[i1].fOffset = e0.fOffset + (e0.fMax - e0.fMin)*e0.fScale;
249 void REveProjection::ClearPreScales()
251 fPreScales[0].clear();
252 fPreScales[1].clear();
253 fPreScales[2].clear();
259 void REveProjection::SetDistortion(Float_t d)
262 fScaleR = 1.0f + fFixR*fDistortion;
263 fScaleZ = 1.0f + fFixZ*fDistortion;
264 fPastFixRScale = TMath::Power(10.0f, fPastFixRFac) / fScaleR;
265 fPastFixZScale = TMath::Power(10.0f, fPastFixZFac) / fScaleZ;
271 void REveProjection::SetFixR(Float_t r)
274 fScaleR = 1 + fFixR*fDistortion;
275 fPastFixRScale = TMath::Power(10.0f, fPastFixRFac) / fScaleR;
281 void REveProjection::SetFixZ(Float_t z)
284 fScaleZ = 1 + fFixZ*fDistortion;
285 fPastFixZScale = TMath::Power(10.0f, fPastFixZFac) / fScaleZ;
291 void REveProjection::SetPastFixRFac(Float_t x)
294 fPastFixRScale = TMath::Power(10.0f, fPastFixRFac) / fScaleR;
300 Float_t* REveProjection::GetProjectedCenter()
302 static REveVector zero;
307 return fCenter.Arr();
316 void REveProjection::SetDisplaceOrigin(Bool_t x)
326 void REveProjection::SetPastFixZFac(Float_t x)
329 fPastFixZScale = TMath::Power(10.0f, fPastFixZFac) / fScaleZ;
338 void REveProjection::BisectBreakPoint(REveVector& vL, REveVector& vR, Float_t )
340 static Bool_t warnedp = kFALSE;
344 Warning(
"BisectBreakPoint",
"call with eps_sqr argument is obsolete - please use the new signature.");
348 BisectBreakPoint(vL, vR, kFALSE);
356 void REveProjection::BisectBreakPoint(REveVector& vL, REveVector& vR,
357 Bool_t project_result, Float_t depth)
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)
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);
367 if (IsOnSubSpaceBoundrary(vMP))
374 if (AcceptSegment(vLP, vMP, 0.0f))
386 ProjectVector(vL, depth);
387 ProjectVector(vR, depth);
394 void REveProjection::SetDirectionalVector(Int_t screenAxis, REveVector& vec)
396 for (Int_t i=0; i<3; i++)
398 vec[i] = (i==screenAxis) ? 1.0f : 0.0f;
405 REveVector REveProjection::GetOrthogonalCenter(
int i, REveVector& centerOO)
408 SetDirectionalVector(i, dirVec);
410 REveVector dirCenter;
411 dirCenter.Mult(dirVec, fCenter.Dot(dirVec));
412 centerOO = fCenter - dirCenter;
421 Float_t REveProjection::GetValForScreenPos(Int_t axisIdx, Float_t sv)
423 static const REveException eH(
"REveProjection::GetValForScreenPos ");
425 static const int kMaxSteps = 5000;
426 static const int kMaxVal = 10;
432 SetDirectionalVector(axisIdx, dirVec);
435 if (fDisplaceOrigin) zero = fCenter;
437 REveVector zeroProjected = zero;
438 ProjectVector(zeroProjected, 0.f);
441 if (sv > zeroProjected[axisIdx])
447 while (cnt < kMaxSteps)
449 vec.Mult(dirVec, xR);
450 if (fDisplaceOrigin) vec += fCenter;
452 ProjectVector(vec, 0);
453 if (vec[axisIdx] >= sv)
break;
456 if (++cnt >= kMaxSteps)
457 throw eH + Form(
"positive projected %f, value %f,xL, xR ( %f, %f)\n", vec[axisIdx], sv, xL, xR);
460 else if (sv < zeroProjected[axisIdx])
466 while (cnt < kMaxSteps)
468 vec.Mult(dirVec, xL);
469 if (fDisplaceOrigin) vec += fCenter;
471 ProjectVector(vec, 0);
472 if (vec[axisIdx] <= sv)
break;
474 if (++cnt >= kMaxSteps)
475 throw eH + Form(
"negative projected %f, value %f,xL, xR ( %f, %f)\n", vec[axisIdx], sv, xL, xR);
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)
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);
499 }
while (TMath::Abs(vec[axisIdx] - sv) >= fgEps);
508 Float_t REveProjection::GetScreenVal(Int_t i, Float_t x, REveVector& dirVec, REveVector& )
510 REveVector pos = dirVec*x;
515 ProjectVector(pos , 0.f);
523 Float_t REveProjection::GetScreenVal(Int_t i, Float_t x)
526 SetDirectionalVector(i, dirVec);
529 return GetScreenVal(i, x, dirVec, oCenter);
541 REveRhoZProjection::REveRhoZProjection() :
551 void REveRhoZProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
552 Float_t d, EPProc_e proc)
554 using namespace TMath;
556 if (fDisplaceOrigin) {
561 if (proc == kPP_Plane || proc == kPP_Full)
564 y = Sign((Float_t)Sqrt(x*x+y*y), y);
567 if (proc == kPP_Distort || proc == kPP_Full)
575 if (!fDisplaceOrigin) {
576 x -= fProjectedCenter.fX;
577 y -= fProjectedCenter.fY;
581 x = fFixZ + fPastFixZScale*(x - fFixZ);
583 x = -fFixZ + fPastFixZScale*(x + fFixZ);
585 x = x * fScaleZ / (1.0f + Abs(x)*fDistortion);
588 y = fFixR + fPastFixRScale*(y - fFixR);
590 y = -fFixR + fPastFixRScale*(y + fFixR);
592 y = y * fScaleR / (1.0f + Abs(y)*fDistortion);
594 if (!fDisplaceOrigin) {
595 x += fProjectedCenter.fX;
596 y += fProjectedCenter.fY;
605 void REveRhoZProjection::SetCenter(REveVector& v)
611 fProjectedCenter.Set(0.f, 0.f, 0.f);
615 Float_t r = TMath::Sqrt(v.fX*v.fX + v.fY*v.fY);
616 fProjectedCenter.fX = fCenter.fZ;
617 fProjectedCenter.fY = TMath::Sign(r, fCenter.fY);
618 fProjectedCenter.fZ = 0;
627 void REveRhoZProjection::SetDirectionalVector(Int_t screenAxis, REveVector& vec)
630 vec.Set(0.0f, 0.0f, 1.0f);
631 else if (screenAxis == 1)
632 vec.Set(0.0f, 1.0f, 0.0f);
642 Bool_t REveRhoZProjection::AcceptSegment(REveVector& v1, REveVector& v2,
643 Float_t tolerance)
const
645 Float_t a = fProjectedCenter.fY;
647 if ((v1.fY < a && v2.fY > a) || (v1.fY > a && v2.fY < a))
652 Float_t a1 = TMath::Abs(v1.fY - a), a2 = TMath::Abs(v2.fY - a);
655 if (a1 < tolerance) { v1.fY = a; val = kTRUE; }
659 if (a2 < tolerance) { v2.fY = a; val = kTRUE; }
671 Int_t REveRhoZProjection::SubSpaceId(
const REveVector& v)
const
673 return v.fY > fProjectedCenter.fY ? 0 : 1;
679 Bool_t REveRhoZProjection::IsOnSubSpaceBoundrary(
const REveVector& v)
const
681 return v.fY == fProjectedCenter.fY;
692 REveRPhiProjection::REveRPhiProjection() :
696 fGeoMode = kGM_Polygons;
703 void REveRPhiProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
704 Float_t d, EPProc_e proc)
706 using namespace TMath;
715 if (proc != kPP_Plane)
721 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
722 PreScalePoint(r, phi);
727 if (!fDisplaceOrigin)
734 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
737 r = fFixR + fPastFixRScale*(r - fFixR);
739 r = -fFixR + fPastFixRScale*(r + fFixR);
741 r = r * fScaleR / (1.0f + r*fDistortion);
746 if (!fDisplaceOrigin)
763 REve3DProjection::REve3DProjection() :
767 fGeoMode = kGM_Unknown;
774 void REve3DProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
775 Float_t , EPProc_e proc)
777 using namespace TMath;
779 if (proc != kPP_Plane)
783 PreScalePoint(x, y, z);