28 ClassImp(TEveProjection);
30 Float_t TEveProjection::fgEps = 0.005f;
31 Float_t TEveProjection::fgEpsSqr = 0.000025f;
36 TEveProjection::TEveProjection() :
38 fGeoMode (kGM_Unknown),
41 fDisplaceOrigin (kFALSE),
42 fUsePreScale (kFALSE),
44 fFixR (300), fFixZ (400),
45 fPastFixRFac (0), fPastFixZFac (0),
46 fScaleR (1), fScaleZ (1),
47 fPastFixRScale (1), fPastFixZScale (1),
55 void TEveProjection::ProjectPointfv(Float_t* v, Float_t d)
57 ProjectPoint(v[0], v[1], v[2], d);
64 void TEveProjection::ProjectPointdv(Double_t* v, Float_t d)
66 Float_t x = v[0], y = v[1], z = v[2];
67 ProjectPoint(x, y, z, d);
68 v[0] = x; v[1] = y; v[2] = z;
74 void TEveProjection::ProjectVector(TEveVector& v, Float_t d)
76 ProjectPoint(v.fX, v.fY, v.fZ, d);
83 void TEveProjection::ProjectPointfv(
const TEveTrans* t,
const Float_t* p, Float_t* v, Float_t d)
85 v[0] = p[0]; v[1] = p[1]; v[2] = p[2];
90 ProjectPoint(v[0], v[1], v[2], d);
98 void TEveProjection::ProjectPointdv(
const TEveTrans* t,
const Double_t* p, Double_t* v, Float_t d)
104 x = v[0]; y = v[1]; z = v[2];
108 x = p[0]; y = p[1]; z = p[2];
110 ProjectPoint(x, y, z, d);
111 v[0] = x; v[1] = y; v[2] = z;
118 void TEveProjection::ProjectVector(
const TEveTrans* t, TEveVector& v, Float_t d)
124 ProjectPoint(v.fX, v.fY, v.fZ, d);
130 void TEveProjection::PreScaleVariable(Int_t dim, Float_t& v)
132 if (!fPreScales[dim].empty())
134 Bool_t invp = kFALSE;
139 vPreScale_i i = fPreScales[dim].begin();
142 v = i->fOffset + (v - i->fMin)*i->fScale;
153 void TEveProjection::PreScalePoint(Float_t& x, Float_t& y)
155 PreScaleVariable(0, x);
156 PreScaleVariable(1, y);
162 void TEveProjection::PreScalePoint(Float_t& x, Float_t& y, Float_t& z)
164 PreScaleVariable(0, x);
165 PreScaleVariable(1, y);
166 PreScaleVariable(2, z);
180 void TEveProjection::AddPreScaleEntry(Int_t coord, Float_t value, Float_t scale)
182 static const TEveException eh(
"TEveProjection::AddPreScaleEntry ");
184 if (coord < 0 || coord > 2)
185 throw (eh +
"coordinate out of range.");
187 const Float_t infty = std::numeric_limits<Float_t>::infinity();
189 vPreScale_t& vec = fPreScales[coord];
195 vec.push_back(PreScaleEntry_t(0, infty, 0, scale));
199 vec.push_back(PreScaleEntry_t(0, value, 0, 1));
200 vec.push_back(PreScaleEntry_t(value, infty, value, scale));
205 PreScaleEntry_t& prev = vec.back();
206 if (value <= prev.fMin)
207 throw (eh +
"minimum value not larger than previous one.");
210 Float_t offset = prev.fOffset + (prev.fMax - prev.fMin)*prev.fScale;
211 vec.push_back(PreScaleEntry_t(value, infty, offset, scale));
222 void TEveProjection::ChangePreScaleEntry(Int_t coord, Int_t entry,
225 static const TEveException eh(
"TEveProjection::ChangePreScaleEntry ");
227 if (coord < 0 || coord > 2)
228 throw (eh +
"coordinate out of range.");
230 vPreScale_t& vec = fPreScales[coord];
231 Int_t vs = vec.size();
232 if (entry < 0 || entry >= vs)
233 throw (eh +
"entry out of range.");
235 vec[entry].fScale = new_scale;
236 Int_t i0 = entry, i1 = entry + 1;
239 PreScaleEntry_t e0 = vec[i0];
240 vec[i1].fOffset = e0.fOffset + (e0.fMax - e0.fMin)*e0.fScale;
248 void TEveProjection::ClearPreScales()
250 fPreScales[0].clear();
251 fPreScales[1].clear();
252 fPreScales[2].clear();
258 void TEveProjection::SetDistortion(Float_t d)
261 fScaleR = 1.0f + fFixR*fDistortion;
262 fScaleZ = 1.0f + fFixZ*fDistortion;
263 fPastFixRScale = TMath::Power(10.0f, fPastFixRFac) / fScaleR;
264 fPastFixZScale = TMath::Power(10.0f, fPastFixZFac) / fScaleZ;
270 void TEveProjection::SetFixR(Float_t r)
273 fScaleR = 1 + fFixR*fDistortion;
274 fPastFixRScale = TMath::Power(10.0f, fPastFixRFac) / fScaleR;
280 void TEveProjection::SetFixZ(Float_t z)
283 fScaleZ = 1 + fFixZ*fDistortion;
284 fPastFixZScale = TMath::Power(10.0f, fPastFixZFac) / fScaleZ;
290 void TEveProjection::SetPastFixRFac(Float_t x)
293 fPastFixRScale = TMath::Power(10.0f, fPastFixRFac) / fScaleR;
299 Float_t* TEveProjection::GetProjectedCenter()
301 static TEveVector zero;
306 return fCenter.Arr();
315 void TEveProjection::SetDisplaceOrigin(Bool_t x)
325 void TEveProjection::SetPastFixZFac(Float_t x)
328 fPastFixZScale = TMath::Power(10.0f, fPastFixZFac) / fScaleZ;
337 void TEveProjection::BisectBreakPoint(TEveVector& vL, TEveVector& vR, Float_t )
339 static Bool_t warnedp = kFALSE;
343 Warning(
"BisectBreakPoint",
"call with eps_sqr argument is obsolete - please use the new signature.");
347 BisectBreakPoint(vL, vR, kFALSE);
355 void TEveProjection::BisectBreakPoint(TEveVector& vL, TEveVector& vR,
356 Bool_t project_result, Float_t depth)
358 TEveVector vM, vLP, vMP;
359 Int_t n_loops = TMath::CeilNint(TMath::Log2(1e12 * (vL-vR).Mag2() / (0.5f*(vL+vR)).Mag2()) / 2);
360 while (--n_loops >= 0)
362 vM.Mult(vL + vR, 0.5f);
363 vLP.Set(vL); ProjectPoint(vLP.fX, vLP.fY, vLP.fZ, 0);
364 vMP.Set(vM); ProjectPoint(vMP.fX, vMP.fY, vMP.fZ, 0);
366 if (IsOnSubSpaceBoundrary(vMP))
373 if (AcceptSegment(vLP, vMP, 0.0f))
385 ProjectVector(vL, depth);
386 ProjectVector(vR, depth);
393 Float_t TEveProjection::GetLimit(Int_t, Bool_t)
395 ::Warning(
"TEveProjection::GetLimits",
"method is obsolete");
403 void TEveProjection::SetDirectionalVector(Int_t screenAxis, TEveVector& vec)
405 for (Int_t i=0; i<3; i++)
407 vec[i] = (i==screenAxis) ? 1.0f : 0.0f;
414 TEveVector TEveProjection::GetOrthogonalCenter(
int i, TEveVector& centerOO)
417 SetDirectionalVector(i, dirVec);
419 TEveVector dirCenter;
420 dirCenter.Mult(dirVec, fCenter.Dot(dirVec));
421 centerOO = fCenter - dirCenter;
430 Float_t TEveProjection::GetValForScreenPos(Int_t axisIdx, Float_t sv)
432 static const TEveException eH(
"TEveProjection::GetValForScreenPos ");
434 static const int kMaxSteps = 5000;
435 static const int kMaxVal = 10;
441 SetDirectionalVector(axisIdx, dirVec);
444 if (fDisplaceOrigin) zero = fCenter;
446 TEveVector zeroProjected = zero;
447 ProjectVector(zeroProjected, 0.f);
450 if (sv > zeroProjected[axisIdx])
456 while (cnt < kMaxSteps)
458 vec.Mult(dirVec, xR);
459 if (fDisplaceOrigin) vec += fCenter;
461 ProjectVector(vec, 0);
462 if (vec[axisIdx] >= sv)
break;
465 if (++cnt >= kMaxSteps)
466 throw eH + Form(
"positive projected %f, value %f,xL, xR ( %f, %f)\n", vec[axisIdx], sv, xL, xR);
469 else if (sv < zeroProjected[axisIdx])
475 while (cnt < kMaxSteps)
477 vec.Mult(dirVec, xL);
478 if (fDisplaceOrigin) vec += fCenter;
480 ProjectVector(vec, 0);
481 if (vec[axisIdx] <= sv)
break;
483 if (++cnt >= kMaxSteps)
484 throw eH + Form(
"negative projected %f, value %f,xL, xR ( %f, %f)\n", vec[axisIdx], sv, xL, xR);
497 xM = 0.5f * (xL + xR);
498 vec.Mult(dirVec, xM);
499 if (fDisplaceOrigin) vec += fCenter;
500 ProjectVector(vec, 0);
501 if (vec[axisIdx] > sv)
505 if (++cnt >= kMaxSteps)
506 throw eH + Form(
"can't converge %f %f, l/r %f/%f, idx=%d\n", vec[axisIdx], sv, xL, xR, axisIdx);
508 }
while (TMath::Abs(vec[axisIdx] - sv) >= fgEps);
517 Float_t TEveProjection::GetScreenVal(Int_t i, Float_t x, TEveVector& dirVec, TEveVector& )
519 TEveVector pos = dirVec*x;
524 ProjectVector(pos , 0.f);
532 Float_t TEveProjection::GetScreenVal(Int_t i, Float_t x)
535 SetDirectionalVector(i, dirVec);
538 return GetScreenVal(i, x, dirVec, oCenter);
547 ClassImp(TEveRhoZProjection);
552 TEveRhoZProjection::TEveRhoZProjection() :
562 void TEveRhoZProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
563 Float_t d, EPProc_e proc)
565 using namespace TMath;
567 if (fDisplaceOrigin) {
572 if (proc == kPP_Plane || proc == kPP_Full)
575 y = Sign((Float_t)Sqrt(x*x+y*y), y);
578 if (proc == kPP_Distort || proc == kPP_Full)
586 if (!fDisplaceOrigin) {
587 x -= fProjectedCenter.fX;
588 y -= fProjectedCenter.fY;
592 x = fFixZ + fPastFixZScale*(x - fFixZ);
594 x = -fFixZ + fPastFixZScale*(x + fFixZ);
596 x = x * fScaleZ / (1.0f + Abs(x)*fDistortion);
599 y = fFixR + fPastFixRScale*(y - fFixR);
601 y = -fFixR + fPastFixRScale*(y + fFixR);
603 y = y * fScaleR / (1.0f + Abs(y)*fDistortion);
605 if (!fDisplaceOrigin) {
606 x += fProjectedCenter.fX;
607 y += fProjectedCenter.fY;
616 void TEveRhoZProjection::SetCenter(TEveVector& v)
622 fProjectedCenter.Set(0.f, 0.f, 0.f);
626 Float_t r = TMath::Sqrt(v.fX*v.fX + v.fY*v.fY);
627 fProjectedCenter.fX = fCenter.fZ;
628 fProjectedCenter.fY = TMath::Sign(r, fCenter.fY);
629 fProjectedCenter.fZ = 0;
638 void TEveRhoZProjection::SetDirectionalVector(Int_t screenAxis, TEveVector& vec)
641 vec.Set(0.0f, 0.0f, 1.0f);
642 else if (screenAxis == 1)
643 vec.Set(0.0f, 1.0f, 0.0f);
653 Bool_t TEveRhoZProjection::AcceptSegment(TEveVector& v1, TEveVector& v2,
654 Float_t tolerance)
const
656 Float_t a = fProjectedCenter.fY;
658 if ((v1.fY < a && v2.fY > a) || (v1.fY > a && v2.fY < a))
663 Float_t a1 = TMath::Abs(v1.fY - a), a2 = TMath::Abs(v2.fY - a);
666 if (a1 < tolerance) { v1.fY = a; val = kTRUE; }
670 if (a2 < tolerance) { v2.fY = a; val = kTRUE; }
682 Int_t TEveRhoZProjection::SubSpaceId(
const TEveVector& v)
const
684 return v.fY > fProjectedCenter.fY ? 0 : 1;
690 Bool_t TEveRhoZProjection::IsOnSubSpaceBoundrary(
const TEveVector& v)
const
692 return v.fY == fProjectedCenter.fY;
700 ClassImp(TEveRPhiProjection);
705 TEveRPhiProjection::TEveRPhiProjection() :
709 fGeoMode = kGM_Polygons;
716 void TEveRPhiProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
717 Float_t d, EPProc_e proc)
719 using namespace TMath;
728 if (proc != kPP_Plane)
734 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
735 PreScalePoint(r, phi);
740 if (!fDisplaceOrigin)
747 phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
750 r = fFixR + fPastFixRScale*(r - fFixR);
752 r = -fFixR + fPastFixRScale*(r + fFixR);
754 r = r * fScaleR / (1.0f + r*fDistortion);
759 if (!fDisplaceOrigin)
773 ClassImp(TEve3DProjection);
778 TEve3DProjection::TEve3DProjection() :
782 fGeoMode = kGM_Unknown;
789 void TEve3DProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
790 Float_t , EPProc_e proc)
792 using namespace TMath;
794 if (proc != kPP_Plane)
798 PreScalePoint(x, y, z);