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);