#include "TEveProjections.h"
#include "TEveUtil.h"
ClassImp(TEveProjection);
Float_t TEveProjection::fgEps = 0.005f;
TEveProjection::TEveProjection(TEveVector& center) :
fType (kPT_Unknown),
fGeoMode (kGM_Unknown),
fName (0),
fCenter (center.fX, center.fY, center.fZ),
fDistortion (0.0f),
fFixR (300), fFixZ (400),
fPastFixRFac (0), fPastFixZFac (0),
fScaleR (1), fScaleZ (1),
fPastFixRScale (1), fPastFixZScale (1),
fLowLimit(-std::numeric_limits<Float_t>::infinity(),
-std::numeric_limits<Float_t>::infinity(),
-std::numeric_limits<Float_t>::infinity()),
fUpLimit ( std::numeric_limits<Float_t>::infinity(),
std::numeric_limits<Float_t>::infinity(),
std::numeric_limits<Float_t>::infinity())
{
}
void TEveProjection::ProjectVector(TEveVector& v)
{
ProjectPoint(v.fX, v.fY, v.fZ);
}
void TEveProjection::UpdateLimit()
{
if (fDistortion == 0.0f)
return;
Float_t lim = 1.0f/fDistortion + fFixR;
Float_t *c = GetProjectedCenter();
fUpLimit .Set( lim + c[0], lim + c[1], c[2]);
fLowLimit.Set(-lim + c[0], -lim + c[1], c[2]);
}
void TEveProjection::SetDistortion(Float_t d)
{
fDistortion = d;
fScaleR = 1.0f + fFixR*fDistortion;
fScaleZ = 1.0f + fFixZ*fDistortion;
fPastFixRScale = TMath::Power(10.0f, fPastFixRFac) / fScaleR;
fPastFixZScale = TMath::Power(10.0f, fPastFixZFac) / fScaleZ;
UpdateLimit();
}
void TEveProjection::SetFixR(Float_t r)
{
fFixR = r;
fScaleR = 1 + fFixR*fDistortion;
fPastFixRScale = TMath::Power(10.0f, fPastFixRFac) / fScaleR;
UpdateLimit();
}
void TEveProjection::SetFixZ(Float_t z)
{
fFixZ = z;
fScaleZ = 1 + fFixZ*fDistortion;
fPastFixZScale = TMath::Power(10.0f, fPastFixZFac) / fScaleZ;
UpdateLimit();
}
void TEveProjection::SetPastFixRFac(Float_t x)
{
fPastFixRFac = x;
fPastFixRScale = TMath::Power(10.0f, fPastFixRFac) / fScaleR;
}
void TEveProjection::SetPastFixZFac(Float_t x)
{
fPastFixZFac = x;
fPastFixZScale = TMath::Power(10.0f, fPastFixZFac) / fScaleZ;
}
void TEveProjection::SetDirectionalVector(Int_t screenAxis, TEveVector& vec)
{
for (Int_t i=0; i<3; i++)
{
vec[i] = (i==screenAxis) ? 1.0f : 0.0f;
}
}
Float_t TEveProjection::GetValForScreenPos(Int_t i, Float_t sv)
{
static const TEveException eH("TEveProjection::GetValForScreenPos ");
Float_t xL, xM, xR;
TEveVector vec;
TEveVector dirVec;
SetDirectionalVector(i, dirVec);
if (fDistortion > 0.0f && ((sv > 0 && sv > fUpLimit[i]) || (sv < 0 && sv < fLowLimit[i])))
throw(eH + Form("screen value '%f' out of limit '%f'.", sv, sv > 0 ? fUpLimit[i] : fLowLimit[i]));
TEveVector zero; ProjectVector(zero);
if (sv > zero[i])
{
xL = 0; xR = 1000;
while (1)
{
vec.Mult(dirVec, xR); ProjectVector(vec);
if (vec[i] > sv || vec[i] == sv) break;
xL = xR; xR *= 2;
}
}
else if (sv < zero[i])
{
xR = 0; xL = -1000;
while (1)
{
vec.Mult(dirVec, xL); ProjectVector(vec);
if (vec[i] < sv || vec[i] == sv) break;
xR = xL; xL *= 2;
}
}
else
{
return 0.0f;
}
do
{
xM = 0.5f * (xL + xR);
vec.Mult(dirVec, xM);
ProjectVector(vec);
if (vec[i] > sv)
xR = xM;
else
xL = xM;
} while (TMath::Abs(vec[i] - sv) >= fgEps);
return xM;
}
Float_t TEveProjection::GetScreenVal(Int_t i, Float_t x)
{
TEveVector dv;
SetDirectionalVector(i, dv); dv = dv*x;
ProjectVector(dv);
return dv[i];
}
ClassImp(TEveRhoZProjection);
TEveRhoZProjection::TEveRhoZProjection(TEveVector& center) :
TEveProjection(center)
{
fType = kPT_RhoZ;
fName = "RhoZ";
}
void TEveRhoZProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
EPProc_e proc )
{
using namespace TMath;
if (proc == kPP_Plane || proc == kPP_Full)
{
y = Sign((Float_t)Sqrt(x*x+y*y), y);
x = z;
}
if (proc == kPP_Distort || proc == kPP_Full)
{
x -= fProjectedCenter.fX;
y -= fProjectedCenter.fY;
if (x > fFixZ)
x = fFixZ + fPastFixZScale*(x - fFixZ);
else if (x < -fFixZ)
x = -fFixZ + fPastFixZScale*(x + fFixZ);
else
x = x * fScaleZ / (1.0f + Abs(x)*fDistortion);
if (y > fFixR)
y = fFixR + fPastFixRScale*(y - fFixR);
else if (y < -fFixR)
y = -fFixR + fPastFixRScale*(y + fFixR);
else
y = y * fScaleR / (1.0f + Abs(y)*fDistortion);
x += fProjectedCenter.fX;
y += fProjectedCenter.fY;
}
z = 0.0f;
}
void TEveRhoZProjection::SetCenter(TEveVector& v)
{
fCenter = v;
Float_t r = TMath::Sqrt(v.fX*v.fX + v.fY*v.fY);
fProjectedCenter.fX = fCenter.fZ;
fProjectedCenter.fY = TMath::Sign(r, fCenter.fY);
fProjectedCenter.fZ = 0;
UpdateLimit();
}
void TEveRhoZProjection::UpdateLimit()
{
if (fDistortion == 0.0f)
return;
Float_t limR = 1.0f/fDistortion + fFixR;
Float_t limZ = 1.0f/fDistortion + fFixZ;
Float_t *c = GetProjectedCenter();
fUpLimit .Set( limZ + c[0], limR + c[1], c[2]);
fLowLimit.Set(-limZ + c[0], -limR + c[1], c[2]);
}
void TEveRhoZProjection::SetDirectionalVector(Int_t screenAxis, TEveVector& vec)
{
if (screenAxis == 0)
vec.Set(0.0f, 0.0f, 1.0f);
else if (screenAxis == 1)
vec.Set(0.0f, 1.0f, 0.0f);
}
Bool_t TEveRhoZProjection::AcceptSegment(TEveVector& v1, TEveVector& v2,
Float_t tolerance)
{
Float_t a = fProjectedCenter.fY;
Bool_t val = kTRUE;
if ((v1.fY < a && v2.fY > a) || (v1.fY > a && v2.fY < a))
{
val = kFALSE;
if (tolerance > 0)
{
Float_t a1 = TMath::Abs(v1.fY - a), a2 = TMath::Abs(v2.fY - a);
if (a1 < a2)
{
if (a1 < tolerance) { v1.fY = a; val = kTRUE; }
}
else
{
if (a2 < tolerance) { v2.fY = a; val = kTRUE; }
}
}
}
return val;
}
ClassImp(TEveRPhiProjection);
TEveRPhiProjection::TEveRPhiProjection(TEveVector& center) :
TEveProjection(center)
{
fType = kPT_RPhi;
fGeoMode = kGM_Polygons;
fName = "RhoPhi";
}
void TEveRPhiProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
EPProc_e proc)
{
using namespace TMath;
if (proc != kPP_Plane)
{
x -= fCenter.fX;
y -= fCenter.fY;
Float_t phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
Float_t r = Sqrt(x*x + y*y);
if (r > fFixR)
r = fFixR + fPastFixRScale*(r - fFixR);
else if (r < -fFixR)
r = -fFixR + fPastFixRScale*(r + fFixR);
else
r = r * fScaleR / (1.0f + r*fDistortion);
x = r*Cos(phi) + fCenter.fX;
y = r*Sin(phi) + fCenter.fY;
}
z = 0.0f;
}
Last change: Tue May 13 17:09:45 2008
Last generated: 2008-05-13 17:09
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.