TGeoTrd1.cxx

Go to the documentation of this file.
00001 // @(#)root/geom:$Id: TGeoTrd1.cxx 21301 2007-12-10 16:21:50Z brun $
00002 // Author: Andrei Gheata   24/10/01
00003 // TGeoTrd1::Contains() and DistFromInside() implemented by Mihaela Gheata
00004 
00005 /*************************************************************************
00006  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00007  * All rights reserved.                                                  *
00008  *                                                                       *
00009  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00010  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00011  *************************************************************************/
00012 
00013 //_____________________________________________________________________________
00014 // TGeoTrd1 - a trapezoid with only x length varying with z. It has 4
00015 //   parameters, the half length in x at the low z surface, that at the
00016 //   high z surface, the half length in y, and in z
00017 //
00018 //_____________________________________________________________________________
00019 //Begin_Html
00020 /*
00021 <img src="gif/t_trd1.gif">
00022 */
00023 //End_Html
00024 
00025 //Begin_Html
00026 /*
00027 <img src="gif/t_trd1divY.gif">
00028 */
00029 //End_Html
00030 
00031 //Begin_Html
00032 /*
00033 <img src="gif/t_trd1divZ.gif">
00034 */
00035 //End_Html
00036 
00037 //Begin_Html
00038 /*
00039 <img src="gif/t_trd1divstepZ.gif">
00040 */
00041 //End_Html
00042 
00043 #include "Riostream.h"
00044 
00045 #include "TGeoManager.h"
00046 #include "TGeoMatrix.h"
00047 #include "TGeoVolume.h"
00048 #include "TGeoTrd1.h"
00049 #include "TMath.h"
00050 
00051 ClassImp(TGeoTrd1)
00052    
00053 //_____________________________________________________________________________
00054 TGeoTrd1::TGeoTrd1()
00055 {
00056    // dummy ctor
00057    fDz = fDx1 = fDx2 = fDy = 0;
00058    SetShapeBit(kGeoTrd1);
00059 }
00060 
00061 //_____________________________________________________________________________
00062 TGeoTrd1::TGeoTrd1(Double_t dx1, Double_t dx2, Double_t dy, Double_t dz)
00063          :TGeoBBox(0,0,0)
00064 {
00065 // constructor. 
00066    SetShapeBit(kGeoTrd1);
00067    fDx1 = dx1;
00068    fDx2 = dx2;
00069    fDy = dy;
00070    fDz = dz;
00071    if ((dx1<0) || (dx2<0) || (dy<0) || (dz<0)) {
00072       SetShapeBit(kGeoRunTimeShape);
00073       printf("trd1 : dx1=%f, dx2=%f, dy=%f, dz=%f\n",
00074               dx1,dx2,dy,dz);
00075    }
00076    else ComputeBBox();
00077 }
00078 
00079 //_____________________________________________________________________________
00080 TGeoTrd1::TGeoTrd1(const char *name, Double_t dx1, Double_t dx2, Double_t dy, Double_t dz)
00081          :TGeoBBox(name, 0,0,0)
00082 {
00083 // constructor. 
00084    SetShapeBit(kGeoTrd1);
00085    fDx1 = dx1;
00086    fDx2 = dx2;
00087    fDy = dy;
00088    fDz = dz;
00089    if ((dx1<0) || (dx2<0) || (dy<0) || (dz<0)) {
00090       SetShapeBit(kGeoRunTimeShape);
00091       printf("trd1 : dx1=%f, dx2=%f, dy=%f, dz=%f\n",
00092               dx1,dx2,dy,dz);
00093    }
00094    else ComputeBBox();
00095 }
00096 
00097 //_____________________________________________________________________________
00098 TGeoTrd1::TGeoTrd1(Double_t *param)
00099          :TGeoBBox(0,0,0)
00100 {
00101    // ctor with an array of parameters
00102    // param[0] = dx1
00103    // param[1] = dx2
00104    // param[2] = dy
00105    // param[3] = dz
00106    SetShapeBit(kGeoTrd1);
00107    SetDimensions(param);
00108    if ((fDx1<0) || (fDx2<0) || (fDy<=0) || (fDz<=0)) SetShapeBit(kGeoRunTimeShape);
00109    else ComputeBBox();
00110 }
00111 
00112 //_____________________________________________________________________________
00113 TGeoTrd1::~TGeoTrd1()
00114 {
00115 // destructor
00116 }
00117 
00118 //_____________________________________________________________________________
00119 Double_t TGeoTrd1::Capacity() const
00120 {
00121 // Computes capacity of the shape in [length^3]
00122    Double_t capacity = 4.*(fDx1+fDx2)*fDy*fDz;
00123    return capacity;
00124 }   
00125 
00126 //_____________________________________________________________________________
00127 void TGeoTrd1::ComputeBBox()
00128 {
00129 // compute bounding box for a trd1
00130    fDX = TMath::Max(fDx1, fDx2);
00131    fDY = fDy;
00132    fDZ = fDz;
00133    memset(fOrigin, 0, 3*sizeof(Double_t));
00134 }
00135 
00136 //_____________________________________________________________________________   
00137 void TGeoTrd1::ComputeNormal(Double_t *point, Double_t *dir, Double_t *norm)
00138 {
00139 // Compute normal to closest surface from POINT.
00140    Double_t safe, safemin;
00141    //--- Compute safety first
00142    Double_t fx = 0.5*(fDx1-fDx2)/fDz;
00143    Double_t calf = 1./TMath::Sqrt(1.0+fx*fx);
00144    // check Z facettes
00145    safe = safemin = TMath::Abs(fDz-TMath::Abs(point[2]));
00146    norm[0] = norm[1] = 0;
00147    norm[2] = (dir[2]>=0)?1:-1;
00148    if (safe<1E-6) return;
00149    // check X facettes
00150    Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
00151    if (distx>=0) {
00152       safe=TMath::Abs(distx-TMath::Abs(point[0]))*calf;
00153       if (safe<safemin) {
00154          safemin = safe;
00155          norm[0] = (point[0]>0)?calf:(-calf);
00156          norm[1] = 0;
00157          norm[2] = calf*fx;
00158          Double_t dot = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
00159          if (dot<0) {
00160             norm[0] = -norm[0];
00161             norm[2] = -norm[2];
00162          }   
00163          if (safe<1E-6) return;
00164       }
00165    }      
00166    // check Y facettes
00167    safe = TMath::Abs(fDy-TMath::Abs(point[1]));
00168    if (safe<safemin) {
00169       norm[0] = norm[2] = 0;
00170       norm[1] = (dir[1]>=0)?1:-1;
00171    }
00172 }
00173 
00174 //_____________________________________________________________________________
00175 Bool_t TGeoTrd1::Contains(Double_t *point) const
00176 {
00177 // test if point is inside this shape
00178    // check Z range
00179    if (TMath::Abs(point[2]) > fDz) return kFALSE;
00180    // then y
00181    if (TMath::Abs(point[1]) > fDy) return kFALSE;
00182    // then x
00183    Double_t dx = 0.5*(fDx2*(point[2]+fDz)+fDx1*(fDz-point[2]))/fDz;
00184    if (TMath::Abs(point[0]) > dx) return kFALSE;
00185    return kTRUE;
00186 }
00187 
00188 //_____________________________________________________________________________
00189 Double_t TGeoTrd1::DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00190 {
00191 // Compute distance from inside point to surface of the trd1
00192 // Boundary safe algorithm.
00193    Double_t snxt = TGeoShape::Big();
00194    if (iact<3 && safe) {
00195    // compute safe distance
00196       *safe = Safety(point, kTRUE);
00197       if (iact==0) return TGeoShape::Big();
00198       if (iact==1 && step<*safe) return TGeoShape::Big();
00199    }
00200 
00201    //--- Compute safety first
00202    Double_t fx = 0.5*(fDx1-fDx2)/fDz;
00203    Double_t cn;
00204    Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
00205    //--- Compute distance to this shape
00206    // first check if Z facettes are crossed
00207    Double_t dist[3];
00208    for (Int_t i=0; i<3; i++) dist[i]=TGeoShape::Big();
00209    if (dir[2]<0) {
00210       dist[0]=-(point[2]+fDz)/dir[2];
00211    } else if (dir[2]>0) {
00212       dist[0]=(fDz-point[2])/dir[2];
00213    } 
00214    if (dist[0]<=0) return 0.0;     
00215    // now check X facettes
00216    cn = -dir[0]+fx*dir[2];
00217    if (cn>0) {
00218       dist[1] = point[0]+distx;
00219       if (dist[1]<=0) return 0.0;
00220       dist[1] /= cn;
00221    }   
00222    cn = dir[0]+fx*dir[2];
00223    if (cn>0) {
00224       Double_t s = distx-point[0];
00225       if (s<=0) return 0.0;
00226       s /= cn;
00227       if (s<dist[1]) dist[1] = s;
00228    }
00229    // now check Y facettes
00230    if (dir[1]<0) {
00231       dist[2]=-(point[1]+fDy)/dir[1];
00232    } else if (dir[1]>0) {
00233       dist[2]=(fDy-point[1])/dir[1];
00234    }  
00235    if (dist[2]<=0) return 0.0;    
00236    snxt = dist[TMath::LocMin(3,dist)];
00237    return snxt;
00238 }
00239 
00240 //_____________________________________________________________________________
00241 void TGeoTrd1::GetVisibleCorner(Double_t *point, Double_t *vertex, Double_t *normals) const
00242 {
00243 // get the most visible corner from outside point and the normals
00244    Double_t fx = 0.5*(fDx1-fDx2)/fDz;
00245    Double_t calf = 1./TMath::Sqrt(1.0+fx*fx);
00246    Double_t salf = calf*fx;
00247    // check visibility of X faces
00248    Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
00249    memset(normals, 0, 9*sizeof(Double_t));
00250    TGeoTrd1 *trd1 = (TGeoTrd1*)this;
00251    if (point[0]>distx) {
00252    // hi x face visible
00253       trd1->SetShapeBit(kGeoVisX);
00254       normals[0]=calf;
00255       normals[2]=salf;
00256    } else {   
00257       trd1->SetShapeBit(kGeoVisX, kFALSE);
00258       normals[0]=-calf;
00259       normals[2]=salf;
00260    }
00261    if (point[1]>fDy) {
00262    // hi y face visible
00263       trd1->SetShapeBit(kGeoVisY);
00264       normals[4]=1;
00265    } else {
00266       trd1->SetShapeBit(kGeoVisY, kFALSE);
00267       normals[4]=-1;  
00268    }   
00269    if (point[2]>fDz) {
00270    // hi z face visible
00271       trd1->SetShapeBit(kGeoVisZ);
00272       normals[8]=1;
00273    } else {
00274       trd1->SetShapeBit(kGeoVisZ, kFALSE);
00275       normals[8]=-1;  
00276    }
00277    SetVertex(vertex);
00278 }
00279 
00280 //_____________________________________________________________________________
00281 void TGeoTrd1::GetOppositeCorner(Double_t * /*point*/, Int_t inorm, Double_t *vertex, Double_t *normals) const
00282 {
00283 // get the opposite corner of the intersected face
00284    TGeoTrd1 *trd1 = (TGeoTrd1*)this;
00285    if (inorm != 0) {
00286    // change x face
00287       trd1->SetShapeBit(kGeoVisX, !TestShapeBit(kGeoVisX));
00288       normals[0]=-normals[0];
00289    }
00290    if (inorm != 1) {
00291    // change y face
00292       trd1->SetShapeBit(kGeoVisY, !TestShapeBit(kGeoVisY));
00293       normals[4]=-normals[4];
00294    } 
00295    if (inorm != 2) {
00296    // hi z face visible
00297       trd1->SetShapeBit(kGeoVisZ, !TestShapeBit(kGeoVisZ));
00298       normals[8]=-normals[8];
00299    } 
00300    SetVertex(vertex);
00301 }
00302 
00303 //_____________________________________________________________________________
00304 Double_t TGeoTrd1::DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00305 {
00306 // Compute distance from outside point to surface of the trd1
00307 // Boundary safe algorithm
00308    Double_t snxt = TGeoShape::Big();
00309    if (iact<3 && safe) {
00310    // compute safe distance
00311       *safe = Safety(point, kFALSE);
00312       if (iact==0) return TGeoShape::Big();
00313       if (iact==1 && step<*safe) return TGeoShape::Big();
00314    }
00315    // find a visible face
00316    Double_t xnew,ynew,znew;
00317    Double_t fx = 0.5*(fDx1-fDx2)/fDz;
00318    Double_t cn;
00319    Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
00320    Bool_t in = kTRUE;
00321    Double_t safx = distx-TMath::Abs(point[0]);
00322    Double_t safy = fDy-TMath::Abs(point[1]);
00323    Double_t safz = fDz-TMath::Abs(point[2]);
00324    
00325    //--- Compute distance to this shape
00326    // first check if Z facettes are crossed
00327    if (point[2]<=-fDz) {
00328       if (dir[2]<=0) return TGeoShape::Big();
00329       in = kFALSE;
00330       snxt = -(fDz+point[2])/dir[2];
00331       // find extrapolated X and Y
00332       xnew = point[0]+snxt*dir[0];
00333       if (TMath::Abs(xnew) <= fDx1) {
00334          ynew = point[1]+snxt*dir[1];
00335          if (TMath::Abs(ynew) <= fDy) return snxt;
00336       }
00337    } else if (point[2]>=fDz) {
00338       if (dir[2]>=0) return TGeoShape::Big();
00339       in = kFALSE;
00340       snxt = (fDz-point[2])/dir[2];
00341       // find extrapolated X and Y
00342       xnew = point[0]+snxt*dir[0];
00343       if (TMath::Abs(xnew) <= fDx2) {
00344          ynew = point[1]+snxt*dir[1];
00345          if (TMath::Abs(ynew) <= fDy) return snxt;
00346       }
00347    }   
00348    // check if X facettes are crossed
00349    if (point[0]<=-distx) {
00350       cn = -dir[0]+fx*dir[2];
00351       if (cn>=0) return TGeoShape::Big();
00352       in = kFALSE;
00353       snxt = (point[0]+distx)/cn;
00354       // find extrapolated Y and Z
00355       ynew = point[1]+snxt*dir[1];
00356       if (TMath::Abs(ynew) <= fDy) {
00357          znew = point[2]+snxt*dir[2];
00358          if (TMath::Abs(znew) <= fDz) return snxt;
00359       }
00360    }            
00361    if (point[0]>=distx) {
00362       cn = dir[0]+fx*dir[2];
00363       if (cn>=0) return TGeoShape::Big();
00364       in = kFALSE;
00365       snxt = (distx-point[0])/cn;
00366       // find extrapolated Y and Z
00367       ynew = point[1]+snxt*dir[1];
00368       if (TMath::Abs(ynew) < fDy) {
00369          znew = point[2]+snxt*dir[2];
00370          if (TMath::Abs(znew) < fDz) return snxt;
00371       }
00372    }
00373    // finally check Y facettes
00374    if (point[1]<=-fDy) {
00375       cn = -dir[1];            
00376       if (cn>=0) return TGeoShape::Big();
00377       in = kFALSE;
00378       snxt = (point[1]+fDy)/cn;
00379       // find extrapolated X and Z
00380       znew = point[2]+snxt*dir[2];
00381       if (TMath::Abs(znew) < fDz) {
00382          xnew = point[0]+snxt*dir[0];
00383          Double_t dx = 0.5*(fDx1+fDx2)-fx*znew;
00384          if (TMath::Abs(xnew) < dx) return snxt;
00385       }
00386    } else if (point[1]>=fDy) {
00387       cn = dir[1];        
00388       if (cn>=0) return TGeoShape::Big();    
00389       in = kFALSE;
00390       snxt = (fDy-point[1])/cn;
00391       // find extrapolated X and Z
00392       znew = point[2]+snxt*dir[2];
00393       if (TMath::Abs(znew) < fDz) {
00394          xnew = point[0]+snxt*dir[0];
00395          Double_t dx = 0.5*(fDx1+fDx2)-fx*znew;
00396          if (TMath::Abs(xnew) < dx) return snxt;
00397       }
00398    }
00399    if (!in) return TGeoShape::Big();
00400    // Point actually inside
00401    if (safz<safx && safz<safy) {
00402       if (point[2]*dir[2]>=0) return TGeoShape::Big();
00403       return 0.0;
00404    }
00405    if (safy<safx) {
00406       if (point[1]*dir[1]>=0) return TGeoShape::Big();
00407       return 0.0;
00408    }
00409    cn = TMath::Sign(1.0,point[0])*dir[0]+fx*dir[2];     
00410    if (cn>=0) return TGeoShape::Big();
00411    return 0.0;
00412 }
00413 
00414 //_____________________________________________________________________________
00415 TGeoVolume *TGeoTrd1::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, 
00416                              Double_t start, Double_t step) 
00417 {
00418 //--- Divide this trd1 shape belonging to volume "voldiv" into ndiv volumes
00419 // called divname, from start position with the given step. Returns pointer
00420 // to created division cell volume in case of Y divisions. For Z divisions just
00421 // return the pointer to the volume to be divided. In case a wrong 
00422 // division axis is supplied, returns pointer to volume that was divided.
00423    TGeoShape *shape;           //--- shape to be created
00424    TGeoVolume *vol;            //--- division volume to be created
00425    TGeoVolumeMulti *vmulti;    //--- generic divided volume
00426    TGeoPatternFinder *finder;  //--- finder to be attached 
00427    TString opt = "";           //--- option to be attached
00428    Double_t zmin, zmax, dx1n, dx2n;
00429    Int_t id;
00430    Double_t end = start+ndiv*step;
00431    switch (iaxis) {
00432       case 1:
00433          Warning("Divide", "dividing a Trd1 on X not implemented");
00434          return 0;
00435       case 2:
00436          finder = new TGeoPatternY(voldiv, ndiv, start, end);
00437          voldiv->SetFinder(finder);
00438          finder->SetDivIndex(voldiv->GetNdaughters());            
00439          shape = new TGeoTrd1(fDx1, fDx2, step/2, fDz);
00440          vol = new TGeoVolume(divname, shape, voldiv->GetMedium()); 
00441          vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
00442          vmulti->AddVolume(vol);
00443          opt = "Y";
00444          for (id=0; id<ndiv; id++) {
00445             voldiv->AddNodeOffset(vol, id, start+step/2+id*step, opt.Data());
00446             ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
00447          }
00448          return vmulti;
00449       case 3:
00450          finder = new TGeoPatternZ(voldiv, ndiv, start, end);
00451          voldiv->SetFinder(finder);
00452          finder->SetDivIndex(voldiv->GetNdaughters());            
00453          vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
00454          for (id=0; id<ndiv; id++) {
00455             zmin = start+id*step;
00456             zmax = start+(id+1)*step;
00457             dx1n = 0.5*(fDx1*(fDz-zmin)+fDx2*(fDz+zmin))/fDz;
00458             dx2n = 0.5*(fDx1*(fDz-zmax)+fDx2*(fDz+zmax))/fDz;
00459             shape = new TGeoTrd1(dx1n, dx2n, fDy, step/2.);
00460             vol = new TGeoVolume(divname, shape, voldiv->GetMedium()); 
00461             vmulti->AddVolume(vol);
00462             opt = "Z";             
00463             voldiv->AddNodeOffset(vol, id, start+step/2+id*step, opt.Data());
00464             ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
00465          }
00466          return vmulti;
00467       default:
00468          Error("Divide", "Wrong axis type for division");
00469          return 0;
00470    }
00471 }
00472 
00473 //_____________________________________________________________________________
00474 Double_t TGeoTrd1::GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
00475 {
00476 // Get range of shape for a given axis.
00477    xlo = 0;
00478    xhi = 0;
00479    Double_t dx = 0;
00480    switch (iaxis) {
00481       case 2:
00482          xlo = -fDy;
00483          xhi = fDy;
00484          dx = xhi-xlo;
00485          return dx;
00486       case 3:
00487          xlo = -fDz;
00488          xhi = fDz;
00489          dx = xhi-xlo;
00490          return dx;
00491    }
00492    return dx;
00493 }         
00494 
00495 //_____________________________________________________________________________
00496 void TGeoTrd1::GetBoundingCylinder(Double_t *param) const
00497 {
00498 //--- Fill vector param[4] with the bounding cylinder parameters. The order
00499 // is the following : Rmin, Rmax, Phi1, Phi2
00500    TGeoBBox::GetBoundingCylinder(param);
00501 }   
00502 
00503 //_____________________________________________________________________________
00504 Int_t TGeoTrd1::GetFittingBox(const TGeoBBox *parambox, TGeoMatrix *mat, Double_t &dx, Double_t &dy, Double_t &dz) const
00505 {
00506 // Fills real parameters of a positioned box inside this. Returns 0 if successfull.
00507    dx=dy=dz=0;
00508    if (mat->IsRotation()) {
00509       Error("GetFittingBox", "cannot handle parametrized rotated volumes");
00510       return 1; // ### rotation not accepted ###
00511    }
00512    //--> translate the origin of the parametrized box to the frame of this box.
00513    Double_t origin[3];
00514    mat->LocalToMaster(parambox->GetOrigin(), origin);
00515    if (!Contains(origin)) {
00516       Error("GetFittingBox", "wrong matrix - parametrized box is outside this");
00517       return 1; // ### wrong matrix ###
00518    }
00519    //--> now we have to get the valid range for all parametrized axis
00520    Double_t dd[3];
00521    dd[0] = parambox->GetDX();
00522    dd[1] = parambox->GetDY();
00523    dd[2] = parambox->GetDZ();
00524    //-> check if Z range is fixed
00525    if (dd[2]<0) {
00526       dd[2] = TMath::Min(origin[2]+fDz, fDz-origin[2]); 
00527       if (dd[2]<0) {
00528          Error("GetFittingBox", "wrong matrix");
00529          return 1;
00530       }
00531    }
00532    //-> check if Y range is fixed
00533    if (dd[1]<0) {
00534       dd[1] = TMath::Min(origin[1]+fDy, fDy-origin[1]); 
00535       if (dd[1]<0) {
00536          Error("GetFittingBox", "wrong matrix");
00537          return 1;
00538       }
00539    }
00540    if (dd[0]>=0) {
00541       dx = dd[0];
00542       dy = dd[1];
00543       dz = dd[2];
00544       return 0;
00545    }
00546    //-> check now range at Z = origin[2] +/- dd[2]
00547    Double_t fx = 0.5*(fDx1-fDx2)/fDz;
00548    Double_t dx0 = 0.5*(fDx1+fDx2);
00549    Double_t z=origin[2]-dd[2];
00550    dd[0] = dx0-fx*z-origin[0]; 
00551    z=origin[2]+dd[2];
00552    dd[0] = TMath::Min(dd[0], dx0-fx*z-origin[0]);
00553    if (dd[0]<0) {
00554       Error("GetFittingBox", "wrong matrix");
00555       return 1;
00556    }   
00557    dx = dd[0];
00558    dy = dd[1];
00559    dz = dd[2];
00560    return 0;
00561 }   
00562 
00563 //_____________________________________________________________________________
00564 TGeoShape *TGeoTrd1::GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix * /*mat*/) const
00565 {
00566 // in case shape has some negative parameters, these has to be computed
00567 // in order to fit the mother
00568    if (!TestShapeBit(kGeoRunTimeShape)) return 0;
00569    if (!mother->TestShapeBit(kGeoTrd1)) {
00570       Error("GetMakeRuntimeShape", "invalid mother");
00571       return 0;
00572    }
00573    Double_t dx1, dx2, dy, dz;
00574    if (fDx1<0) dx1=((TGeoTrd1*)mother)->GetDx1();
00575    else dx1=fDx1;
00576    if (fDx2<0) dx2=((TGeoTrd1*)mother)->GetDx2();
00577    else dx2=fDx2;
00578    if (fDy<0) dy=((TGeoTrd1*)mother)->GetDy();
00579    else dy=fDy;
00580    if (fDz<0) dz=((TGeoTrd1*)mother)->GetDz();
00581    else dz=fDz;
00582 
00583    return (new TGeoTrd1(dx1, dx2, dy, dz));
00584 }
00585 
00586 //_____________________________________________________________________________
00587 void TGeoTrd1::InspectShape() const
00588 {
00589 // print shape parameters
00590    printf("*** Shape %s: TGeoTrd1 ***\n", GetName());
00591    printf("    dx1 = %11.5f\n", fDx1);
00592    printf("    dx2 = %11.5f\n", fDx2);
00593    printf("    dy  = %11.5f\n", fDy);
00594    printf("    dz  = %11.5f\n", fDz);
00595    printf(" Bounding box:\n");
00596    TGeoBBox::InspectShape();
00597 }
00598 
00599 //_____________________________________________________________________________
00600 Double_t TGeoTrd1::Safety(Double_t *point, Bool_t in) const
00601 {
00602 // computes the closest distance from given point to this shape, according
00603 // to option. The matching point on the shape is stored in spoint.
00604    Double_t saf[3];
00605    //--- Compute safety first
00606    // check Z facettes
00607    saf[0] = fDz-TMath::Abs(point[2]);
00608    Double_t fx = 0.5*(fDx1-fDx2)/fDz;
00609    Double_t calf = 1./TMath::Sqrt(1.0+fx*fx);
00610    // check X facettes
00611    Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
00612    if (distx<0) saf[1]=TGeoShape::Big();
00613    else         saf[1]=(distx-TMath::Abs(point[0]))*calf;
00614    // check Y facettes
00615    saf[2] = fDy-TMath::Abs(point[1]);
00616    if (in) return saf[TMath::LocMin(3,saf)];
00617    for (Int_t i=0; i<3; i++) saf[i]=-saf[i];
00618    return saf[TMath::LocMax(3,saf)];
00619 }
00620 
00621 //_____________________________________________________________________________
00622 void TGeoTrd1::SavePrimitive(ostream &out, Option_t * /*option*/ /*= ""*/)
00623 {
00624 // Save a primitive as a C++ statement(s) on output stream "out".
00625    if (TObject::TestBit(kGeoSavePrimitive)) return;
00626    out << "   // Shape: " << GetName() << " type: " << ClassName() << endl;
00627    out << "   dx1 = " << fDx1 << ";" << endl;
00628    out << "   dx2 = " << fDx2 << ";" << endl;
00629    out << "   dy  = " << fDy  << ";" << endl;
00630    out << "   dz  = " << fDZ  << ";" << endl;
00631    out << "   TGeoShape *" << GetPointerName() << " = new TGeoTrd1(\"" << GetName() << "\", dx1,dx2,dy,dz);" << endl;  
00632    TObject::SetBit(TGeoShape::kGeoSavePrimitive);
00633 }         
00634 
00635 //_____________________________________________________________________________
00636 void TGeoTrd1::SetDimensions(Double_t *param)
00637 {
00638 // set trd1 params in one step :
00639    fDx1 = param[0];
00640    fDx2 = param[1];
00641    fDy  = param[2];
00642    fDz  = param[3];
00643    ComputeBBox();
00644 }   
00645 
00646 //_____________________________________________________________________________
00647 void TGeoTrd1::SetVertex(Double_t *vertex) const
00648 {
00649 // set vertex of a corner according to visibility flags
00650    if (TestShapeBit(kGeoVisX)) {
00651       if (TestShapeBit(kGeoVisZ)) {
00652          vertex[0] = fDx2;
00653          vertex[2] = fDz;
00654          vertex[1] = (TestShapeBit(kGeoVisY))?fDy:-fDy;
00655       } else {   
00656          vertex[0] = fDx1;
00657          vertex[2] = -fDz;
00658          vertex[1] = (TestShapeBit(kGeoVisY))?fDy:-fDy;
00659       }
00660    } else {
00661       if (TestShapeBit(kGeoVisZ)) {
00662          vertex[0] = -fDx2;
00663          vertex[2] = fDz;
00664          vertex[1] = (TestShapeBit(kGeoVisY))?fDy:-fDy;
00665       } else {   
00666          vertex[0] = -fDx1;
00667          vertex[2] = -fDz;
00668          vertex[1] = (TestShapeBit(kGeoVisY))?fDy:-fDy;
00669       }
00670    }            
00671 } 
00672 
00673 //_____________________________________________________________________________
00674 void TGeoTrd1::SetPoints(Double_t *points) const
00675 {
00676 // create arb8 mesh points
00677    if (!points) return;
00678    points[ 0] = -fDx1; points[ 1] = -fDy; points[ 2] = -fDz;
00679    points[ 3] = -fDx1; points[ 4] =  fDy; points[ 5] = -fDz;
00680    points[ 6] =  fDx1; points[ 7] =  fDy; points[ 8] = -fDz;
00681    points[ 9] =  fDx1; points[10] = -fDy; points[11] = -fDz;
00682    points[12] = -fDx2; points[13] = -fDy; points[14] =  fDz;
00683    points[15] = -fDx2; points[16] =  fDy; points[17] =  fDz;
00684    points[18] =  fDx2; points[19] =  fDy; points[20] =  fDz;
00685    points[21] =  fDx2; points[22] = -fDy; points[23] =  fDz;
00686 }
00687 
00688 //_____________________________________________________________________________
00689 void TGeoTrd1::SetPoints(Float_t *points) const
00690 {
00691 // create arb8 mesh points
00692    if (!points) return;
00693    points[ 0] = -fDx1; points[ 1] = -fDy; points[ 2] = -fDz;
00694    points[ 3] = -fDx1; points[ 4] =  fDy; points[ 5] = -fDz;
00695    points[ 6] =  fDx1; points[ 7] =  fDy; points[ 8] = -fDz;
00696    points[ 9] =  fDx1; points[10] = -fDy; points[11] = -fDz;
00697    points[12] = -fDx2; points[13] = -fDy; points[14] =  fDz;
00698    points[15] = -fDx2; points[16] =  fDy; points[17] =  fDz;
00699    points[18] =  fDx2; points[19] =  fDy; points[20] =  fDz;
00700    points[21] =  fDx2; points[22] = -fDy; points[23] =  fDz;
00701 }
00702 
00703 //_____________________________________________________________________________
00704 void TGeoTrd1::Sizeof3D() const
00705 {
00706 // fill size of this 3-D object
00707    TGeoBBox::Sizeof3D();
00708 }

Generated on Tue Jul 5 14:12:58 2011 for ROOT_528-00b_version by  doxygen 1.5.1