#include "TEveJetCone.h"
#include "TEveTrans.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TVirtualPad.h"
#include "TVirtualViewer3D.h"
#include "TMath.h"
ClassImp(TEveJetCone);
TEveJetCone::TEveJetCone(const Text_t* n, const Text_t* t) :
TEveElementList(n, t, kTRUE),
TAttBBox(),
fApex( TEveVector(0.,0.,0.) ),
fBasePoints(),
fCylinderBorder( TEveVector(-1.,0.,-1.) ),
fThetaC(0.)
{
fColor = kGreen;
}
void TEveJetCone::ComputeBBox()
{
BBoxInit();
BBoxCheckPoint(fApex);
for (vTEveVector_ci i = fBasePoints.begin(); i != fBasePoints.end(); ++i)
{
BBoxCheckPoint(*i);
}
}
void TEveJetCone::Paint(Option_t*)
{
static const TEveException eh("TEveJetCone::Paint ");
if (fRnrSelf == kFALSE) return;
TBuffer3D buff(TBuffer3DTypes::kGeneric);
buff.fID = this;
buff.fColor = GetMainColor();
buff.fTransparency = GetMainTransparency();
if (HasMainTrans())
RefMainTrans().SetBuffer3D(buff);
buff.SetSectionsValid(TBuffer3D::kCore);
Int_t reqSections = gPad->GetViewer3D()->AddObject(buff);
if (reqSections != TBuffer3D::kNone)
Error(eh, "only direct GL rendering supported.");
}
Int_t TEveJetCone::AddCone(Float_t eta, Float_t phi, Float_t coneRadius, Float_t height )
{
if ( fCylinderBorder.fZ == -1. && fCylinderBorder.fX == -1. && height == -1 )
return -1;
TEveVector coneAxis;
FillTEveVectorFromEtaPhi( coneAxis, eta, phi );
Float_t angleRad = 0.;
for ( Float_t angle = 0.; angle < 360. ; angle+=5. , angleRad=angle*TMath::Pi()/180 ) {
TEveVector contourPoint;
FillTEveVectorFromEtaPhi( contourPoint,
eta + coneRadius * TMath::Cos(angleRad),
phi + coneRadius * TMath::Sin(angleRad) );
if ( fCylinderBorder.fZ != -1. && fCylinderBorder.fX != -1. ) {
if ( contourPoint.Theta() < fThetaC )
contourPoint *= fCylinderBorder.fZ / TMath::Cos( contourPoint.Theta() ) ;
else if ( contourPoint.Theta() > ( TMath::Pi() - fThetaC ) )
contourPoint *= fCylinderBorder.fZ / TMath::Cos( contourPoint.Theta() - TMath::Pi() ) ;
else
contourPoint *= fCylinderBorder.fX / TMath::Sin( contourPoint.Theta() ) ;
if ( height != -1 ) contourPoint *= height;
}
else {
contourPoint *= height / GetArcCosConeOpeningAngle( coneAxis, contourPoint );
}
fBasePoints.push_back( contourPoint );
}
return 0;
}
Int_t TEveJetCone::AddEllipticCone(Float_t eta, Float_t phi, Float_t reta, Float_t rphi, Float_t height)
{
if ( fCylinderBorder.fZ == -1. && fCylinderBorder.fX == -1. && height == -1 )
return -1;
TEveVector coneAxis;
FillTEveVectorFromEtaPhi( coneAxis, eta, phi );
Float_t angleRad = 0.;
for ( Float_t angle = 0.; angle < 360. ; angle+=5. , angleRad=angle*TMath::Pi()/180 ) {
TEveVector contourPoint;
FillTEveVectorFromEtaPhi( contourPoint,
eta + reta * TMath::Cos(angleRad),
phi + rphi * TMath::Sin(angleRad) );
if ( fCylinderBorder.fZ != -1. && fCylinderBorder.fX != -1. ) {
if ( contourPoint.Theta() < fThetaC )
contourPoint *= fCylinderBorder.fZ / TMath::Cos( contourPoint.Theta() ) ;
else if ( contourPoint.Theta() > ( TMath::Pi() - fThetaC ) )
contourPoint *= fCylinderBorder.fZ / TMath::Cos( contourPoint.Theta() - TMath::Pi() ) ;
else
contourPoint *= fCylinderBorder.fX / TMath::Sin( contourPoint.Theta() ) ;
if ( height != -1 ) contourPoint *= height;
}
else {
contourPoint *= height / GetArcCosConeOpeningAngle( coneAxis, contourPoint );
}
fBasePoints.push_back( contourPoint );
}
return 0;
}
void TEveJetCone::FillTEveVectorFromEtaPhi( TEveVector &vec, const Float_t& eta, const Float_t& phi )
{
vec.Set( TMath::Cos(phi) / TMath::CosH(eta),
TMath::Sin(phi) / TMath::CosH(eta),
TMath::TanH(eta) );
return;
}
Float_t TEveJetCone::GetArcCosConeOpeningAngle( const TEveVector& axis, const TEveVector& contour )
{
Float_t arcCos = 0.;
Float_t tot2 = axis.Mag2() * contour.Mag2();
if( tot2 > 0. ) {
arcCos = axis.Dot( contour )/ TMath::Sqrt( tot2 );
if (arcCos > 1.0) arcCos = 1.0;
if (arcCos < -1.0) arcCos = -1.0;
}
return arcCos;
}