```// @(#)root/geom:\$Id: TGeoHype.cxx 27731 2009-03-09 17:40:56Z brun \$
// Author: Mihaela Gheata   20/11/04

/*************************************************************************
*                                                                       *
* For the licensing terms see \$ROOTSYS/LICENSE.                         *
* For the list of contributors see \$ROOTSYS/README/CREDITS.             *
*************************************************************************/

#include "Riostream.h"

#include "TGeoManager.h"
#include "TGeoVolume.h"
#include "TVirtualGeoPainter.h"
#include "TGeoHype.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TMath.h"

//_____________________________________________________________________________
// TGeoHype - Hyperboloid class defined by 5 parameters. Bounded by:
//            - Two z planes at z=+/-dz
//            - Inner and outer lateral surfaces. These represent the surfaces
//              described by the revolution of 2 hyperbolas about the Z axis:
//               r^2 - (t*z)^2 = a^2
//
//            r = distance between hyperbola and Z axis at coordinate z
//            t = tangent of the stereo angle (angle made by hyperbola
//                asimptotic lines and Z axis). t=0 means cylindrical surface.
//            a = distance between hyperbola and Z axis at z=0
//
//          The inner hyperbolic surface is described by:
//              r^2 - (tin*z)^2 = rin^2
//           - absence of the inner surface (filled hyperboloid can be forced
//             by rin=0 and sin=0
//          The outer hyperbolic surface is described by:
//              r^2 - (tout*z)^2 = rout^2
//  TGeoHype parameters: dz[cm], rin[cm], sin[deg], rout[cm], sout[deg].
//    MANDATORY conditions:
//           - rin < rout
//           - rout > 0
//           - rin^2 + (tin*dz)^2 > rout^2 + (tout*dz)^2
//    SUPPORTED CASES:
//           - rin = 0, tin != 0     => inner surface conical
//           - tin=0 AND/OR tout=0   => corresponding surface(s) cyllindrical
//             e.g. tin=0 AND tout=0 => shape becomes a tube with: rmin,rmax,dz
//
//_____________________________________________________________________________

ClassImp(TGeoHype)

//_____________________________________________________________________________
TGeoHype::TGeoHype()
{
// Default constructor
SetShapeBit(TGeoShape::kGeoHype);
fStIn = 0.;
fStOut = 0.;
fTin = 0.;
fTinsq = 0.;
fTout = 0.;
fToutsq = 0.;
}

//_____________________________________________________________________________
TGeoHype::TGeoHype(Double_t rin, Double_t stin, Double_t rout, Double_t stout, Double_t dz)
:TGeoTube(rin, rout, dz)
{
// Constructor specifying hyperboloid parameters.
SetShapeBit(TGeoShape::kGeoHype);
SetHypeDimensions(rin, stin, rout, stout, dz);
// dz<0 can be used to force dz of hyperboloid fit the container volume
if (fDz<0) SetShapeBit(kGeoRunTimeShape);
ComputeBBox();
}
//_____________________________________________________________________________
TGeoHype::TGeoHype(const char *name,Double_t rin, Double_t stin, Double_t rout, Double_t stout, Double_t dz)
:TGeoTube(name, rin, rout, dz)
{
// Constructor specifying parameters and name.
SetShapeBit(TGeoShape::kGeoHype);
SetHypeDimensions(rin, stin, rout, stout, dz);
// dz<0 can be used to force dz of hyperboloid fit the container volume
if (fDz<0) SetShapeBit(kGeoRunTimeShape);
ComputeBBox();
}

//_____________________________________________________________________________
TGeoHype::TGeoHype(Double_t *param)
:TGeoTube(param[1],param[3],param[0])
{
// Default constructor specifying a list of parameters
// param[0] = dz
// param[1] = rin
// param[2] = stin
// param[3] = rout
// param[4] = stout
SetShapeBit(TGeoShape::kGeoHype);
SetDimensions(param);
// dz<0 can be used to force dz of hyperboloid fit the container volume
if (fDz<0) SetShapeBit(kGeoRunTimeShape);
ComputeBBox();
}

//_____________________________________________________________________________
TGeoHype::~TGeoHype()
{
// destructor
}

//_____________________________________________________________________________
Double_t TGeoHype::Capacity() const
{
// Computes capacity of the shape in [length^3]
Double_t capacity = 2.*TMath::Pi()*fDz*(fRmax*fRmax-fRmin*fRmin) +
(2.*TMath::Pi()/3.)*fDz*fDz*fDz*(fToutsq-fTinsq);
return capacity;
}

//_____________________________________________________________________________
void TGeoHype::ComputeBBox()
{
// Compute bounding box of the hyperboloid
if (fRmin<0.) {
Warning("ComputeBBox", "Shape %s has invalid rmin=%g ! SET TO 0.", fRmin);
fRmin = 0.;
}
if ((fRmin>fRmax) || (fRmin*fRmin+fTinsq*fDz*fDz > fRmax*fRmax+fToutsq*fDz*fDz)) {
SetShapeBit(kGeoInvalidShape);
Error("ComputeBBox", "Shape %s hyperbolic surfaces are malformed: rin=%g, stin=%g, rout=%g, stout=%g",
GetName(), fRmin, fStIn, fRmax, fStOut);
return;
}

fDX = fDY = TMath::Sqrt(RadiusHypeSq(fDz, kFALSE));
fDZ = fDz;
}

//_____________________________________________________________________________
void TGeoHype::ComputeNormal(Double_t *point, Double_t *dir, Double_t *norm)
{
// Compute normal to closest surface from POINT.
Double_t saf[3];
Double_t rsq = point[0]*point[0]+point[1]*point[1];
Double_t r = TMath::Sqrt(rsq);
saf[0] = TMath::Abs(fDz-TMath::Abs(point[2]));
saf[1] = (HasInner())?TMath::Abs(rin-r):TGeoShape::Big();
saf[2] = TMath::Abs(rout-r);
Int_t i = TMath::LocMin(3,saf);
if (i==0 || r<1.E-10) {
norm[0] = norm[1] = 0.;
norm[2] = TMath::Sign(1.,dir[2]);
return;
}
Double_t t = (i==1)?fTinsq:fToutsq;;
t *= -point[2]/r;
Double_t ct = TMath::Sqrt(1./(1.+t*t));
Double_t st = t * ct;
Double_t phi = TMath::ATan2(point[1], point[0]);
Double_t cphi = TMath::Cos(phi);
Double_t sphi = TMath::Sin(phi);

norm[0] = ct*cphi;
norm[1] = ct*sphi;
norm[2] = st;
if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
norm[0] = -norm[0];
norm[1] = -norm[1];
norm[2] = -norm[2];
}
}

//_____________________________________________________________________________
Bool_t TGeoHype::Contains(Double_t *point) const
{
// test if point is inside this tube
if (TMath::Abs(point[2]) > fDz) return kFALSE;
Double_t r2 = point[0]*point[0]+point[1]*point[1];
if (r2>routsq) return kFALSE;
if (!HasInner()) return kTRUE;
if (r2<rinsq) return kFALSE;
return kTRUE;
}

//_____________________________________________________________________________
Int_t TGeoHype::DistancetoPrimitive(Int_t px, Int_t py)
{
// compute closest distance from point px,py to each corner
Int_t numPoints = GetNmeshVertices();
return ShapeDistancetoPrimitive(numPoints, px, py);
}

//_____________________________________________________________________________
Double_t TGeoHype::DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
{
// Compute distance from inside point to surface of the hyperboloid.
if (iact<3 && safe) {
*safe = Safety(point, kTRUE);
if (iact==0) return TGeoShape::Big();
if ((iact==1) && (*safe>step)) return TGeoShape::Big();
}
// compute distance to surface
// Do Z
Double_t sz = TGeoShape::Big();
if (dir[2]>0) {
sz = (fDz-point[2])/dir[2];
if (sz<=0.) return 0.;
} else {
if (dir[2]<0) {
sz = -(fDz+point[2])/dir[2];
if (sz<=0.) return 0.;
}
}

// Do R
Double_t srin = TGeoShape::Big();
Double_t srout = TGeoShape::Big();
Double_t sr;
// inner and outer surfaces
Double_t s[2];
Int_t npos;
npos = DistToHype(point, dir, s, kTRUE);
if (npos) srin = s[0];
npos = DistToHype(point, dir, s, kFALSE);
if (npos) srout = s[0];
sr = TMath::Min(srin, srout);
return TMath::Min(sz,sr);
}

//_____________________________________________________________________________
Double_t TGeoHype::DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
{
// compute distance from outside point to surface of the hyperboloid.
if (iact<3 && safe) {
*safe = Safety(point, kFALSE);
if (iact==0) return TGeoShape::Big();
if ((iact==1) && (step<=*safe)) return TGeoShape::Big();
}
// Check if the bounding box is crossed within the requested distance
Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
if (sdist>=step) return TGeoShape::Big();
// find distance to shape
// Do Z
Double_t xi, yi, zi;
Double_t sz = TGeoShape::Big();
if (TMath::Abs(point[2])>=fDz) {
// We might find Z plane crossing
if ((point[2]*dir[2]) < 0) {
// Compute distance to Z (always positive)
sz = (TMath::Abs(point[2])-fDz)/TMath::Abs(dir[2]);
// Extrapolate
xi = point[0]+sz*dir[0];
yi = point[1]+sz*dir[1];
Double_t r2 = xi*xi + yi*yi;
if (r2 >= rmin2) {
if (r2 <= rmax2) return sz;
}
}
}
// We do not cross Z planes.
Double_t sin = TGeoShape::Big();
Double_t sout = TGeoShape::Big();
Double_t s[2];
Int_t npos;
npos = DistToHype(point, dir, s, kTRUE);
if (npos) {
zi = point[2] + s[0]*dir[2];
if (TMath::Abs(zi) <= fDz) sin = s[0];
else if (npos==2) {
zi = point[2] + s[1]*dir[2];
if (TMath::Abs(zi) <= fDz) sin = s[1];
}
}
npos = DistToHype(point, dir, s, kFALSE);
if (npos) {
zi = point[2] + s[0]*dir[2];
if (TMath::Abs(zi) <= fDz) sout = s[0];
else if (npos==2) {
zi = point[2] + s[1]*dir[2];
if (TMath::Abs(zi) <= fDz) sout = s[1];
}
}
return TMath::Min(sin, sout);
}

//_____________________________________________________________________________
Int_t TGeoHype::DistToHype(Double_t *point, Double_t *dir, Double_t *s, Bool_t inner) const
{
// Compute distance from an arbitrary point to inner/outer surface of hyperboloid.
// Returns number of positive solutions. S[2] contains the solutions.
Double_t r0, t0, snext;
if (inner) {
if (!HasInner()) return 0;
r0 = fRmin;
t0 = fTinsq;
} else {
r0 = fRmax;
t0 = fToutsq;
}
Double_t a = dir[0]*dir[0] + dir[1]*dir[1] - t0*dir[2]*dir[2];
Double_t b = t0*point[2]*dir[2] - point[0]*dir[0] - point[1]*dir[1];
Double_t c = point[0]*point[0] + point[1]*point[1] - t0*point[2]*point[2] - r0*r0;

if (TMath::Abs(a) < TGeoShape::Tolerance()) {
if (TMath::Abs(b) < TGeoShape::Tolerance()) return 0;
snext = 0.5*c/b;
if (snext < 0.) return 0;
s[0] = snext;
return 1;
}

Double_t delta = b*b - a*c;
Double_t ainv = 1./a;
Int_t npos = 0;
if (delta < 0.) return 0;
delta = TMath::Sqrt(delta);
Double_t sone = TMath::Sign(1.,ainv);
snext = (b - sone*delta)*ainv;
if (snext >= 0.) s[npos++] = snext;
snext = (b + sone*delta)*ainv;
if (snext >= 0.) s[npos++] = snext;
return npos;
}

//_____________________________________________________________________________
TGeoVolume *TGeoHype::Divide(TGeoVolume * /*voldiv*/, const char *divname, Int_t /*iaxis*/, Int_t /*ndiv*/,
Double_t /*start*/, Double_t /*step*/)
{
// Cannot divide hyperboloids.
Error("Divide", "Hyperboloids cannot be divided. Division volume %s not created", divname);
return 0;
}

//_____________________________________________________________________________
Double_t TGeoHype::GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
{
// Get range of shape for a given axis.
xlo = 0;
xhi = 0;
Double_t dx = 0;
switch (iaxis) {
case 1: // R
xlo = fRmin;
dx = xhi-xlo;
return dx;
case 2: // Phi
xlo = 0;
xhi = 360;
dx = 360;
return dx;
case 3: // Z
xlo = -fDz;
xhi = fDz;
dx = xhi-xlo;
return dx;
}
return dx;
}

//_____________________________________________________________________________
void TGeoHype::GetBoundingCylinder(Double_t *param) const
{
//--- Fill vector param[4] with the bounding cylinder parameters. The order
// is the following : Rmin, Rmax, Phi1, Phi2, dZ
param[0] = fRmin; // Rmin
param[0] *= param[0];
param[1] = TMath::Sqrt(RadiusHypeSq(fDz, kFALSE)); // Rmax
param[1] *= param[1];
param[2] = 0.;    // Phi1
param[3] = 360.;  // Phi1
}

//_____________________________________________________________________________
TGeoShape *TGeoHype::GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix * /*mat*/) const
{
// in case shape has some negative parameters, these has to be computed
// in order to fit the mother
if (!TestShapeBit(kGeoRunTimeShape)) return 0;
Double_t rmin, rmax, dz;
Double_t zmin,zmax;
rmin = fRmin;
rmax = fRmax;
dz = fDz;
if (fDz<0) {
mother->GetAxisRange(3,zmin,zmax);
if (zmax<0) return 0;
dz=zmax;
} else {
Error("GetMakeRuntimeShape", "Shape %s does not have negative Z range", GetName());
return 0;
}
TGeoShape *hype = new TGeoHype(GetName(), dz, fRmax, fStOut, fRmin, fStIn);
return hype;
}

//_____________________________________________________________________________
void TGeoHype::InspectShape() const
{
// print shape parameters
printf("*** Shape %s: TGeoHype ***\n", GetName());
printf("    Rin  = %11.5f\n", fRmin);
printf("    sin  = %11.5f\n", fStIn);
printf("    Rout = %11.5f\n", fRmax);
printf("    sout = %11.5f\n", fStOut);
printf("    dz   = %11.5f\n", fDz);

printf(" Bounding box:\n");
TGeoBBox::InspectShape();
}

//_____________________________________________________________________________
TBuffer3D *TGeoHype::MakeBuffer3D() const
{
// Creates a TBuffer3D describing *this* shape.
// Coordinates are in local reference frame.

Int_t n = gGeoManager->GetNsegments();
Bool_t hasRmin = HasInner();
Int_t nbPnts = (hasRmin)?(2*n*n):(n*n+2);
Int_t nbSegs = (hasRmin)?(4*n*n):(n*(2*n+1));
Int_t nbPols = (hasRmin)?(2*n*n):(n*(n+1));

TBuffer3D* buff = new TBuffer3D(TBuffer3DTypes::kGeneric,
nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols);
if (buff)
{
SetPoints(buff->fPnts);
SetSegsAndPols(*buff);
}

return buff;
}

//_____________________________________________________________________________
void TGeoHype::SetSegsAndPols(TBuffer3D &buff) const
{
// Fill TBuffer3D structure for segments and polygons.
Int_t c = GetBasicColor();
Int_t i, j, n;
n = gGeoManager->GetNsegments();
Bool_t hasRmin = HasInner();
Int_t irin = 0;
Int_t irout = (hasRmin)?(n*n):2;
// Fill segments
// Case hasRmin:
//   Inner circles:  [isin = 0], n (per circle) * n ( circles)
//        iseg = isin+n*i+j , i = 0, n-1   , j = 0, n-1
//        seg(i=1,n; j=1,n) = [irin+n*i+j] and [irin+n*i+(j+1)%n]
//   Inner generators: [isgenin = isin+n*n], n (per circle) *(n-1) (slices)
//        iseg = isgenin + i*n + j, i=0,n-2,  j=0,n-1
//        seg(i,j) = [irin+n*i+j] and [irin+n*(i+1)+j]
//   Outer circles:  [isout = isgenin+n*(n-1)], n (per circle) * n ( circles)
//        iseg = isout + i*n + j , iz = 0, n-1   , j = 0, n-1
//        seg(i=1,n; j=1,n) = [irout+n*i+j] and [irout+n*i+(j+1)%n]
//   Outer generators: [isgenout = isout+n*n], n (per circle) *(n-1) (slices)
//        iseg = isgenout + i*n + j, i=0,n-2,  j=0,n-1
//        seg(i,j) = [irout+n*i+j] and [irout+n*(i+1)+j]
//   Lower cap : [islow = isgenout + n*(n-1)], n radial segments
//        iseg = islow + j,  j=0,n-1
//        seg(j) = [irin + j] and [irout+j]
//   Upper cap: [ishi = islow + n], nradial segments
//        iseg = ishi + j, j=0,n-1
//        seg[j] = [irin + n*(n-1) + j] and [irout+n*(n-1) + j]
//
// Case !hasRmin:
//   Outer circles: [isout=0], same outer circles (n*n)
// Outer generators: isgenout = isout + n*n
//   Lower cap: [islow = isgenout+n*(n-1)], n seg.
//        iseg = islow + j, j=0,n-1
//        seg[j] = [irin] and [irout+j]
//   Upper cap: [ishi = islow +n]
//        iseg = ishi + j, j=0,n-1
//        seg[j] = [irin+1] and [irout+n*(n-1) + j]

Int_t isin = 0;
Int_t isgenin = (hasRmin)?(isin+n*n):0;
Int_t isout = (hasRmin)?(isgenin+n*(n-1)):0;
Int_t isgenout  = isout+n*n;
Int_t islo = isgenout+n*(n-1);
Int_t ishi = islo + n;

Int_t npt = 0;
// Fill inner circle segments (n*n)
if (hasRmin) {
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
npt = 3*(isin+n*i+j);
buff.fSegs[npt]   = c;
buff.fSegs[npt+1] = irin+n*i+j;
buff.fSegs[npt+2] = irin+n*i+((j+1)%n);
}
}
// Fill inner generators (n*(n-1))
for (i=0; i<n-1; i++) {
for (j=0; j<n; j++) {
npt = 3*(isgenin+n*i+j);
buff.fSegs[npt]   = c;
buff.fSegs[npt+1] = irin+n*i+j;
buff.fSegs[npt+2] = irin+n*(i+1)+j;
}
}
}
// Fill outer circle segments (n*n)
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
npt = 3*(isout + n*i+j);
buff.fSegs[npt]   = c;
buff.fSegs[npt+1] = irout+n*i+j;
buff.fSegs[npt+2] = irout+n*i+((j+1)%n);
}
}
// Fill outer generators (n*(n-1))
for (i=0; i<n-1; i++) {
for (j=0; j<n; j++) {
npt = 3*(isgenout+n*i+j);
buff.fSegs[npt]   = c;
buff.fSegs[npt+1] = irout+n*i+j;
buff.fSegs[npt+2] = irout+n*(i+1)+j;
}
}
// Fill lower cap (n)
for (j=0; j<n; j++) {
npt = 3*(islo+j);
buff.fSegs[npt]   = c;
buff.fSegs[npt+1] = irin;
if (hasRmin) buff.fSegs[npt+1] += j;
buff.fSegs[npt+2] = irout + j;
}
// Fill upper cap (n)
for (j=0; j<n; j++) {
npt = 3*(ishi+j);
buff.fSegs[npt]   = c;
buff.fSegs[npt+1] = irin+1;
if (hasRmin) buff.fSegs[npt+1] += n*(n-1)+j-1;
buff.fSegs[npt+2] = irout + n*(n-1)+j;
}

// Fill polygons
// Inner polygons: [ipin = 0] (n-1) slices * n (edges)
//   ipoly = ipin + n*i + j;  i=0,n-2   j=0,n-1
//   poly[i,j] = [isin+n*i+j]  [isgenin+i*n+(j+1)%n]  [isin+n*(i+1)+j]  [isgenin+i*n+j]
// Outer polygons: [ipout = ipin+n*(n-1)]  also (n-1)*n
//   ipoly = ipout + n*i + j; i=0,n-2   j=0,n-1
//   poly[i,j] = [isout+n*i+j]  [isgenout+i*n+j]  [isout+n*(i+1)+j]  [isgenout+i*n+(j+1)%n]
// Lower cap: [iplow = ipout+n*(n-1):  n polygons
//   ipoly = iplow + j;  j=0,n-1
//   poly[i=0,j] = [isin+j] [islow+j] [isout+j] [islow+(j+1)%n]
// Upper cap: [ipup = iplow+n] : n polygons
//   ipoly = ipup + j;  j=0,n-1
//   poly[i=n-1, j] = [isin+n*(n-1)+j] [ishi+(j+1)%n] [isout+n*(n-1)+j] [ishi+j]
//
// Case !hasRmin:
// ipin = 0 no inner polygons
// ipout = 0 same outer polygons
// Lower cap: iplow = ipout+n*(n-1):  n polygons with 3 segments
//   poly[i=0,j] = [isout+j] [islow+(j+1)%n] [islow+j]
// Upper cap: ipup = iplow+n;
//   poly[i=n-1,j] = [isout+n*(n-1)+j] [ishi+j] [ishi+(j+1)%n]

Int_t ipin = 0;
Int_t ipout = (hasRmin)?(ipin+n*(n-1)):0;
Int_t iplo = ipout+n*(n-1);
Int_t ipup = iplo+n;
// Inner polygons n*(n-1)
if (hasRmin) {
for (i=0; i<n-1; i++) {
for (j=0; j<n; j++) {
npt = 6*(ipin+n*i+j);
buff.fPols[npt]   = c;
buff.fPols[npt+1] = 4;
buff.fPols[npt+2] = isin+n*i+j;
buff.fPols[npt+3] = isgenin+i*n+((j+1)%n);
buff.fPols[npt+4] = isin+n*(i+1)+j;
buff.fPols[npt+5] = isgenin+i*n+j;
}
}
}
// Outer polygons n*(n-1)
for (i=0; i<n-1; i++) {
for (j=0; j<n; j++) {
npt = 6*(ipout+n*i+j);
buff.fPols[npt]   = c;
buff.fPols[npt+1] = 4;
buff.fPols[npt+2] = isout+n*i+j;
buff.fPols[npt+3] = isgenout+i*n+j;
buff.fPols[npt+4] = isout+n*(i+1)+j;
buff.fPols[npt+5] = isgenout+i*n+((j+1)%n);
}
}
// End caps
if (hasRmin) {
for (j=0; j<n; j++) {
npt = 6*(iplo+j);
buff.fPols[npt]   = c+1;
buff.fPols[npt+1] = 4;
buff.fPols[npt+2] = isin+j;
buff.fPols[npt+3] = islo+j;
buff.fPols[npt+4] = isout+j;
buff.fPols[npt+5] = islo+((j+1)%n);
}
for (j=0; j<n; j++) {
npt = 6*(ipup+j);
buff.fPols[npt]   = c+2;
buff.fPols[npt+1] = 4;
buff.fPols[npt+2] = isin+n*(n-1)+j;
buff.fPols[npt+3] = ishi+((j+1)%n);
buff.fPols[npt+4] = isout+n*(n-1)+j;
buff.fPols[npt+5] = ishi+j;
}
} else {
for (j=0; j<n; j++) {
npt = 6*iplo+5*j;
buff.fPols[npt]   = c+1;
buff.fPols[npt+1] = 3;
buff.fPols[npt+2] = isout+j;
buff.fPols[npt+3] = islo+((j+1)%n);
buff.fPols[npt+4] = islo+j;
}
for (j=0; j<n; j++) {
npt = 6*iplo+5*(n+j);
buff.fPols[npt]   = c+2;
buff.fPols[npt+1] = 3;
buff.fPols[npt+2] = isout+n*(n-1)+j;
buff.fPols[npt+3] = ishi+j;
buff.fPols[npt+4] = ishi+((j+1)%n);
}
}
}

//_____________________________________________________________________________
Double_t TGeoHype::RadiusHypeSq(Double_t z, Bool_t inner) const
{
// Compute r^2 = x^2 + y^2 at a given z coordinate, for either inner or outer hyperbolas.
Double_t r0, tsq;
if (inner) {
r0 = fRmin;
tsq = fTinsq;
} else {
r0 = fRmax;
tsq = fToutsq;
}
return (r0*r0+tsq*z*z);
}

//_____________________________________________________________________________
Double_t TGeoHype::ZHypeSq(Double_t r, Bool_t inner) const
{
// Compute z^2 at a given  r^2, for either inner or outer hyperbolas.
Double_t r0, tsq;
if (inner) {
r0 = fRmin;
tsq = fTinsq;
} else {
r0 = fRmax;
tsq = fToutsq;
}
if (TMath::Abs(tsq) < TGeoShape::Tolerance()) return TGeoShape::Big();
return ((r*r-r0*r0)/tsq);
}

//_____________________________________________________________________________
Double_t TGeoHype::Safety(Double_t *point, Bool_t in) const
{
// computes the closest distance from given point to this shape, according
// to option. The matching point on the shape is stored in spoint.
Double_t safe, safrmin, safrmax;
if (in) {
safe    = fDz-TMath::Abs(point[2]);
safrmin = SafetyToHype(point, kTRUE, in);
if (safrmin < safe) safe = safrmin;
safrmax = SafetyToHype(point, kFALSE,in);
if (safrmax < safe) safe = safrmax;
} else {
safe    = -fDz+TMath::Abs(point[2]);
safrmin = SafetyToHype(point, kTRUE, in);
if (safrmin > safe) safe = safrmin;
safrmax = SafetyToHype(point, kFALSE,in);
if (safrmax > safe) safe = safrmax;
}
return safe;
}

//_____________________________________________________________________________
Double_t TGeoHype::SafetyToHype(Double_t *point, Bool_t inner, Bool_t in) const
{
// Compute an underestimate of the closest distance from a point to inner or
// outer infinite hyperbolas.
Double_t r, rsq, rhsq, rh, dr, tsq, saf;
if (inner && !HasInner()) return (in)?TGeoShape::Big():-TGeoShape::Big();
rsq = point[0]*point[0]+point[1]*point[1];
r = TMath::Sqrt(rsq);
rh = TMath::Sqrt(rhsq);
dr = r - rh;
if (inner) {
if (!in && dr>0) return -TGeoShape::Big();
if (TMath::Abs(fStIn) < TGeoShape::Tolerance()) return TMath::Abs(dr);
if (fRmin<TGeoShape::Tolerance()) return TMath::Abs(dr/TMath::Sqrt(1.+ fTinsq));
tsq = fTinsq;
} else {
if (!in && dr<0) return -TGeoShape::Big();
if (TMath::Abs(fStOut) < TGeoShape::Tolerance()) return TMath::Abs(dr);
tsq = fToutsq;
}
if (TMath::Abs(dr)<TGeoShape::Tolerance()) return 0.;
// 1. dr<0 => approximate safety with distance to tangent to hyperbola in z = |point[2]|
Double_t m;
if (dr<0) {
m = rh/(tsq*TMath::Abs(point[2]));
saf = -m*dr/TMath::Sqrt(1.+m*m);
return saf;
}
// 2. dr>0 => approximate safety with distance from point to segment P1(r(z0),z0) and P2(r0, z(r0))
m = (TMath::Sqrt(ZHypeSq(r,inner)) - TMath::Abs(point[2]))/dr;
saf = m*dr/TMath::Sqrt(1.+m*m);
return saf;
}

//_____________________________________________________________________________
void TGeoHype::SavePrimitive(ostream &out, Option_t * /*option*/ /*= ""*/)
{
// Save a primitive as a C++ statement(s) on output stream "out".
if (TObject::TestBit(kGeoSavePrimitive)) return;
out << "   // Shape: " << GetName() << " type: " << ClassName() << endl;
out << "   rin   = " << fRmin << ";" << endl;
out << "   stin  = " << fStIn << ";" << endl;
out << "   rout  = " << fRmax << ";" << endl;
out << "   stout = " << fStOut << ";" << endl;
out << "   dz    = " << fDz << ";" << endl;
out << "   TGeoShape *" << GetPointerName() << " = new TGeoHype(\"" << GetName() << "\",rin,stin,rout,stout,dz);" << endl;
TObject::SetBit(TGeoShape::kGeoSavePrimitive);
}

//_____________________________________________________________________________
void TGeoHype::SetHypeDimensions(Double_t rin, Double_t stin, Double_t rout, Double_t stout, Double_t dz)
{
// Set dimensions of the hyperboloid.
fRmin = rin;
fRmax = rout;
fDz   = dz;
fStIn = stin;
fStOut = stout;
fTinsq = fTin*fTin;
fToutsq = fTout*fTout;
if ((fRmin==0) && (fStIn==0)) SetShapeBit(kGeoRSeg, kTRUE);
else                          SetShapeBit(kGeoRSeg, kFALSE);
}

//_____________________________________________________________________________
void TGeoHype::SetDimensions(Double_t *param)
{
// Set dimensions of the hyperboloid starting from an array.
// param[0] = dz
// param[1] = rin
// param[2] = stin
// param[3] = rout
// param[4] = stout
Double_t dz = param[0];
Double_t rin = param[1];
Double_t stin = param[2];
Double_t rout = param[3];
Double_t stout = param[4];
SetHypeDimensions(rin, stin, rout, stout, dz);
}

//_____________________________________________________________________________
void TGeoHype::SetPoints(Double_t *points) const
{
// create tube mesh points
Double_t z,dz,r;
Int_t i,j, n;
if (!points) return;
n = gGeoManager->GetNsegments();
Double_t dphi = 360./n;
Double_t phi = 0;
dz = 2.*fDz/(n-1);

Int_t indx = 0;

if (HasInner()) {
// Inner surface points
for (i=0; i<n; i++) {
z = -fDz+i*dz;
for (j=0; j<n; j++) {
points[indx++] = r * TMath::Cos(phi);
points[indx++] = r * TMath::Sin(phi);
points[indx++] = z;
}
}
} else {
points[indx++] = 0.;
points[indx++] = 0.;
points[indx++] = -fDz;
points[indx++] = 0.;
points[indx++] = 0.;
points[indx++] = fDz;
}
// Outer surface points
for (i=0; i<n; i++) {
z = -fDz + i*dz;
for (j=0; j<n; j++) {
points[indx++] = r * TMath::Cos(phi);
points[indx++] = r * TMath::Sin(phi);
points[indx++] = z;
}
}
}

//_____________________________________________________________________________
void TGeoHype::SetPoints(Float_t *points) const
{
// create tube mesh points
Double_t z,dz,r;
Int_t i,j, n;
if (!points) return;
n = gGeoManager->GetNsegments();
Double_t dphi = 360./n;
Double_t phi = 0;
dz = 2.*fDz/(n-1);

Int_t indx = 0;

if (HasInner()) {
// Inner surface points
for (i=0; i<n; i++) {
z = -fDz+i*dz;
for (j=0; j<n; j++) {
points[indx++] = r * TMath::Cos(phi);
points[indx++] = r * TMath::Sin(phi);
points[indx++] = z;
}
}
} else {
points[indx++] = 0.;
points[indx++] = 0.;
points[indx++] = -fDz;
points[indx++] = 0.;
points[indx++] = 0.;
points[indx++] = fDz;
}
// Outer surface points
for (i=0; i<n; i++) {
z = -fDz + i*dz;
for (j=0; j<n; j++) {
points[indx++] = r * TMath::Cos(phi);
points[indx++] = r * TMath::Sin(phi);
points[indx++] = z;
}
}
}

//_____________________________________________________________________________
void TGeoHype::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
{
// Returns numbers of vertices, segments and polygons composing the shape mesh.
Int_t n = gGeoManager->GetNsegments();
Bool_t hasRmin = HasInner();
nvert = (hasRmin)?(2*n*n):(n*n+2);
nsegs = (hasRmin)?(4*n*n):(n*(2*n+1));
npols = (hasRmin)?(2*n*n):(n*(n+1));
}

//_____________________________________________________________________________
Int_t TGeoHype::GetNmeshVertices() const
{
// Return number of vertices of the mesh representation
Int_t n = gGeoManager->GetNsegments();
Int_t numPoints = (HasRmin())?(2*n*n):(n*n+2);
return numPoints;
}

//_____________________________________________________________________________
void TGeoHype::Sizeof3D() const
{
///// fill size of this 3-D object
///    TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
///    if (!painter) return;
///    Int_t n = gGeoManager->GetNsegments();
///    Int_t numPoints = n*4;
///    Int_t numSegs   = n*8;
///    Int_t numPolys  = n*4;
}

//_____________________________________________________________________________
const TBuffer3D & TGeoHype::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
{
// Fills a static 3D buffer and returns a reference.
static TBuffer3D buffer(TBuffer3DTypes::kGeneric);

TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);

if (reqSections & TBuffer3D::kRawSizes) {
Int_t n = gGeoManager->GetNsegments();
Bool_t hasRmin = HasInner();
Int_t nbPnts = (hasRmin)?(2*n*n):(n*n+2);
Int_t nbSegs = (hasRmin)?(4*n*n):(n*(2*n+1));
Int_t nbPols = (hasRmin)?(2*n*n):(n*(n+1));
if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
buffer.SetSectionsValid(TBuffer3D::kRawSizes);
}
}
if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
SetPoints(buffer.fPnts);
if (!buffer.fLocalFrame) {
TransformPoints(buffer.fPnts, buffer.NbPnts());
}

SetSegsAndPols(buffer);
buffer.SetSectionsValid(TBuffer3D::kRaw);
}

return buffer;
}
```
TGeoHype.cxx:1
TGeoHype.cxx:2
TGeoHype.cxx:3
TGeoHype.cxx:4
TGeoHype.cxx:5
TGeoHype.cxx:6
TGeoHype.cxx:7
TGeoHype.cxx:8
TGeoHype.cxx:9
TGeoHype.cxx:10
TGeoHype.cxx:11
TGeoHype.cxx:12
TGeoHype.cxx:13
TGeoHype.cxx:14
TGeoHype.cxx:15
TGeoHype.cxx:16
TGeoHype.cxx:17
TGeoHype.cxx:18
TGeoHype.cxx:19
TGeoHype.cxx:20
TGeoHype.cxx:21
TGeoHype.cxx:22
TGeoHype.cxx:23
TGeoHype.cxx:24
TGeoHype.cxx:25
TGeoHype.cxx:26
TGeoHype.cxx:27
TGeoHype.cxx:28
TGeoHype.cxx:29
TGeoHype.cxx:30
TGeoHype.cxx:31
TGeoHype.cxx:32
TGeoHype.cxx:33
TGeoHype.cxx:34
TGeoHype.cxx:35
TGeoHype.cxx:36
TGeoHype.cxx:37
TGeoHype.cxx:38
TGeoHype.cxx:39
TGeoHype.cxx:40
TGeoHype.cxx:41
TGeoHype.cxx:42
TGeoHype.cxx:43
TGeoHype.cxx:44
TGeoHype.cxx:45
TGeoHype.cxx:46
TGeoHype.cxx:47
TGeoHype.cxx:48
TGeoHype.cxx:49
TGeoHype.cxx:50
TGeoHype.cxx:51
TGeoHype.cxx:52
TGeoHype.cxx:53
TGeoHype.cxx:54
TGeoHype.cxx:55
TGeoHype.cxx:56
TGeoHype.cxx:57
TGeoHype.cxx:58
TGeoHype.cxx:59
TGeoHype.cxx:60
TGeoHype.cxx:61
TGeoHype.cxx:62
TGeoHype.cxx:63
TGeoHype.cxx:64
TGeoHype.cxx:65
TGeoHype.cxx:66
TGeoHype.cxx:67
TGeoHype.cxx:68
TGeoHype.cxx:69
TGeoHype.cxx:70
TGeoHype.cxx:71
TGeoHype.cxx:72
TGeoHype.cxx:73
TGeoHype.cxx:74
TGeoHype.cxx:75
TGeoHype.cxx:76
TGeoHype.cxx:77
TGeoHype.cxx:78
TGeoHype.cxx:79
TGeoHype.cxx:80
TGeoHype.cxx:81
TGeoHype.cxx:82
TGeoHype.cxx:83
TGeoHype.cxx:84
TGeoHype.cxx:85
TGeoHype.cxx:86
TGeoHype.cxx:87
TGeoHype.cxx:88
TGeoHype.cxx:89
TGeoHype.cxx:90
TGeoHype.cxx:91
TGeoHype.cxx:92
TGeoHype.cxx:93
TGeoHype.cxx:94
TGeoHype.cxx:95
TGeoHype.cxx:96
TGeoHype.cxx:97
TGeoHype.cxx:98
TGeoHype.cxx:99
TGeoHype.cxx:100
TGeoHype.cxx:101
TGeoHype.cxx:102
TGeoHype.cxx:103
TGeoHype.cxx:104
TGeoHype.cxx:105
TGeoHype.cxx:106
TGeoHype.cxx:107
TGeoHype.cxx:108
TGeoHype.cxx:109
TGeoHype.cxx:110
TGeoHype.cxx:111
TGeoHype.cxx:112
TGeoHype.cxx:113
TGeoHype.cxx:114
TGeoHype.cxx:115
TGeoHype.cxx:116
TGeoHype.cxx:117
TGeoHype.cxx:118
TGeoHype.cxx:119
TGeoHype.cxx:120
TGeoHype.cxx:121
TGeoHype.cxx:122
TGeoHype.cxx:123
TGeoHype.cxx:124
TGeoHype.cxx:125
TGeoHype.cxx:126
TGeoHype.cxx:127
TGeoHype.cxx:128
TGeoHype.cxx:129
TGeoHype.cxx:130
TGeoHype.cxx:131
TGeoHype.cxx:132
TGeoHype.cxx:133
TGeoHype.cxx:134
TGeoHype.cxx:135
TGeoHype.cxx:136
TGeoHype.cxx:137
TGeoHype.cxx:138
TGeoHype.cxx:139
TGeoHype.cxx:140
TGeoHype.cxx:141
TGeoHype.cxx:142
TGeoHype.cxx:143
TGeoHype.cxx:144
TGeoHype.cxx:145
TGeoHype.cxx:146
TGeoHype.cxx:147
TGeoHype.cxx:148
TGeoHype.cxx:149
TGeoHype.cxx:150
TGeoHype.cxx:151
TGeoHype.cxx:152
TGeoHype.cxx:153
TGeoHype.cxx:154
TGeoHype.cxx:155
TGeoHype.cxx:156
TGeoHype.cxx:157
TGeoHype.cxx:158
TGeoHype.cxx:159
TGeoHype.cxx:160
TGeoHype.cxx:161
TGeoHype.cxx:162
TGeoHype.cxx:163
TGeoHype.cxx:164
TGeoHype.cxx:165
TGeoHype.cxx:166
TGeoHype.cxx:167
TGeoHype.cxx:168
TGeoHype.cxx:169
TGeoHype.cxx:170
TGeoHype.cxx:171
TGeoHype.cxx:172
TGeoHype.cxx:173
TGeoHype.cxx:174
TGeoHype.cxx:175
TGeoHype.cxx:176
TGeoHype.cxx:177
TGeoHype.cxx:178
TGeoHype.cxx:179
TGeoHype.cxx:180
TGeoHype.cxx:181
TGeoHype.cxx:182
TGeoHype.cxx:183
TGeoHype.cxx:184
TGeoHype.cxx:185
TGeoHype.cxx:186
TGeoHype.cxx:187
TGeoHype.cxx:188
TGeoHype.cxx:189
TGeoHype.cxx:190
TGeoHype.cxx:191
TGeoHype.cxx:192
TGeoHype.cxx:193
TGeoHype.cxx:194
TGeoHype.cxx:195
TGeoHype.cxx:196
TGeoHype.cxx:197
TGeoHype.cxx:198
TGeoHype.cxx:199
TGeoHype.cxx:200
TGeoHype.cxx:201
TGeoHype.cxx:202
TGeoHype.cxx:203
TGeoHype.cxx:204
TGeoHype.cxx:205
TGeoHype.cxx:206
TGeoHype.cxx:207
TGeoHype.cxx:208
TGeoHype.cxx:209
TGeoHype.cxx:210
TGeoHype.cxx:211
TGeoHype.cxx:212
TGeoHype.cxx:213
TGeoHype.cxx:214
TGeoHype.cxx:215
TGeoHype.cxx:216
TGeoHype.cxx:217
TGeoHype.cxx:218
TGeoHype.cxx:219
TGeoHype.cxx:220
TGeoHype.cxx:221
TGeoHype.cxx:222
TGeoHype.cxx:223
TGeoHype.cxx:224
TGeoHype.cxx:225
TGeoHype.cxx:226
TGeoHype.cxx:227
TGeoHype.cxx:228
TGeoHype.cxx:229
TGeoHype.cxx:230
TGeoHype.cxx:231
TGeoHype.cxx:232
TGeoHype.cxx:233
TGeoHype.cxx:234
TGeoHype.cxx:235
TGeoHype.cxx:236
TGeoHype.cxx:237
TGeoHype.cxx:238
TGeoHype.cxx:239
TGeoHype.cxx:240
TGeoHype.cxx:241
TGeoHype.cxx:242
TGeoHype.cxx:243
TGeoHype.cxx:244
TGeoHype.cxx:245
TGeoHype.cxx:246
TGeoHype.cxx:247
TGeoHype.cxx:248
TGeoHype.cxx:249
TGeoHype.cxx:250
TGeoHype.cxx:251
TGeoHype.cxx:252
TGeoHype.cxx:253
TGeoHype.cxx:254
TGeoHype.cxx:255
TGeoHype.cxx:256
TGeoHype.cxx:257
TGeoHype.cxx:258
TGeoHype.cxx:259
TGeoHype.cxx:260
TGeoHype.cxx:261
TGeoHype.cxx:262
TGeoHype.cxx:263
TGeoHype.cxx:264
TGeoHype.cxx:265
TGeoHype.cxx:266
TGeoHype.cxx:267
TGeoHype.cxx:268
TGeoHype.cxx:269
TGeoHype.cxx:270
TGeoHype.cxx:271
TGeoHype.cxx:272
TGeoHype.cxx:273
TGeoHype.cxx:274
TGeoHype.cxx:275
TGeoHype.cxx:276
TGeoHype.cxx:277
TGeoHype.cxx:278
TGeoHype.cxx:279
TGeoHype.cxx:280
TGeoHype.cxx:281
TGeoHype.cxx:282
TGeoHype.cxx:283
TGeoHype.cxx:284
TGeoHype.cxx:285
TGeoHype.cxx:286
TGeoHype.cxx:287
TGeoHype.cxx:288
TGeoHype.cxx:289
TGeoHype.cxx:290
TGeoHype.cxx:291
TGeoHype.cxx:292
TGeoHype.cxx:293
TGeoHype.cxx:294
TGeoHype.cxx:295
TGeoHype.cxx:296
TGeoHype.cxx:297
TGeoHype.cxx:298
TGeoHype.cxx:299
TGeoHype.cxx:300
TGeoHype.cxx:301
TGeoHype.cxx:302
TGeoHype.cxx:303
TGeoHype.cxx:304
TGeoHype.cxx:305
TGeoHype.cxx:306
TGeoHype.cxx:307
TGeoHype.cxx:308
TGeoHype.cxx:309
TGeoHype.cxx:310
TGeoHype.cxx:311
TGeoHype.cxx:312
TGeoHype.cxx:313
TGeoHype.cxx:314
TGeoHype.cxx:315
TGeoHype.cxx:316
TGeoHype.cxx:317
TGeoHype.cxx:318
TGeoHype.cxx:319
TGeoHype.cxx:320
TGeoHype.cxx:321
TGeoHype.cxx:322
TGeoHype.cxx:323
TGeoHype.cxx:324
TGeoHype.cxx:325
TGeoHype.cxx:326
TGeoHype.cxx:327
TGeoHype.cxx:328
TGeoHype.cxx:329
TGeoHype.cxx:330
TGeoHype.cxx:331
TGeoHype.cxx:332
TGeoHype.cxx:333
TGeoHype.cxx:334
TGeoHype.cxx:335
TGeoHype.cxx:336
TGeoHype.cxx:337
TGeoHype.cxx:338
TGeoHype.cxx:339
TGeoHype.cxx:340
TGeoHype.cxx:341
TGeoHype.cxx:342
TGeoHype.cxx:343
TGeoHype.cxx:344
TGeoHype.cxx:345
TGeoHype.cxx:346
TGeoHype.cxx:347
TGeoHype.cxx:348
TGeoHype.cxx:349
TGeoHype.cxx:350
TGeoHype.cxx:351
TGeoHype.cxx:352
TGeoHype.cxx:353
TGeoHype.cxx:354
TGeoHype.cxx:355
TGeoHype.cxx:356
TGeoHype.cxx:357
TGeoHype.cxx:358
TGeoHype.cxx:359
TGeoHype.cxx:360
TGeoHype.cxx:361
TGeoHype.cxx:362
TGeoHype.cxx:363
TGeoHype.cxx:364
TGeoHype.cxx:365
TGeoHype.cxx:366
TGeoHype.cxx:367
TGeoHype.cxx:368
TGeoHype.cxx:369
TGeoHype.cxx:370
TGeoHype.cxx:371
TGeoHype.cxx:372
TGeoHype.cxx:373
TGeoHype.cxx:374
TGeoHype.cxx:375
TGeoHype.cxx:376
TGeoHype.cxx:377
TGeoHype.cxx:378
TGeoHype.cxx:379
TGeoHype.cxx:380
TGeoHype.cxx:381
TGeoHype.cxx:382
TGeoHype.cxx:383
TGeoHype.cxx:384
TGeoHype.cxx:385
TGeoHype.cxx:386
TGeoHype.cxx:387
TGeoHype.cxx:388
TGeoHype.cxx:389
TGeoHype.cxx:390
TGeoHype.cxx:391
TGeoHype.cxx:392
TGeoHype.cxx:393
TGeoHype.cxx:394
TGeoHype.cxx:395
TGeoHype.cxx:396
TGeoHype.cxx:397
TGeoHype.cxx:398
TGeoHype.cxx:399
TGeoHype.cxx:400
TGeoHype.cxx:401
TGeoHype.cxx:402
TGeoHype.cxx:403
TGeoHype.cxx:404
TGeoHype.cxx:405
TGeoHype.cxx:406
TGeoHype.cxx:407
TGeoHype.cxx:408
TGeoHype.cxx:409
TGeoHype.cxx:410
TGeoHype.cxx:411
TGeoHype.cxx:412
TGeoHype.cxx:413
TGeoHype.cxx:414
TGeoHype.cxx:415
TGeoHype.cxx:416
TGeoHype.cxx:417
TGeoHype.cxx:418
TGeoHype.cxx:419
TGeoHype.cxx:420
TGeoHype.cxx:421
TGeoHype.cxx:422
TGeoHype.cxx:423
TGeoHype.cxx:424
TGeoHype.cxx:425
TGeoHype.cxx:426
TGeoHype.cxx:427
TGeoHype.cxx:428
TGeoHype.cxx:429
TGeoHype.cxx:430
TGeoHype.cxx:431
TGeoHype.cxx:432
TGeoHype.cxx:433
TGeoHype.cxx:434
TGeoHype.cxx:435
TGeoHype.cxx:436
TGeoHype.cxx:437
TGeoHype.cxx:438
TGeoHype.cxx:439
TGeoHype.cxx:440
TGeoHype.cxx:441
TGeoHype.cxx:442
TGeoHype.cxx:443
TGeoHype.cxx:444
TGeoHype.cxx:445
TGeoHype.cxx:446
TGeoHype.cxx:447
TGeoHype.cxx:448
TGeoHype.cxx:449
TGeoHype.cxx:450
TGeoHype.cxx:451
TGeoHype.cxx:452
TGeoHype.cxx:453
TGeoHype.cxx:454
TGeoHype.cxx:455
TGeoHype.cxx:456
TGeoHype.cxx:457
TGeoHype.cxx:458
TGeoHype.cxx:459
TGeoHype.cxx:460
TGeoHype.cxx:461
TGeoHype.cxx:462
TGeoHype.cxx:463
TGeoHype.cxx:464
TGeoHype.cxx:465
TGeoHype.cxx:466
TGeoHype.cxx:467
TGeoHype.cxx:468
TGeoHype.cxx:469
TGeoHype.cxx:470
TGeoHype.cxx:471
TGeoHype.cxx:472
TGeoHype.cxx:473
TGeoHype.cxx:474
TGeoHype.cxx:475
TGeoHype.cxx:476
TGeoHype.cxx:477
TGeoHype.cxx:478
TGeoHype.cxx:479
TGeoHype.cxx:480
TGeoHype.cxx:481
TGeoHype.cxx:482
TGeoHype.cxx:483
TGeoHype.cxx:484
TGeoHype.cxx:485
TGeoHype.cxx:486
TGeoHype.cxx:487
TGeoHype.cxx:488
TGeoHype.cxx:489
TGeoHype.cxx:490
TGeoHype.cxx:491
TGeoHype.cxx:492
TGeoHype.cxx:493
TGeoHype.cxx:494
TGeoHype.cxx:495
TGeoHype.cxx:496
TGeoHype.cxx:497
TGeoHype.cxx:498
TGeoHype.cxx:499
TGeoHype.cxx:500
TGeoHype.cxx:501
TGeoHype.cxx:502
TGeoHype.cxx:503
TGeoHype.cxx:504
TGeoHype.cxx:505
TGeoHype.cxx:506
TGeoHype.cxx:507
TGeoHype.cxx:508
TGeoHype.cxx:509
TGeoHype.cxx:510
TGeoHype.cxx:511
TGeoHype.cxx:512
TGeoHype.cxx:513
TGeoHype.cxx:514
TGeoHype.cxx:515
TGeoHype.cxx:516
TGeoHype.cxx:517
TGeoHype.cxx:518
TGeoHype.cxx:519
TGeoHype.cxx:520
TGeoHype.cxx:521
TGeoHype.cxx:522
TGeoHype.cxx:523
TGeoHype.cxx:524
TGeoHype.cxx:525
TGeoHype.cxx:526
TGeoHype.cxx:527
TGeoHype.cxx:528
TGeoHype.cxx:529
TGeoHype.cxx:530
TGeoHype.cxx:531
TGeoHype.cxx:532
TGeoHype.cxx:533
TGeoHype.cxx:534
TGeoHype.cxx:535
TGeoHype.cxx:536
TGeoHype.cxx:537
TGeoHype.cxx:538
TGeoHype.cxx:539
TGeoHype.cxx:540
TGeoHype.cxx:541
TGeoHype.cxx:542
TGeoHype.cxx:543
TGeoHype.cxx:544
TGeoHype.cxx:545
TGeoHype.cxx:546
TGeoHype.cxx:547
TGeoHype.cxx:548
TGeoHype.cxx:549
TGeoHype.cxx:550
TGeoHype.cxx:551
TGeoHype.cxx:552
TGeoHype.cxx:553
TGeoHype.cxx:554
TGeoHype.cxx:555
TGeoHype.cxx:556
TGeoHype.cxx:557
TGeoHype.cxx:558
TGeoHype.cxx:559
TGeoHype.cxx:560
TGeoHype.cxx:561
TGeoHype.cxx:562
TGeoHype.cxx:563
TGeoHype.cxx:564
TGeoHype.cxx:565
TGeoHype.cxx:566
TGeoHype.cxx:567
TGeoHype.cxx:568
TGeoHype.cxx:569
TGeoHype.cxx:570
TGeoHype.cxx:571
TGeoHype.cxx:572
TGeoHype.cxx:573
TGeoHype.cxx:574
TGeoHype.cxx:575
TGeoHype.cxx:576
TGeoHype.cxx:577
TGeoHype.cxx:578
TGeoHype.cxx:579
TGeoHype.cxx:580
TGeoHype.cxx:581
TGeoHype.cxx:582
TGeoHype.cxx:583
TGeoHype.cxx:584
TGeoHype.cxx:585
TGeoHype.cxx:586
TGeoHype.cxx:587
TGeoHype.cxx:588
TGeoHype.cxx:589
TGeoHype.cxx:590
TGeoHype.cxx:591
TGeoHype.cxx:592
TGeoHype.cxx:593
TGeoHype.cxx:594
TGeoHype.cxx:595
TGeoHype.cxx:596
TGeoHype.cxx:597
TGeoHype.cxx:598
TGeoHype.cxx:599
TGeoHype.cxx:600
TGeoHype.cxx:601
TGeoHype.cxx:602
TGeoHype.cxx:603
TGeoHype.cxx:604
TGeoHype.cxx:605
TGeoHype.cxx:606
TGeoHype.cxx:607
TGeoHype.cxx:608
TGeoHype.cxx:609
TGeoHype.cxx:610
TGeoHype.cxx:611
TGeoHype.cxx:612
TGeoHype.cxx:613
TGeoHype.cxx:614
TGeoHype.cxx:615
TGeoHype.cxx:616
TGeoHype.cxx:617
TGeoHype.cxx:618
TGeoHype.cxx:619
TGeoHype.cxx:620
TGeoHype.cxx:621
TGeoHype.cxx:622
TGeoHype.cxx:623
TGeoHype.cxx:624
TGeoHype.cxx:625
TGeoHype.cxx:626
TGeoHype.cxx:627
TGeoHype.cxx:628
TGeoHype.cxx:629
TGeoHype.cxx:630
TGeoHype.cxx:631
TGeoHype.cxx:632
TGeoHype.cxx:633
TGeoHype.cxx:634
TGeoHype.cxx:635
TGeoHype.cxx:636
TGeoHype.cxx:637
TGeoHype.cxx:638
TGeoHype.cxx:639
TGeoHype.cxx:640
TGeoHype.cxx:641
TGeoHype.cxx:642
TGeoHype.cxx:643
TGeoHype.cxx:644
TGeoHype.cxx:645
TGeoHype.cxx:646
TGeoHype.cxx:647
TGeoHype.cxx:648
TGeoHype.cxx:649
TGeoHype.cxx:650
TGeoHype.cxx:651
TGeoHype.cxx:652
TGeoHype.cxx:653
TGeoHype.cxx:654
TGeoHype.cxx:655
TGeoHype.cxx:656
TGeoHype.cxx:657
TGeoHype.cxx:658
TGeoHype.cxx:659
TGeoHype.cxx:660
TGeoHype.cxx:661
TGeoHype.cxx:662
TGeoHype.cxx:663
TGeoHype.cxx:664
TGeoHype.cxx:665
TGeoHype.cxx:666
TGeoHype.cxx:667
TGeoHype.cxx:668
TGeoHype.cxx:669
TGeoHype.cxx:670
TGeoHype.cxx:671
TGeoHype.cxx:672
TGeoHype.cxx:673
TGeoHype.cxx:674
TGeoHype.cxx:675
TGeoHype.cxx:676
TGeoHype.cxx:677
TGeoHype.cxx:678
TGeoHype.cxx:679
TGeoHype.cxx:680
TGeoHype.cxx:681
TGeoHype.cxx:682
TGeoHype.cxx:683
TGeoHype.cxx:684
TGeoHype.cxx:685
TGeoHype.cxx:686
TGeoHype.cxx:687
TGeoHype.cxx:688
TGeoHype.cxx:689
TGeoHype.cxx:690
TGeoHype.cxx:691
TGeoHype.cxx:692
TGeoHype.cxx:693
TGeoHype.cxx:694
TGeoHype.cxx:695
TGeoHype.cxx:696
TGeoHype.cxx:697
TGeoHype.cxx:698
TGeoHype.cxx:699
TGeoHype.cxx:700
TGeoHype.cxx:701
TGeoHype.cxx:702
TGeoHype.cxx:703
TGeoHype.cxx:704
TGeoHype.cxx:705
TGeoHype.cxx:706
TGeoHype.cxx:707
TGeoHype.cxx:708
TGeoHype.cxx:709
TGeoHype.cxx:710
TGeoHype.cxx:711
TGeoHype.cxx:712
TGeoHype.cxx:713
TGeoHype.cxx:714
TGeoHype.cxx:715
TGeoHype.cxx:716
TGeoHype.cxx:717
TGeoHype.cxx:718
TGeoHype.cxx:719
TGeoHype.cxx:720
TGeoHype.cxx:721
TGeoHype.cxx:722
TGeoHype.cxx:723
TGeoHype.cxx:724
TGeoHype.cxx:725
TGeoHype.cxx:726
TGeoHype.cxx:727
TGeoHype.cxx:728
TGeoHype.cxx:729
TGeoHype.cxx:730
TGeoHype.cxx:731
TGeoHype.cxx:732
TGeoHype.cxx:733
TGeoHype.cxx:734
TGeoHype.cxx:735
TGeoHype.cxx:736
TGeoHype.cxx:737
TGeoHype.cxx:738
TGeoHype.cxx:739
TGeoHype.cxx:740
TGeoHype.cxx:741
TGeoHype.cxx:742
TGeoHype.cxx:743
TGeoHype.cxx:744
TGeoHype.cxx:745
TGeoHype.cxx:746
TGeoHype.cxx:747
TGeoHype.cxx:748
TGeoHype.cxx:749
TGeoHype.cxx:750
TGeoHype.cxx:751
TGeoHype.cxx:752
TGeoHype.cxx:753
TGeoHype.cxx:754
TGeoHype.cxx:755
TGeoHype.cxx:756
TGeoHype.cxx:757
TGeoHype.cxx:758
TGeoHype.cxx:759
TGeoHype.cxx:760
TGeoHype.cxx:761
TGeoHype.cxx:762
TGeoHype.cxx:763
TGeoHype.cxx:764
TGeoHype.cxx:765
TGeoHype.cxx:766
TGeoHype.cxx:767
TGeoHype.cxx:768
TGeoHype.cxx:769
TGeoHype.cxx:770
TGeoHype.cxx:771
TGeoHype.cxx:772
TGeoHype.cxx:773
TGeoHype.cxx:774
TGeoHype.cxx:775
TGeoHype.cxx:776
TGeoHype.cxx:777
TGeoHype.cxx:778
TGeoHype.cxx:779
TGeoHype.cxx:780
TGeoHype.cxx:781
TGeoHype.cxx:782
TGeoHype.cxx:783
TGeoHype.cxx:784
TGeoHype.cxx:785
TGeoHype.cxx:786
TGeoHype.cxx:787
TGeoHype.cxx:788
TGeoHype.cxx:789
TGeoHype.cxx:790
TGeoHype.cxx:791
TGeoHype.cxx:792
TGeoHype.cxx:793
TGeoHype.cxx:794
TGeoHype.cxx:795
TGeoHype.cxx:796
TGeoHype.cxx:797
TGeoHype.cxx:798
TGeoHype.cxx:799
TGeoHype.cxx:800
TGeoHype.cxx:801
TGeoHype.cxx:802
TGeoHype.cxx:803
TGeoHype.cxx:804
TGeoHype.cxx:805
TGeoHype.cxx:806
TGeoHype.cxx:807
TGeoHype.cxx:808
TGeoHype.cxx:809
TGeoHype.cxx:810
TGeoHype.cxx:811
TGeoHype.cxx:812
TGeoHype.cxx:813
TGeoHype.cxx:814
TGeoHype.cxx:815
TGeoHype.cxx:816
TGeoHype.cxx:817
TGeoHype.cxx:818
TGeoHype.cxx:819
TGeoHype.cxx:820
TGeoHype.cxx:821
TGeoHype.cxx:822
TGeoHype.cxx:823
TGeoHype.cxx:824
TGeoHype.cxx:825
TGeoHype.cxx:826
TGeoHype.cxx:827
TGeoHype.cxx:828
TGeoHype.cxx:829
TGeoHype.cxx:830
TGeoHype.cxx:831
TGeoHype.cxx:832
TGeoHype.cxx:833
TGeoHype.cxx:834
TGeoHype.cxx:835
TGeoHype.cxx:836
TGeoHype.cxx:837
TGeoHype.cxx:838
TGeoHype.cxx:839
TGeoHype.cxx:840
TGeoHype.cxx:841
TGeoHype.cxx:842
TGeoHype.cxx:843
TGeoHype.cxx:844
TGeoHype.cxx:845
TGeoHype.cxx:846
TGeoHype.cxx:847
TGeoHype.cxx:848
TGeoHype.cxx:849
TGeoHype.cxx:850
TGeoHype.cxx:851
TGeoHype.cxx:852
TGeoHype.cxx:853
TGeoHype.cxx:854
TGeoHype.cxx:855
TGeoHype.cxx:856
TGeoHype.cxx:857
TGeoHype.cxx:858
TGeoHype.cxx:859
TGeoHype.cxx:860
TGeoHype.cxx:861
TGeoHype.cxx:862
TGeoHype.cxx:863
TGeoHype.cxx:864
TGeoHype.cxx:865
TGeoHype.cxx:866
TGeoHype.cxx:867
TGeoHype.cxx:868
TGeoHype.cxx:869
TGeoHype.cxx:870
TGeoHype.cxx:871
TGeoHype.cxx:872
TGeoHype.cxx:873
TGeoHype.cxx:874
TGeoHype.cxx:875
TGeoHype.cxx:876
TGeoHype.cxx:877
TGeoHype.cxx:878
TGeoHype.cxx:879
TGeoHype.cxx:880
TGeoHype.cxx:881
TGeoHype.cxx:882
TGeoHype.cxx:883
TGeoHype.cxx:884
TGeoHype.cxx:885
TGeoHype.cxx:886
TGeoHype.cxx:887
TGeoHype.cxx:888
TGeoHype.cxx:889
TGeoHype.cxx:890
TGeoHype.cxx:891
TGeoHype.cxx:892
TGeoHype.cxx:893
TGeoHype.cxx:894
TGeoHype.cxx:895
TGeoHype.cxx:896
TGeoHype.cxx:897
TGeoHype.cxx:898
TGeoHype.cxx:899
TGeoHype.cxx:900
TGeoHype.cxx:901
TGeoHype.cxx:902
TGeoHype.cxx:903
TGeoHype.cxx:904
TGeoHype.cxx:905
TGeoHype.cxx:906
TGeoHype.cxx:907
TGeoHype.cxx:908
TGeoHype.cxx:909
TGeoHype.cxx:910
TGeoHype.cxx:911
TGeoHype.cxx:912
TGeoHype.cxx:913
TGeoHype.cxx:914
TGeoHype.cxx:915
TGeoHype.cxx:916
TGeoHype.cxx:917
TGeoHype.cxx:918
TGeoHype.cxx:919
TGeoHype.cxx:920
TGeoHype.cxx:921
TGeoHype.cxx:922
TGeoHype.cxx:923
TGeoHype.cxx:924
TGeoHype.cxx:925
TGeoHype.cxx:926
TGeoHype.cxx:927
TGeoHype.cxx:928
TGeoHype.cxx:929
TGeoHype.cxx:930
TGeoHype.cxx:931
TGeoHype.cxx:932
TGeoHype.cxx:933
TGeoHype.cxx:934
TGeoHype.cxx:935
TGeoHype.cxx:936
TGeoHype.cxx:937
TGeoHype.cxx:938
TGeoHype.cxx:939