00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include "Riostream.h"
00064
00065 #include "TGeoManager.h"
00066 #include "TGeoVolume.h"
00067 #include "TVirtualGeoPainter.h"
00068 #include "TGeoCone.h"
00069 #include "TVirtualPad.h"
00070 #include "TBuffer3D.h"
00071 #include "TBuffer3DTypes.h"
00072 #include "TMath.h"
00073
00074 ClassImp(TGeoCone)
00075
00076
00077 TGeoCone::TGeoCone()
00078 {
00079
00080 SetShapeBit(TGeoShape::kGeoCone);
00081 fDz = 0.0;
00082 fRmin1 = 0.0;
00083 fRmax1 = 0.0;
00084 fRmin2 = 0.0;
00085 fRmax2 = 0.0;
00086 }
00087
00088
00089 TGeoCone::TGeoCone(Double_t dz, Double_t rmin1, Double_t rmax1,
00090 Double_t rmin2, Double_t rmax2)
00091 :TGeoBBox(0, 0, 0)
00092 {
00093
00094 SetShapeBit(TGeoShape::kGeoCone);
00095 SetConeDimensions(dz, rmin1, rmax1, rmin2, rmax2);
00096 if ((dz<0) || (rmin1<0) || (rmax1<0) || (rmin2<0) || (rmax2<0)) {
00097 SetShapeBit(kGeoRunTimeShape);
00098 }
00099 else ComputeBBox();
00100 }
00101
00102
00103 TGeoCone::TGeoCone(const char *name, Double_t dz, Double_t rmin1, Double_t rmax1,
00104 Double_t rmin2, Double_t rmax2)
00105 :TGeoBBox(name, 0, 0, 0)
00106 {
00107
00108 SetShapeBit(TGeoShape::kGeoCone);
00109 SetConeDimensions(dz, rmin1, rmax1, rmin2, rmax2);
00110 if ((dz<0) || (rmin1<0) || (rmax1<0) || (rmin2<0) || (rmax2<0)) {
00111 SetShapeBit(kGeoRunTimeShape);
00112 }
00113 else ComputeBBox();
00114 }
00115
00116
00117 TGeoCone::TGeoCone(Double_t *param)
00118 :TGeoBBox(0, 0, 0)
00119 {
00120
00121
00122
00123
00124
00125
00126 SetShapeBit(TGeoShape::kGeoCone);
00127 SetDimensions(param);
00128 if ((fDz<0) || (fRmin1<0) || (fRmax1<0) || (fRmin2<0) || (fRmax2<0))
00129 SetShapeBit(kGeoRunTimeShape);
00130 else ComputeBBox();
00131 }
00132
00133
00134 Double_t TGeoCone::Capacity() const
00135 {
00136
00137 return TGeoCone::Capacity(fDz, fRmin1, fRmax1, fRmin2, fRmax2);
00138 }
00139
00140
00141 Double_t TGeoCone::Capacity(Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
00142 {
00143
00144 Double_t capacity = (2.*dz*TMath::Pi()/3.)*(rmax1*rmax1+rmax2*rmax2+rmax1*rmax2-
00145 rmin1*rmin1-rmin2*rmin2-rmin1*rmin2);
00146 return capacity;
00147 }
00148
00149
00150 TGeoCone::~TGeoCone()
00151 {
00152
00153 }
00154
00155
00156 void TGeoCone::ComputeBBox()
00157 {
00158
00159 TGeoBBox *box = (TGeoBBox*)this;
00160 box->SetBoxDimensions(TMath::Max(fRmax1, fRmax2), TMath::Max(fRmax1, fRmax2), fDz);
00161 memset(fOrigin, 0, 3*sizeof(Double_t));
00162 }
00163
00164
00165 void TGeoCone::ComputeNormal(Double_t *point, Double_t *dir, Double_t *norm)
00166 {
00167
00168 Double_t safr,safe,phi;
00169 memset(norm,0,3*sizeof(Double_t));
00170 phi = TMath::ATan2(point[1],point[0]);
00171 Double_t cphi = TMath::Cos(phi);
00172 Double_t sphi = TMath::Sin(phi);
00173 Double_t ro1 = 0.5*(fRmin1+fRmin2);
00174 Double_t tg1 = 0.5*(fRmin2-fRmin1)/fDz;
00175 Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
00176 Double_t ro2 = 0.5*(fRmax1+fRmax2);
00177 Double_t tg2 = 0.5*(fRmax2-fRmax1)/fDz;
00178 Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
00179
00180 Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
00181 Double_t rin = tg1*point[2]+ro1;
00182 Double_t rout = tg2*point[2]+ro2;
00183 safe = TMath::Abs(fDz-TMath::Abs(point[2]));
00184 norm[2] = 1;
00185
00186 safr = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
00187 if (safr<safe) {
00188 safe = safr;
00189 norm[0] = cr1*cphi;
00190 norm[1] = cr1*sphi;
00191 norm[2] = -tg1*cr1;
00192 }
00193 safr = TMath::Abs((rout-r)*cr2);
00194 if (safr<safe) {
00195 norm[0] = cr2*cphi;
00196 norm[1] = cr2*sphi;
00197 norm[2] = -tg2*cr2;
00198 }
00199 if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
00200 norm[0] = -norm[0];
00201 norm[1] = -norm[1];
00202 norm[2] = -norm[2];
00203 }
00204 }
00205
00206
00207 void TGeoCone::ComputeNormalS(Double_t *point, Double_t *dir, Double_t *norm,
00208 Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
00209 {
00210
00211 Double_t safe,phi;
00212 memset(norm,0,3*sizeof(Double_t));
00213 phi = TMath::ATan2(point[1],point[0]);
00214 Double_t cphi = TMath::Cos(phi);
00215 Double_t sphi = TMath::Sin(phi);
00216 Double_t ro1 = 0.5*(rmin1+rmin2);
00217 Double_t tg1 = 0.5*(rmin2-rmin1)/dz;
00218 Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
00219 Double_t ro2 = 0.5*(rmax1+rmax2);
00220 Double_t tg2 = 0.5*(rmax2-rmax1)/dz;
00221 Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
00222
00223 Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
00224 Double_t rin = tg1*point[2]+ro1;
00225 Double_t rout = tg2*point[2]+ro2;
00226 safe = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
00227 norm[0] = cr1*cphi;
00228 norm[1] = cr1*sphi;
00229 norm[2] = -tg1*cr1;
00230 if (TMath::Abs((rout-r)*cr2)<safe) {
00231 norm[0] = cr2*cphi;
00232 norm[1] = cr2*sphi;
00233 norm[2] = -tg2*cr2;
00234 }
00235 if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
00236 norm[0] = -norm[0];
00237 norm[1] = -norm[1];
00238 norm[2] = -norm[2];
00239 }
00240 }
00241
00242
00243 Bool_t TGeoCone::Contains(Double_t *point) const
00244 {
00245
00246 if (TMath::Abs(point[2]) > fDz) return kFALSE;
00247 Double_t r2 = point[0]*point[0]+point[1]*point[1];
00248 Double_t rl = 0.5*(fRmin2*(point[2]+fDz)+fRmin1*(fDz-point[2]))/fDz;
00249 Double_t rh = 0.5*(fRmax2*(point[2]+fDz)+fRmax1*(fDz-point[2]))/fDz;
00250 if ((r2<rl*rl) || (r2>rh*rh)) return kFALSE;
00251 return kTRUE;
00252 }
00253
00254
00255 Double_t TGeoCone::DistFromInsideS(Double_t *point, Double_t *dir, Double_t dz,
00256 Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
00257 {
00258
00259
00260 if (dz<=0) return TGeoShape::Big();
00261
00262
00263 Double_t sz = TGeoShape::Big();
00264 if (dir[2]) {
00265 sz = (TMath::Sign(dz, dir[2])-point[2])/dir[2];
00266 if (sz<=0) return 0.0;
00267 }
00268 Double_t rsq=point[0]*point[0]+point[1]*point[1];
00269 Double_t zinv = 1./dz;
00270 Double_t rin = 0.5*(rmin1+rmin2+(rmin2-rmin1)*point[2]*zinv);
00271
00272 Double_t sr = TGeoShape::Big();
00273 Double_t b,delta,zi;
00274 if (rin>0) {
00275
00276 if (rsq < rin*(rin+TGeoShape::Tolerance())) {
00277 Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]+0.5*(rmin1-rmin2)*dir[2]*zinv*TMath::Sqrt(rsq);
00278 if (ddotn<=0) return 0.0;
00279 } else {
00280 TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
00281 if (delta>0) {
00282 sr = -b-delta;
00283 if (sr>0) {
00284 zi = point[2]+sr*dir[2];
00285 if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
00286 }
00287 sr = -b+delta;
00288 if (sr>0) {
00289 zi = point[2]+sr*dir[2];
00290 if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
00291 }
00292 }
00293 }
00294 }
00295
00296 Double_t rout = 0.5*(rmax1+rmax2+(rmax2-rmax1)*point[2]*zinv);
00297 if (rsq > rout*(rout-TGeoShape::Tolerance())) {
00298 Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]+0.5*(rmax1-rmax2)*dir[2]*zinv*TMath::Sqrt(rsq);
00299 if (ddotn>=0) return 0.0;
00300 TGeoCone::DistToCone(point, dir, dz, rmax1, rmax2, b, delta);
00301 if (delta<0) return 0.0;
00302 sr = -b+delta;
00303 if (sr<0) return sz;
00304 if (TMath::Abs(-b-delta)>sr) return sz;
00305 zi = point[2]+sr*dir[2];
00306 if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
00307 return sz;
00308 }
00309 TGeoCone::DistToCone(point, dir, dz, rmax1, rmax2, b, delta);
00310 if (delta>0) {
00311 sr = -b-delta;
00312 if (sr>0) {
00313 zi = point[2]+sr*dir[2];
00314 if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
00315 }
00316 sr = -b+delta;
00317 if (sr>TGeoShape::Tolerance()) {
00318 zi = point[2]+sr*dir[2];
00319 if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
00320 }
00321 }
00322 return sz;
00323 }
00324
00325
00326 Double_t TGeoCone::DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00327 {
00328
00329
00330
00331 if (iact<3 && safe) {
00332 *safe = Safety(point, kTRUE);
00333 if (iact==0) return TGeoShape::Big();
00334 if ((iact==1) && (*safe>step)) return TGeoShape::Big();
00335 }
00336
00337 return TGeoCone::DistFromInsideS(point, dir, fDz, fRmin1, fRmax1, fRmin2, fRmax2);
00338 }
00339
00340
00341 Double_t TGeoCone::DistFromOutsideS(Double_t *point, Double_t *dir, Double_t dz,
00342 Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
00343 {
00344
00345
00346
00347 if (dz<=0) return TGeoShape::Big();
00348 Double_t snxt;
00349 Double_t xp, yp, zp;
00350 Bool_t inz = kTRUE;
00351
00352 if (point[2]<=-dz) {
00353 if (dir[2]<=0) return TGeoShape::Big();
00354 snxt = (-dz-point[2])/dir[2];
00355 xp = point[0]+snxt*dir[0];
00356 yp = point[1]+snxt*dir[1];
00357 Double_t r2 = xp*xp+yp*yp;
00358 if ((r2>=rmin1*rmin1) && (r2<=rmax1*rmax1)) return snxt;
00359 inz = kFALSE;
00360 } else {
00361 if (point[2]>=dz) {
00362 if (dir[2]>=0) return TGeoShape::Big();
00363 snxt = (dz-point[2])/dir[2];
00364 xp = point[0]+snxt*dir[0];
00365 yp = point[1]+snxt*dir[1];
00366 Double_t r2 = xp*xp+yp*yp;
00367 if ((r2>=rmin2*rmin2) && (r2<=rmax2*rmax2)) return snxt;
00368 inz = kFALSE;
00369 }
00370 }
00371
00372 Double_t rsq = point[0]*point[0]+point[1]*point[1];
00373 Double_t dzinv = 1./dz;
00374 Double_t ro1=0.5*(rmin1+rmin2);
00375 Bool_t hasrmin = (ro1>0)?kTRUE:kFALSE;
00376 Double_t tg1 = 0.;
00377 Double_t rin = 0.;
00378 Bool_t inrmin = kTRUE;
00379 if (hasrmin) {
00380 tg1=0.5*(rmin2-rmin1)*dzinv;
00381 rin=ro1+tg1*point[2];
00382 if (rin>0 && rsq<rin*(rin-TGeoShape::Tolerance())) inrmin=kFALSE;
00383 }
00384 Double_t ro2=0.5*(rmax1+rmax2);
00385 Double_t tg2=0.5*(rmax2-rmax1)*dzinv;
00386 Double_t rout=tg2*point[2]+ro2;
00387 Bool_t inrmax = kFALSE;
00388 if (rout>0 && rsq<rout*(rout+TGeoShape::Tolerance())) inrmax=kTRUE;
00389 Bool_t in = inz & inrmin & inrmax;
00390 Double_t b,delta;
00391
00392 if (in) {
00393 Double_t r=TMath::Sqrt(rsq);
00394 Double_t safz = dz-TMath::Abs(point[2]);
00395 Double_t safrmin = (hasrmin)?(r-rin):TGeoShape::Big();
00396 Double_t safrmax = rout - r;
00397 if (safz<=safrmin && safz<=safrmax) {
00398
00399 if (point[2]*dir[2]<0) return 0.0;
00400 return TGeoShape::Big();
00401 }
00402 if (safrmax<safrmin) {
00403
00404 Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg2*dir[2]*r;
00405 if (ddotn<=0) return 0.0;
00406 return TGeoShape::Big();
00407 }
00408
00409 Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg1*dir[2]*r;
00410 if (ddotn>=0) return 0.0;
00411
00412 TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
00413
00414 if (delta<0) return 0.0;
00415 snxt = -b+delta;
00416 if (snxt<0) return TGeoShape::Big();
00417 if (TMath::Abs(-b-delta)>snxt) return TGeoShape::Big();
00418 zp = point[2]+snxt*dir[2];
00419 if (TMath::Abs(zp)<=dz) return snxt;
00420 return TGeoShape::Big();
00421 }
00422
00423
00424 snxt = TGeoShape::Big();
00425 if (!inrmin) {
00426
00427 TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
00428 if (delta<0) return TGeoShape::Big();
00429 snxt = -b+delta;
00430 if (snxt>0) {
00431 zp = point[2]+snxt*dir[2];
00432 if (TMath::Abs(zp)<=dz) return snxt;
00433 }
00434 snxt = -b-delta;
00435 if (snxt>0) {
00436 zp = point[2]+snxt*dir[2];
00437 if (TMath::Abs(zp)<=dz) return snxt;
00438 }
00439 snxt = TGeoShape::Big();
00440 } else {
00441 if (hasrmin) {
00442 TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
00443 if (delta>0) {
00444 Double_t din = -b+delta;
00445 if (din>0) {
00446 zp = point[2]+din*dir[2];
00447 if (TMath::Abs(zp)<=dz) snxt = din;
00448 }
00449 }
00450 }
00451 }
00452
00453 if (inrmax) return snxt;
00454
00455
00456 TGeoCone::DistToCone(point, dir, dz, rmax1, rmax2, b, delta);
00457 if (delta<0) return snxt;
00458 Double_t dout = -b-delta;
00459 if (dout>0 && dout<snxt) {
00460 zp = point[2]+dout*dir[2];
00461 if (TMath::Abs(zp)<=dz) return dout;
00462 }
00463 dout = -b+delta;
00464 if (dout<=0 || dout>snxt) return snxt;
00465 zp = point[2]+dout*dir[2];
00466 if (TMath::Abs(zp)<=dz) return dout;
00467 return snxt;
00468 }
00469
00470
00471 Double_t TGeoCone::DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00472 {
00473
00474
00475 if (iact<3 && safe) {
00476 *safe = Safety(point, kFALSE);
00477 if (iact==0) return TGeoShape::Big();
00478 if ((iact==1) && (*safe>step)) return TGeoShape::Big();
00479 }
00480
00481 Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
00482 if (sdist>=step) return TGeoShape::Big();
00483
00484 return TGeoCone::DistFromOutsideS(point, dir, fDz, fRmin1, fRmax1, fRmin2, fRmax2);
00485 }
00486
00487
00488 void TGeoCone::DistToCone(Double_t *point, Double_t *dir, Double_t dz, Double_t r1, Double_t r2,
00489 Double_t &b, Double_t &delta)
00490 {
00491
00492
00493
00494 delta = -1.;
00495 if (dz<0) return;
00496 Double_t ro0 = 0.5*(r1+r2);
00497 Double_t tz = 0.5*(r2-r1)/dz;
00498 Double_t rsq = point[0]*point[0] + point[1]*point[1];
00499 Double_t rc = ro0 + point[2]*tz;
00500
00501 Double_t a = dir[0]*dir[0] + dir[1]*dir[1] - tz*tz*dir[2]*dir[2];
00502 b = point[0]*dir[0] + point[1]*dir[1] - tz*rc*dir[2];
00503 Double_t c = rsq - rc*rc;
00504
00505 if (TMath::Abs(a)<TGeoShape::Tolerance()) {
00506 if (TMath::Abs(b)<TGeoShape::Tolerance()) return;
00507 b = 0.5*c/b;
00508 delta = 0.;
00509 return;
00510 }
00511 a = 1./a;
00512 b *= a;
00513 c *= a;
00514 delta = b*b - c;
00515 if (delta>0) {
00516 delta = TMath::Sqrt(delta);
00517 } else {
00518 delta = -1.;
00519 }
00520 }
00521
00522
00523 Int_t TGeoCone::DistancetoPrimitive(Int_t px, Int_t py)
00524 {
00525
00526 Int_t n = gGeoManager->GetNsegments();
00527 const Int_t numPoints = 4*n;
00528 return ShapeDistancetoPrimitive(numPoints, px, py);
00529 }
00530
00531
00532 TGeoVolume *TGeoCone::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv,
00533 Double_t start, Double_t step)
00534 {
00535
00536
00537
00538
00539
00540
00541 TGeoShape *shape;
00542 TGeoVolume *vol;
00543 TGeoVolumeMulti *vmulti;
00544 TGeoPatternFinder *finder;
00545 TString opt = "";
00546 Int_t id;
00547 Double_t end = start+ndiv*step;
00548 switch (iaxis) {
00549 case 1:
00550 Error("Divide","division of a cone on R not implemented");
00551 return 0;
00552 case 2:
00553 finder = new TGeoPatternCylPhi(voldiv, ndiv, start, end);
00554 voldiv->SetFinder(finder);
00555 finder->SetDivIndex(voldiv->GetNdaughters());
00556 shape = new TGeoConeSeg(fDz, fRmin1, fRmax1, fRmin2, fRmax2, -step/2, step/2);
00557 vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
00558 vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
00559 vmulti->AddVolume(vol);
00560 opt = "Phi";
00561 for (id=0; id<ndiv; id++) {
00562 voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
00563 ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
00564 }
00565 return vmulti;
00566 case 3:
00567 vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
00568 finder = new TGeoPatternZ(voldiv, ndiv, start, end);
00569 voldiv->SetFinder(finder);
00570 finder->SetDivIndex(voldiv->GetNdaughters());
00571 for (id=0; id<ndiv; id++) {
00572 Double_t z1 = start+id*step;
00573 Double_t z2 = start+(id+1)*step;
00574 Double_t rmin1n = 0.5*(fRmin1*(fDz-z1)+fRmin2*(fDz+z1))/fDz;
00575 Double_t rmax1n = 0.5*(fRmax1*(fDz-z1)+fRmax2*(fDz+z1))/fDz;
00576 Double_t rmin2n = 0.5*(fRmin1*(fDz-z2)+fRmin2*(fDz+z2))/fDz;
00577 Double_t rmax2n = 0.5*(fRmax1*(fDz-z2)+fRmax2*(fDz+z2))/fDz;
00578 shape = new TGeoCone(0.5*step,rmin1n, rmax1n, rmin2n, rmax2n);
00579 vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
00580 vmulti->AddVolume(vol);
00581 opt = "Z";
00582 voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
00583 ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
00584 }
00585 return vmulti;
00586 default:
00587 Error("Divide", "Wrong axis type for division");
00588 return 0;
00589 }
00590 }
00591
00592
00593 const char *TGeoCone::GetAxisName(Int_t iaxis) const
00594 {
00595
00596 switch (iaxis) {
00597 case 1:
00598 return "R";
00599 case 2:
00600 return "PHI";
00601 case 3:
00602 return "Z";
00603 default:
00604 return "undefined";
00605 }
00606 }
00607
00608
00609 Double_t TGeoCone::GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
00610 {
00611
00612 xlo = 0;
00613 xhi = 0;
00614 Double_t dx = 0;
00615 switch (iaxis) {
00616 case 2:
00617 xlo = 0.;
00618 xhi = 360.;
00619 return 360.;
00620 case 3:
00621 xlo = -fDz;
00622 xhi = fDz;
00623 dx = xhi-xlo;
00624 return dx;
00625 }
00626 return dx;
00627 }
00628
00629
00630 void TGeoCone::GetBoundingCylinder(Double_t *param) const
00631 {
00632
00633
00634 param[0] = TMath::Min(fRmin1, fRmin2);
00635 param[0] *= param[0];
00636 param[1] = TMath::Max(fRmax1, fRmax2);
00637 param[1] *= param[1];
00638 param[2] = 0.;
00639 param[3] = 360.;
00640 }
00641
00642
00643 TGeoShape *TGeoCone::GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix * ) const
00644 {
00645
00646
00647 if (!TestShapeBit(kGeoRunTimeShape)) return 0;
00648 if (!mother->TestShapeBit(kGeoCone)) {
00649 Error("GetMakeRuntimeShape", "invalid mother");
00650 return 0;
00651 }
00652 Double_t rmin1, rmax1, rmin2, rmax2, dz;
00653 rmin1 = fRmin1;
00654 rmax1 = fRmax1;
00655 rmin2 = fRmin2;
00656 rmax2 = fRmax2;
00657 dz = fDz;
00658 if (fDz<0) dz=((TGeoCone*)mother)->GetDz();
00659 if (fRmin1<0)
00660 rmin1 = ((TGeoCone*)mother)->GetRmin1();
00661 if (fRmax1<0)
00662 rmax1 = ((TGeoCone*)mother)->GetRmax1();
00663 if (fRmin2<0)
00664 rmin2 = ((TGeoCone*)mother)->GetRmin2();
00665 if (fRmax2<0)
00666 rmax2 = ((TGeoCone*)mother)->GetRmax2();
00667
00668 return (new TGeoCone(GetName(), dz, rmin1, rmax1, rmin2, rmax2));
00669 }
00670
00671
00672 Bool_t TGeoCone::GetPointsOnSegments(Int_t npoints, Double_t *array) const
00673 {
00674
00675
00676
00677 if (npoints > (npoints/2)*2) {
00678 Error("GetPointsOnSegments","Npoints must be even number");
00679 return kFALSE;
00680 }
00681 Bool_t hasrmin = (fRmin1>0 || fRmin2>0)?kTRUE:kFALSE;
00682 Int_t nc = 0;
00683 if (hasrmin) nc = (Int_t)TMath::Sqrt(0.5*npoints);
00684 else nc = (Int_t)TMath::Sqrt(1.*npoints);
00685 Double_t dphi = TMath::TwoPi()/nc;
00686 Double_t phi = 0;
00687 Int_t ntop = 0;
00688 if (hasrmin) ntop = npoints/2 - nc*(nc-1);
00689 else ntop = npoints - nc*(nc-1);
00690 Double_t dz = 2*fDz/(nc-1);
00691 Double_t z = 0;
00692 Int_t icrt = 0;
00693 Int_t nphi = nc;
00694 Double_t rmin = 0.;
00695 Double_t rmax = 0.;
00696
00697 for (Int_t i=0; i<nc; i++) {
00698 if (i == (nc-1)) nphi = ntop;
00699 z = -fDz + i*dz;
00700 if (hasrmin) rmin = 0.5*(fRmin1+fRmin2) + 0.5*(fRmin2-fRmin1)*z/fDz;
00701 rmax = 0.5*(fRmax1+fRmax2) + 0.5*(fRmax2-fRmax1)*z/fDz;
00702
00703 for (Int_t j=0; j<nphi; j++) {
00704 phi = j*dphi;
00705 if (hasrmin) {
00706 array[icrt++] = rmin * TMath::Cos(phi);
00707 array[icrt++] = rmin * TMath::Sin(phi);
00708 array[icrt++] = z;
00709 }
00710 array[icrt++] = rmax * TMath::Cos(phi);
00711 array[icrt++] = rmax * TMath::Sin(phi);
00712 array[icrt++] = z;
00713 }
00714 }
00715 return kTRUE;
00716 }
00717
00718
00719
00720 void TGeoCone::InspectShape() const
00721 {
00722
00723 printf("*** Shape %s TGeoCone ***\n", GetName());
00724 printf(" dz =: %11.5f\n", fDz);
00725 printf(" Rmin1 = %11.5f\n", fRmin1);
00726 printf(" Rmax1 = %11.5f\n", fRmax1);
00727 printf(" Rmin2 = %11.5f\n", fRmin2);
00728 printf(" Rmax2 = %11.5f\n", fRmax2);
00729 printf(" Bounding box:\n");
00730 TGeoBBox::InspectShape();
00731 }
00732
00733
00734 TBuffer3D *TGeoCone::MakeBuffer3D() const
00735 {
00736
00737
00738
00739 Int_t n = gGeoManager->GetNsegments();
00740 Int_t nbPnts = 4*n;
00741 Int_t nbSegs = 8*n;
00742 Int_t nbPols = 4*n;
00743 TBuffer3D* buff = new TBuffer3D(TBuffer3DTypes::kGeneric,
00744 nbPnts, 3*nbPnts,
00745 nbSegs, 3*nbSegs,
00746 nbPols, 6*nbPols);
00747
00748 if (buff)
00749 {
00750 SetPoints(buff->fPnts);
00751 SetSegsAndPols(*buff);
00752 }
00753 return buff;
00754 }
00755
00756
00757 void TGeoCone::SetSegsAndPols(TBuffer3D &buffer) const
00758 {
00759
00760 Int_t i,j;
00761 Int_t n = gGeoManager->GetNsegments();
00762 Int_t c = GetBasicColor();
00763
00764 for (i = 0; i < 4; i++) {
00765 for (j = 0; j < n; j++) {
00766 buffer.fSegs[(i*n+j)*3 ] = c;
00767 buffer.fSegs[(i*n+j)*3+1] = i*n+j;
00768 buffer.fSegs[(i*n+j)*3+2] = i*n+j+1;
00769 }
00770 buffer.fSegs[(i*n+j-1)*3+2] = i*n;
00771 }
00772 for (i = 4; i < 6; i++) {
00773 for (j = 0; j < n; j++) {
00774 buffer.fSegs[(i*n+j)*3 ] = c+1;
00775 buffer.fSegs[(i*n+j)*3+1] = (i-4)*n+j;
00776 buffer.fSegs[(i*n+j)*3+2] = (i-2)*n+j;
00777 }
00778 }
00779 for (i = 6; i < 8; i++) {
00780 for (j = 0; j < n; j++) {
00781 buffer.fSegs[(i*n+j)*3 ] = c;
00782 buffer.fSegs[(i*n+j)*3+1] = 2*(i-6)*n+j;
00783 buffer.fSegs[(i*n+j)*3+2] = (2*(i-6)+1)*n+j;
00784 }
00785 }
00786
00787 Int_t indx = 0;
00788 i=0;
00789 for (j = 0; j < n; j++) {
00790 indx = 6*(i*n+j);
00791 buffer.fPols[indx ] = c;
00792 buffer.fPols[indx+1] = 4;
00793 buffer.fPols[indx+5] = i*n+j;
00794 buffer.fPols[indx+4] = (4+i)*n+j;
00795 buffer.fPols[indx+3] = (2+i)*n+j;
00796 buffer.fPols[indx+2] = (4+i)*n+j+1;
00797 }
00798 buffer.fPols[indx+2] = (4+i)*n;
00799 i=1;
00800 for (j = 0; j < n; j++) {
00801 indx = 6*(i*n+j);
00802 buffer.fPols[indx ] = c;
00803 buffer.fPols[indx+1] = 4;
00804 buffer.fPols[indx+2] = i*n+j;
00805 buffer.fPols[indx+3] = (4+i)*n+j;
00806 buffer.fPols[indx+4] = (2+i)*n+j;
00807 buffer.fPols[indx+5] = (4+i)*n+j+1;
00808 }
00809 buffer.fPols[indx+5] = (4+i)*n;
00810 i=2;
00811 for (j = 0; j < n; j++) {
00812 indx = 6*(i*n+j);
00813 buffer.fPols[indx ] = c+i;
00814 buffer.fPols[indx+1] = 4;
00815 buffer.fPols[indx+2] = (i-2)*2*n+j;
00816 buffer.fPols[indx+3] = (4+i)*n+j;
00817 buffer.fPols[indx+4] = ((i-2)*2+1)*n+j;
00818 buffer.fPols[indx+5] = (4+i)*n+j+1;
00819 }
00820 buffer.fPols[indx+5] = (4+i)*n;
00821 i=3;
00822 for (j = 0; j < n; j++) {
00823 indx = 6*(i*n+j);
00824 buffer.fPols[indx ] = c+i;
00825 buffer.fPols[indx+1] = 4;
00826 buffer.fPols[indx+5] = (i-2)*2*n+j;
00827 buffer.fPols[indx+4] = (4+i)*n+j;
00828 buffer.fPols[indx+3] = ((i-2)*2+1)*n+j;
00829 buffer.fPols[indx+2] = (4+i)*n+j+1;
00830 }
00831 buffer.fPols[indx+2] = (4+i)*n;
00832 }
00833
00834
00835 Double_t TGeoCone::Safety(Double_t *point, Bool_t in) const
00836 {
00837
00838
00839 Double_t saf[3];
00840
00841
00842 Double_t ro1 = 0.5*(fRmin1+fRmin2);
00843 Double_t tg1 = 0.5*(fRmin2-fRmin1)/fDz;
00844 Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
00845 Double_t ro2 = 0.5*(fRmax1+fRmax2);
00846 Double_t tg2 = 0.5*(fRmax2-fRmax1)/fDz;
00847 Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
00848
00849 Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
00850 Double_t rin = tg1*point[2]+ro1;
00851 Double_t rout = tg2*point[2]+ro2;
00852 saf[0] = fDz-TMath::Abs(point[2]);
00853 saf[1] = (ro1>0)?((r-rin)*cr1):TGeoShape::Big();
00854 saf[2] = (rout-r)*cr2;
00855 if (in) return saf[TMath::LocMin(3,saf)];
00856 for (Int_t i=0; i<3; i++) saf[i]=-saf[i];
00857 return saf[TMath::LocMax(3,saf)];
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 }
00871
00872
00873 Double_t TGeoCone::SafetyS(Double_t *point, Bool_t in, Double_t dz, Double_t rmin1, Double_t rmax1,
00874 Double_t rmin2, Double_t rmax2, Int_t skipz)
00875 {
00876
00877
00878 Double_t saf[3];
00879 Double_t ro1 = 0.5*(rmin1+rmin2);
00880 Double_t tg1 = 0.5*(rmin2-rmin1)/dz;
00881 Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
00882 Double_t ro2 = 0.5*(rmax1+rmax2);
00883 Double_t tg2 = 0.5*(rmax2-rmax1)/dz;
00884 Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
00885
00886 Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
00887 Double_t rin = tg1*point[2]+ro1;
00888 Double_t rout = tg2*point[2]+ro2;
00889 switch (skipz) {
00890 case 1:
00891 saf[0] = dz - point[2];
00892 break;
00893 case 2:
00894 saf[0] = dz + point[2];
00895 break;
00896 case 3:
00897 saf[0] = TGeoShape::Big();
00898 break;
00899 default:
00900 saf[0] = dz-TMath::Abs(point[2]);
00901 }
00902 saf[1] = (ro1>0)?((r-rin)*cr1):TGeoShape::Big();
00903 saf[2] = (rout-r)*cr2;
00904 if (in) return saf[TMath::LocMin(3,saf)];
00905 for (Int_t i=0; i<3; i++) saf[i]=-saf[i];
00906 return saf[TMath::LocMax(3,saf)];
00907 }
00908
00909
00910 void TGeoCone::SavePrimitive(ostream &out, Option_t * )
00911 {
00912
00913 if (TObject::TestBit(kGeoSavePrimitive)) return;
00914 out << " // Shape: " << GetName() << " type: " << ClassName() << endl;
00915 out << " dz = " << fDz << ";" << endl;
00916 out << " rmin1 = " << fRmin1 << ";" << endl;
00917 out << " rmax1 = " << fRmax1 << ";" << endl;
00918 out << " rmin2 = " << fRmin2 << ";" << endl;
00919 out << " rmax2 = " << fRmax2 << ";" << endl;
00920 out << " TGeoShape *" << GetPointerName() << " = new TGeoCone(\"" << GetName() << "\", dz,rmin1,rmax1,rmin2,rmax2);" << endl;
00921 TObject::SetBit(TGeoShape::kGeoSavePrimitive);
00922 }
00923
00924
00925 void TGeoCone::SetConeDimensions(Double_t dz, Double_t rmin1, Double_t rmax1,
00926 Double_t rmin2, Double_t rmax2)
00927 {
00928
00929 if (rmin1>=0) {
00930 if (rmax1>0) {
00931 if (rmin1<=rmax1) {
00932
00933 fRmin1 = rmin1;
00934 fRmax1 = rmax1;
00935 } else {
00936 fRmin1 = rmax1;
00937 fRmax1 = rmin1;
00938 Warning("SetConeDimensions", "rmin1>rmax1 Switch rmin1<->rmax1");
00939 SetShapeBit(TGeoShape::kGeoBad);
00940 }
00941 } else {
00942
00943 fRmin1 = rmin1;
00944 fRmax1 = rmax1;
00945 }
00946 } else {
00947
00948 fRmin1 = rmin1;
00949 fRmax1 = rmax1;
00950 }
00951 if (rmin2>=0) {
00952 if (rmax2>0) {
00953 if (rmin2<=rmax2) {
00954
00955 fRmin2 = rmin2;
00956 fRmax2 = rmax2;
00957 } else {
00958 fRmin2 = rmax2;
00959 fRmax2 = rmin2;
00960 Warning("SetConeDimensions", "rmin2>rmax2 Switch rmin2<->rmax2");
00961 SetShapeBit(TGeoShape::kGeoBad);
00962 }
00963 } else {
00964
00965 fRmin2 = rmin2;
00966 fRmax2 = rmax2;
00967 }
00968 } else {
00969
00970 fRmin2 = rmin2;
00971 fRmax2 = rmax2;
00972 }
00973
00974 fDz = dz;
00975 }
00976
00977
00978 void TGeoCone::SetDimensions(Double_t *param)
00979 {
00980
00981 Double_t dz = param[0];
00982 Double_t rmin1 = param[1];
00983 Double_t rmax1 = param[2];
00984 Double_t rmin2 = param[3];
00985 Double_t rmax2 = param[4];
00986 SetConeDimensions(dz, rmin1, rmax1, rmin2, rmax2);
00987 }
00988
00989
00990 void TGeoCone::SetPoints(Double_t *points) const
00991 {
00992
00993 Double_t dz, phi, dphi;
00994 Int_t j, n;
00995
00996 n = gGeoManager->GetNsegments();
00997 dphi = 360./n;
00998 dz = fDz;
00999 Int_t indx = 0;
01000
01001 if (points) {
01002 for (j = 0; j < n; j++) {
01003 phi = j*dphi*TMath::DegToRad();
01004 points[indx++] = fRmin1 * TMath::Cos(phi);
01005 points[indx++] = fRmin1 * TMath::Sin(phi);
01006 points[indx++] = -dz;
01007 }
01008
01009 for (j = 0; j < n; j++) {
01010 phi = j*dphi*TMath::DegToRad();
01011 points[indx++] = fRmax1 * TMath::Cos(phi);
01012 points[indx++] = fRmax1 * TMath::Sin(phi);
01013 points[indx++] = -dz;
01014 }
01015
01016 for (j = 0; j < n; j++) {
01017 phi = j*dphi*TMath::DegToRad();
01018 points[indx++] = fRmin2 * TMath::Cos(phi);
01019 points[indx++] = fRmin2 * TMath::Sin(phi);
01020 points[indx++] = dz;
01021 }
01022
01023 for (j = 0; j < n; j++) {
01024 phi = j*dphi*TMath::DegToRad();
01025 points[indx++] = fRmax2 * TMath::Cos(phi);
01026 points[indx++] = fRmax2 * TMath::Sin(phi);
01027 points[indx++] = dz;
01028 }
01029 }
01030 }
01031
01032
01033 void TGeoCone::SetPoints(Float_t *points) const
01034 {
01035
01036 Double_t dz, phi, dphi;
01037 Int_t j, n;
01038
01039 n = gGeoManager->GetNsegments();
01040 dphi = 360./n;
01041 dz = fDz;
01042 Int_t indx = 0;
01043
01044 if (points) {
01045 for (j = 0; j < n; j++) {
01046 phi = j*dphi*TMath::DegToRad();
01047 points[indx++] = fRmin1 * TMath::Cos(phi);
01048 points[indx++] = fRmin1 * TMath::Sin(phi);
01049 points[indx++] = -dz;
01050 }
01051
01052 for (j = 0; j < n; j++) {
01053 phi = j*dphi*TMath::DegToRad();
01054 points[indx++] = fRmax1 * TMath::Cos(phi);
01055 points[indx++] = fRmax1 * TMath::Sin(phi);
01056 points[indx++] = -dz;
01057 }
01058
01059 for (j = 0; j < n; j++) {
01060 phi = j*dphi*TMath::DegToRad();
01061 points[indx++] = fRmin2 * TMath::Cos(phi);
01062 points[indx++] = fRmin2 * TMath::Sin(phi);
01063 points[indx++] = dz;
01064 }
01065
01066 for (j = 0; j < n; j++) {
01067 phi = j*dphi*TMath::DegToRad();
01068 points[indx++] = fRmax2 * TMath::Cos(phi);
01069 points[indx++] = fRmax2 * TMath::Sin(phi);
01070 points[indx++] = dz;
01071 }
01072 }
01073 }
01074
01075
01076 void TGeoCone::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
01077 {
01078
01079 Int_t n = gGeoManager->GetNsegments();
01080 nvert = n*4;
01081 nsegs = n*8;
01082 npols = n*4;
01083 }
01084
01085
01086 Int_t TGeoCone::GetNmeshVertices() const
01087 {
01088
01089 Int_t n = gGeoManager->GetNsegments();
01090 Int_t numPoints = n*4;
01091 return numPoints;
01092 }
01093
01094
01095 void TGeoCone::Sizeof3D() const
01096 {
01097
01098
01099
01100
01101
01102
01103
01104
01105 }
01106
01107
01108 const TBuffer3D & TGeoCone::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
01109 {
01110
01111 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
01112
01113 TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
01114
01115 if (reqSections & TBuffer3D::kRawSizes) {
01116 Int_t n = gGeoManager->GetNsegments();
01117 Int_t nbPnts = 4*n;
01118 Int_t nbSegs = 8*n;
01119 Int_t nbPols = 4*n;
01120 if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
01121 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
01122 }
01123 }
01124
01125
01126 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
01127 SetPoints(buffer.fPnts);
01128 if (!buffer.fLocalFrame) {
01129 TransformPoints(buffer.fPnts, buffer.NbPnts());
01130 }
01131
01132 SetSegsAndPols(buffer);
01133 buffer.SetSectionsValid(TBuffer3D::kRaw);
01134 }
01135
01136 return buffer;
01137 }
01138
01139 ClassImp(TGeoConeSeg)
01140
01141
01142 TGeoConeSeg::TGeoConeSeg()
01143 {
01144
01145 SetShapeBit(TGeoShape::kGeoConeSeg);
01146 fPhi1 = fPhi2 = 0.0;
01147 }
01148
01149
01150 TGeoConeSeg::TGeoConeSeg(Double_t dz, Double_t rmin1, Double_t rmax1,
01151 Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
01152 :TGeoCone(dz, rmin1, rmax1, rmin2, rmax2)
01153 {
01154
01155 SetShapeBit(TGeoShape::kGeoConeSeg);
01156 SetConsDimensions(dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
01157 ComputeBBox();
01158 }
01159
01160
01161 TGeoConeSeg::TGeoConeSeg(const char *name, Double_t dz, Double_t rmin1, Double_t rmax1,
01162 Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
01163 :TGeoCone(name, dz, rmin1, rmax1, rmin2, rmax2)
01164 {
01165
01166 SetShapeBit(TGeoShape::kGeoConeSeg);
01167 SetConsDimensions(dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
01168 ComputeBBox();
01169 }
01170
01171
01172 TGeoConeSeg::TGeoConeSeg(Double_t *param)
01173 :TGeoCone(0,0,0,0,0)
01174 {
01175
01176
01177
01178
01179
01180
01181
01182
01183 SetShapeBit(TGeoShape::kGeoConeSeg);
01184 SetDimensions(param);
01185 ComputeBBox();
01186 }
01187
01188
01189 TGeoConeSeg::~TGeoConeSeg()
01190 {
01191
01192 }
01193
01194
01195 Double_t TGeoConeSeg::Capacity() const
01196 {
01197
01198 return TGeoConeSeg::Capacity(fDz, fRmin1, fRmax1, fRmin2, fRmax2, fPhi1, fPhi2);
01199 }
01200
01201
01202 Double_t TGeoConeSeg::Capacity(Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
01203 {
01204
01205 Double_t capacity = (TMath::Abs(phi2-phi1)*TMath::DegToRad()*dz/3.)*
01206 (rmax1*rmax1+rmax2*rmax2+rmax1*rmax2-
01207 rmin1*rmin1-rmin2*rmin2-rmin1*rmin2);
01208 return capacity;
01209 }
01210
01211
01212 void TGeoConeSeg::ComputeBBox()
01213 {
01214
01215 Double_t rmin, rmax;
01216 rmin = TMath::Min(fRmin1, fRmin2);
01217 rmax = TMath::Max(fRmax1, fRmax2);
01218
01219 Double_t xc[4];
01220 Double_t yc[4];
01221 xc[0] = rmax*TMath::Cos(fPhi1*TMath::DegToRad());
01222 yc[0] = rmax*TMath::Sin(fPhi1*TMath::DegToRad());
01223 xc[1] = rmax*TMath::Cos(fPhi2*TMath::DegToRad());
01224 yc[1] = rmax*TMath::Sin(fPhi2*TMath::DegToRad());
01225 xc[2] = rmin*TMath::Cos(fPhi1*TMath::DegToRad());
01226 yc[2] = rmin*TMath::Sin(fPhi1*TMath::DegToRad());
01227 xc[3] = rmin*TMath::Cos(fPhi2*TMath::DegToRad());
01228 yc[3] = rmin*TMath::Sin(fPhi2*TMath::DegToRad());
01229
01230 Double_t xmin = xc[TMath::LocMin(4, &xc[0])];
01231 Double_t xmax = xc[TMath::LocMax(4, &xc[0])];
01232 Double_t ymin = yc[TMath::LocMin(4, &yc[0])];
01233 Double_t ymax = yc[TMath::LocMax(4, &yc[0])];
01234
01235 Double_t dp = fPhi2-fPhi1;
01236 Double_t ddp = -fPhi1;
01237 if (ddp<0) ddp+= 360;
01238 if (ddp<=dp) xmax = rmax;
01239 ddp = 90-fPhi1;
01240 if (ddp<0) ddp+= 360;
01241 if (ddp<=dp) ymax = rmax;
01242 ddp = 180-fPhi1;
01243 if (ddp<0) ddp+= 360;
01244 if (ddp<=dp) xmin = -rmax;
01245 ddp = 270-fPhi1;
01246 if (ddp<0) ddp+= 360;
01247 if (ddp<=dp) ymin = -rmax;
01248 fOrigin[0] = (xmax+xmin)/2;
01249 fOrigin[1] = (ymax+ymin)/2;
01250 fOrigin[2] = 0;
01251 fDX = (xmax-xmin)/2;
01252 fDY = (ymax-ymin)/2;
01253 fDZ = fDz;
01254 }
01255
01256
01257 void TGeoConeSeg::ComputeNormal(Double_t *point, Double_t *dir, Double_t *norm)
01258 {
01259
01260 Double_t saf[3];
01261 Double_t ro1 = 0.5*(fRmin1+fRmin2);
01262 Double_t tg1 = 0.5*(fRmin2-fRmin1)/fDz;
01263 Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
01264 Double_t ro2 = 0.5*(fRmax1+fRmax2);
01265 Double_t tg2 = 0.5*(fRmax2-fRmax1)/fDz;
01266 Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
01267
01268 Double_t c1 = TMath::Cos(fPhi1*TMath::DegToRad());
01269 Double_t s1 = TMath::Sin(fPhi1*TMath::DegToRad());
01270 Double_t c2 = TMath::Cos(fPhi2*TMath::DegToRad());
01271 Double_t s2 = TMath::Sin(fPhi2*TMath::DegToRad());
01272
01273 Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
01274 Double_t rin = tg1*point[2]+ro1;
01275 Double_t rout = tg2*point[2]+ro2;
01276 saf[0] = TMath::Abs(fDz-TMath::Abs(point[2]));
01277 saf[1] = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
01278 saf[2] = TMath::Abs((rout-r)*cr2);
01279 Int_t i = TMath::LocMin(3,saf);
01280 if (((fPhi2-fPhi1)<360.) && TGeoShape::IsCloseToPhi(saf[i], point,c1,s1,c2,s2)) {
01281 TGeoShape::NormalPhi(point,dir,norm,c1,s1,c2,s2);
01282 return;
01283 }
01284 if (i==0) {
01285 norm[0] = norm[1] = 0.;
01286 norm[2] = TMath::Sign(1.,dir[2]);
01287 return;
01288 }
01289
01290 Double_t phi = TMath::ATan2(point[1],point[0]);
01291 Double_t cphi = TMath::Cos(phi);
01292 Double_t sphi = TMath::Sin(phi);
01293
01294 if (i==1) {
01295 norm[0] = cr1*cphi;
01296 norm[1] = cr1*sphi;
01297 norm[2] = -tg1*cr1;
01298 } else {
01299 norm[0] = cr2*cphi;
01300 norm[1] = cr2*sphi;
01301 norm[2] = -tg2*cr2;
01302 }
01303
01304 if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
01305 norm[0] = -norm[0];
01306 norm[1] = -norm[1];
01307 norm[2] = -norm[2];
01308 }
01309 }
01310
01311
01312 void TGeoConeSeg::ComputeNormalS(Double_t *point, Double_t *dir, Double_t *norm,
01313 Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2,
01314 Double_t c1, Double_t s1, Double_t c2, Double_t s2)
01315 {
01316
01317 Double_t saf[2];
01318 Double_t ro1 = 0.5*(rmin1+rmin2);
01319 Double_t tg1 = 0.5*(rmin2-rmin1)/dz;
01320 Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
01321 Double_t ro2 = 0.5*(rmax1+rmax2);
01322 Double_t tg2 = 0.5*(rmax2-rmax1)/dz;
01323 Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
01324
01325 Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
01326 Double_t rin = tg1*point[2]+ro1;
01327 Double_t rout = tg2*point[2]+ro2;
01328 saf[0] = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
01329 saf[1] = TMath::Abs((rout-r)*cr2);
01330 Int_t i = TMath::LocMin(2,saf);
01331 if (TGeoShape::IsCloseToPhi(saf[i], point,c1,s1,c2,s2)) {
01332 TGeoShape::NormalPhi(point,dir,norm,c1,s1,c2,s2);
01333 return;
01334 }
01335
01336 Double_t phi = TMath::ATan2(point[1],point[0]);
01337 Double_t cphi = TMath::Cos(phi);
01338 Double_t sphi = TMath::Sin(phi);
01339
01340 if (i==0) {
01341 norm[0] = cr1*cphi;
01342 norm[1] = cr1*sphi;
01343 norm[2] = -tg1*cr1;
01344 } else {
01345 norm[0] = cr2*cphi;
01346 norm[1] = cr2*sphi;
01347 norm[2] = -tg2*cr2;
01348 }
01349
01350 if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
01351 norm[0] = -norm[0];
01352 norm[1] = -norm[1];
01353 norm[2] = -norm[2];
01354 }
01355 }
01356
01357
01358 Bool_t TGeoConeSeg::Contains(Double_t *point) const
01359 {
01360
01361 if (!TGeoCone::Contains(point)) return kFALSE;
01362 Double_t dphi = fPhi2 - fPhi1;
01363 if (dphi >= 360.) return kTRUE;
01364 Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
01365 if (phi < 0 ) phi+=360.;
01366 Double_t ddp = phi-fPhi1;
01367 if (ddp < 0) ddp+=360.;
01368
01369 if (ddp > dphi) return kFALSE;
01370 return kTRUE;
01371 }
01372
01373
01374 Double_t TGeoConeSeg::DistToCons(Double_t *point, Double_t *dir, Double_t r1, Double_t z1, Double_t r2, Double_t z2, Double_t phi1, Double_t phi2)
01375 {
01376
01377
01378
01379
01380 Double_t dz = z2-z1;
01381 if (dz<=0) {
01382 return TGeoShape::Big();
01383 }
01384
01385 Double_t dphi = phi2 - phi1;
01386 Bool_t hasphi = kTRUE;
01387 if (dphi >= 360.) hasphi=kFALSE;
01388 if (dphi < 0) dphi+=360.;
01389
01390
01391 Double_t ro0 = 0.5*(r1+r2);
01392 Double_t fz = (r2-r1)/dz;
01393 Double_t r0sq = point[0]*point[0] + point[1]*point[1];
01394 Double_t rc = ro0 + fz*(point[2]-0.5*(z1+z2));
01395
01396 Double_t a = dir[0]*dir[0] + dir[1]*dir[1] - fz*fz*dir[2]*dir[2];
01397 Double_t b = point[0]*dir[0] + point[1]*dir[1] - fz*rc*dir[2];
01398 Double_t c = r0sq - rc*rc;
01399
01400 if (a==0) return TGeoShape::Big();
01401 a = 1./a;
01402 b *= a;
01403 c *= a;
01404 Double_t delta = b*b - c;
01405 if (delta<0) return TGeoShape::Big();
01406 delta = TMath::Sqrt(delta);
01407
01408 Double_t snxt = -b-delta;
01409 Double_t ptnew[3];
01410 Double_t ddp, phi;
01411 if (snxt>0) {
01412
01413 ptnew[2] = point[2] + snxt*dir[2];
01414 if (((ptnew[2]-z1)*(ptnew[2]-z2)) < 0) {
01415
01416 if (!hasphi) return snxt;
01417 ptnew[0] = point[0] + snxt*dir[0];
01418 ptnew[1] = point[1] + snxt*dir[1];
01419 phi = TMath::ATan2(ptnew[1], ptnew[0]) * TMath::RadToDeg();
01420 if (phi < 0 ) phi+=360.;
01421 ddp = phi-phi1;
01422 if (ddp < 0) ddp+=360.;
01423
01424 if (ddp<=dphi) return snxt;
01425 }
01426 }
01427 snxt = -b+delta;
01428 if (snxt>0) {
01429
01430 ptnew[2] = point[2] + snxt*dir[2];
01431 if (((ptnew[2]-z1)*(ptnew[2]-z2)) < 0) {
01432
01433 if (!hasphi) return snxt;
01434 ptnew[0] = point[0] + snxt*dir[0];
01435 ptnew[1] = point[1] + snxt*dir[1];
01436 phi = TMath::ATan2(ptnew[1], ptnew[0]) * TMath::RadToDeg();
01437 if (phi < 0 ) phi+=360.;
01438 ddp = phi-phi1;
01439 if (ddp < 0) ddp+=360.;
01440
01441 if (ddp<=dphi) return snxt;
01442 }
01443 }
01444 return TGeoShape::Big();
01445 }
01446
01447
01448 Double_t TGeoConeSeg::DistFromInsideS(Double_t *point, Double_t *dir, Double_t dz,
01449 Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2,
01450 Double_t c1, Double_t s1, Double_t c2, Double_t s2, Double_t cm, Double_t sm, Double_t cdfi)
01451 {
01452
01453 if (dz<=0) return TGeoShape::Big();
01454
01455 Double_t scone = TGeoCone::DistFromInsideS(point,dir,dz,rmin1,rmax1,rmin2,rmax2);
01456 if (scone<=0) return 0.0;
01457 Double_t sfmin = TGeoShape::Big();
01458 Double_t rsq = point[0]*point[0]+point[1]*point[1];
01459 Double_t r = TMath::Sqrt(rsq);
01460 Double_t cpsi=point[0]*cm+point[1]*sm;
01461 if (cpsi>r*cdfi+TGeoShape::Tolerance()) {
01462 sfmin = TGeoShape::DistToPhiMin(point, dir, s1, c1, s2, c2, sm, cm);
01463 return TMath::Min(scone,sfmin);
01464 }
01465
01466
01467 Double_t ddotn, xi, yi;
01468 if (TMath::Abs(point[1]-s1*r) < TMath::Abs(point[1]-s2*r)) {
01469 ddotn = s1*dir[0]-c1*dir[1];
01470 if (ddotn>=0) return 0.0;
01471 ddotn = -s2*dir[0]+c2*dir[1];
01472 if (ddotn<=0) return scone;
01473 sfmin = s2*point[0]-c2*point[1];
01474 if (sfmin<=0) return scone;
01475 sfmin /= ddotn;
01476 if (sfmin >= scone) return scone;
01477 xi = point[0]+sfmin*dir[0];
01478 yi = point[1]+sfmin*dir[1];
01479 if (yi*cm-xi*sm<0) return scone;
01480 return sfmin;
01481 }
01482 ddotn = -s2*dir[0]+c2*dir[1];
01483 if (ddotn>=0) return 0.0;
01484 ddotn = s1*dir[0]-c1*dir[1];
01485 if (ddotn<=0) return scone;
01486 sfmin = -s1*point[0]+c1*point[1];
01487 if (sfmin<=0) return scone;
01488 sfmin /= ddotn;
01489 if (sfmin >= scone) return scone;
01490 xi = point[0]+sfmin*dir[0];
01491 yi = point[1]+sfmin*dir[1];
01492 if (yi*cm-xi*sm>0) return scone;
01493 return sfmin;
01494 }
01495
01496
01497 Double_t TGeoConeSeg::DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
01498 {
01499
01500 if (iact<3 && safe) {
01501 *safe = TGeoConeSeg::SafetyS(point, kTRUE, fDz,fRmin1,fRmax1,fRmin2,fRmax2,fPhi1,fPhi2);
01502 if (iact==0) return TGeoShape::Big();
01503 if ((iact==1) && (*safe>step)) return TGeoShape::Big();
01504 }
01505 if ((fPhi2-fPhi1)>=360.) return TGeoCone::DistFromInsideS(point,dir,fDz,fRmin1,fRmax1,fRmin2,fRmax2);
01506 Double_t phi1 = fPhi1*TMath::DegToRad();
01507 Double_t phi2 = fPhi2*TMath::DegToRad();
01508 Double_t c1 = TMath::Cos(phi1);
01509 Double_t c2 = TMath::Cos(phi2);
01510 Double_t s1 = TMath::Sin(phi1);
01511 Double_t s2 = TMath::Sin(phi2);
01512 Double_t phim = 0.5*(phi1+phi2);
01513 Double_t cm = TMath::Cos(phim);
01514 Double_t sm = TMath::Sin(phim);
01515 Double_t dfi = 0.5*(phi2-phi1);
01516 Double_t cdfi = TMath::Cos(dfi);
01517
01518
01519 return TGeoConeSeg::DistFromInsideS(point,dir,fDz,fRmin1,fRmax1,fRmin2,fRmax2,c1,s1,c2,s2,cm,sm,cdfi);
01520 }
01521
01522
01523 Double_t TGeoConeSeg::DistFromOutsideS(Double_t *point, Double_t *dir, Double_t dz,
01524 Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2,
01525 Double_t c1, Double_t s1, Double_t c2, Double_t s2, Double_t cm, Double_t sm, Double_t cdfi)
01526 {
01527
01528 if (dz<=0) return TGeoShape::Big();
01529 Double_t r2, cpsi;
01530
01531 Double_t xi, yi, zi;
01532 Double_t b,delta;
01533 zi = dz - TMath::Abs(point[2]);
01534 Double_t rin,rout;
01535 Double_t s = TGeoShape::Big();
01536 Double_t snxt=TGeoShape::Big();
01537 Bool_t in = kFALSE;
01538 Bool_t inz = (zi<0)?kFALSE:kTRUE;
01539 if (!inz) {
01540 if (point[2]*dir[2]>=0) return TGeoShape::Big();
01541 s = -zi/TMath::Abs(dir[2]);
01542 xi = point[0]+s*dir[0];
01543 yi = point[1]+s*dir[1];
01544 r2=xi*xi+yi*yi;
01545 if (dir[2]>0) {
01546 rin = rmin1;
01547 rout = rmax1;
01548 } else {
01549 rin = rmin2;
01550 rout = rmax2;
01551 }
01552 if ((rin*rin<=r2) && (r2<=rout*rout)) {
01553 cpsi=xi*cm+yi*sm;
01554 if (cpsi>=(cdfi*TMath::Sqrt(r2))) return s;
01555 }
01556 }
01557 Double_t zinv = 1./dz;
01558 Double_t rsq = point[0]*point[0]+point[1]*point[1];
01559 Double_t r = TMath::Sqrt(rsq);
01560 Double_t ro1=0.5*(rmin1+rmin2);
01561 Bool_t hasrmin = (ro1>0)?kTRUE:kFALSE;
01562 Double_t tg1 = 0.0;
01563 Bool_t inrmin = kFALSE;
01564 rin = 0.0;
01565 if (hasrmin) {
01566 tg1=0.5*(rmin2-rmin1)*zinv;
01567 rin = ro1+tg1*point[2];
01568 if (rsq > rin*(rin-TGeoShape::Tolerance())) inrmin=kTRUE;
01569 } else {
01570 inrmin = kTRUE;
01571 }
01572 Double_t ro2=0.5*(rmax1+rmax2);
01573 Double_t tg2=0.5*(rmax2-rmax1)*zinv;
01574 rout = ro2+tg2*point[2];
01575 Bool_t inrmax = kFALSE;
01576 if (rsq < rout*(rout+TGeoShape::Tolerance())) inrmax = kTRUE;
01577 Bool_t inphi = kFALSE;
01578 cpsi=point[0]*cm+point[1]*sm;
01579 if (cpsi>r*cdfi-TGeoShape::Tolerance()) inphi = kTRUE;
01580 in = inz & inrmin & inrmax & inphi;
01581
01582 if (in) {
01583 Double_t safphi = (cpsi-r*cdfi)*TMath::Sqrt(1.-cdfi*cdfi);
01584 Double_t safrmin = (hasrmin)?TMath::Abs(r-rin):(TGeoShape::Big());
01585 Double_t safrmax = TMath::Abs(r-rout);
01586
01587 if (zi<safrmax && zi<safrmin && zi<safphi) {
01588 if (point[2]*dir[2]<0) return 0.0;
01589 return TGeoShape::Big();
01590 }
01591
01592 if (safrmax<safrmin && safrmax<safphi) {
01593 Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg2*dir[2]*r;
01594 if (ddotn<=0) return 0.0;
01595 return TGeoShape::Big();
01596 }
01597
01598 if (safphi<safrmin) {
01599
01600
01601 Double_t un;
01602 if (TMath::Abs(point[1]-s1*r) < TMath::Abs(point[1]-s2*r)) {
01603 un = dir[0]*s1-dir[1]*c1;
01604 if (un < 0) return 0.0;
01605 if (cdfi>=0) return TGeoShape::Big();
01606 un = -dir[0]*s2+dir[1]*c2;
01607 if (un<0) {
01608 s = -point[0]*s2+point[1]*c2;
01609 if (s>0) {
01610 s /= (-un);
01611 zi = point[2]+s*dir[2];
01612 if (TMath::Abs(zi)<=dz) {
01613 xi = point[0]+s*dir[0];
01614 yi = point[1]+s*dir[1];
01615 if ((yi*cm-xi*sm)>0) {
01616 r2=xi*xi+yi*yi;
01617 rin = ro1+tg1*zi;
01618 rout = ro2+tg2*zi;
01619 if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
01620 }
01621 }
01622 }
01623 }
01624 } else {
01625 un = -dir[0]*s2+dir[1]*c2;
01626 if (un < 0) return 0.0;
01627 if (cdfi>=0) return TGeoShape::Big();
01628 un = dir[0]*s1-dir[1]*c1;
01629 if (un<0) {
01630 s = point[0]*s1-point[1]*c1;
01631 if (s>0) {
01632 s /= (-un);
01633 zi = point[2]+s*dir[2];
01634 if (TMath::Abs(zi)<=dz) {
01635 xi = point[0]+s*dir[0];
01636 yi = point[1]+s*dir[1];
01637 if ((yi*cm-xi*sm)<0) {
01638 r2=xi*xi+yi*yi;
01639 rin = ro1+tg1*zi;
01640 rout = ro2+tg2*zi;
01641 if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
01642 }
01643 }
01644 }
01645 }
01646 }
01647
01648 Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg1*dir[2]*r;
01649 if (ddotn>=0) return TGeoShape::Big();
01650 if (cdfi>=0) return TGeoShape::Big();
01651 TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
01652 if (delta<0) return TGeoShape::Big();
01653 snxt = -b-delta;
01654 if (snxt<0) return TGeoShape::Big();
01655 snxt = -b+delta;
01656 zi = point[2]+snxt*dir[2];
01657 if (TMath::Abs(zi)>dz) return TGeoShape::Big();
01658 xi = point[0]+snxt*dir[0];
01659 yi = point[1]+snxt*dir[1];
01660 r2=xi*xi+yi*yi;
01661 cpsi=xi*cm+yi*sm;
01662 if (cpsi>=(cdfi*TMath::Sqrt(r2))) return snxt;
01663 return TGeoShape::Big();
01664 }
01665
01666 Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg1*dir[2]*r;
01667 if (ddotn>=0) return 0.0;
01668 TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
01669 if (delta<0) return 0.0;
01670 snxt = -b+delta;
01671 if (snxt<0) return TGeoShape::Big();
01672 if (TMath::Abs(-b-delta)>snxt) return TGeoShape::Big();
01673 zi = point[2]+snxt*dir[2];
01674 if (TMath::Abs(zi)>dz) return TGeoShape::Big();
01675
01676 xi = point[0]+snxt*dir[0];
01677 yi = point[1]+snxt*dir[1];
01678 r2=xi*xi+yi*yi;
01679 cpsi=xi*cm+yi*sm;
01680 if (cpsi>=(cdfi*TMath::Sqrt(r2))) return snxt;
01681
01682 if (cdfi>=0) return TGeoShape::Big();
01683 Double_t un=-dir[0]*s1+dir[1]*c1;
01684 if (un > 0) {
01685 s=point[0]*s1-point[1]*c1;
01686 if (s>=0) {
01687 s /= un;
01688 zi=point[2]+s*dir[2];
01689 if (TMath::Abs(zi)<=dz) {
01690 xi=point[0]+s*dir[0];
01691 yi=point[1]+s*dir[1];
01692 if ((yi*cm-xi*sm)<=0) {
01693 r2=xi*xi+yi*yi;
01694 rin = ro1+tg1*zi;
01695 rout = ro2+tg2*zi;
01696 if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
01697 }
01698 }
01699 }
01700 }
01701 un=dir[0]*s2-dir[1]*c2;
01702 if (un > 0) {
01703 s=(point[1]*c2-point[0]*s2)/un;
01704 if (s>=0) {
01705 zi=point[2]+s*dir[2];
01706 if (TMath::Abs(zi)<=dz) {
01707 xi=point[0]+s*dir[0];
01708 yi=point[1]+s*dir[1];
01709 if ((yi*cm-xi*sm)>=0) {
01710 r2=xi*xi+yi*yi;
01711 rin = ro1+tg1*zi;
01712 rout = ro2+tg2*zi;
01713 if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
01714 }
01715 }
01716 }
01717 }
01718 return TGeoShape::Big();
01719 }
01720
01721
01722 Double_t sr1 = TGeoShape::Big();
01723 if (!inrmax) {
01724
01725 TGeoCone::DistToCone(point, dir, dz, rmax1, rmax2, b, delta);
01726 if (delta>=0) {
01727 s = -b-delta;
01728 if (s>0) {
01729 zi=point[2]+s*dir[2];
01730 if (TMath::Abs(zi)<=dz) {
01731 xi=point[0]+s*dir[0];
01732 yi=point[1]+s*dir[1];
01733 r2=xi*xi+yi*yi;
01734 cpsi=xi*cm+yi*sm;
01735 if (cpsi>=(cdfi*TMath::Sqrt(r2))) return s;
01736 }
01737 }
01738 s = -b+delta;
01739 if (s>0) {
01740 zi=point[2]+s*dir[2];
01741 if (TMath::Abs(zi)<=dz) {
01742 xi=point[0]+s*dir[0];
01743 yi=point[1]+s*dir[1];
01744 r2=xi*xi+yi*yi;
01745 cpsi=xi*cm+yi*sm;
01746 if (cpsi>=(cdfi*TMath::Sqrt(r2))) sr1=s;
01747 }
01748 }
01749 }
01750 }
01751
01752 Double_t sr2 = TGeoShape::Big();
01753 TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
01754 if (delta>=0) {
01755 s = -b-delta;
01756 if (s>0) {
01757 zi=point[2]+s*dir[2];
01758 if (TMath::Abs(zi)<=dz) {
01759 xi=point[0]+s*dir[0];
01760 yi=point[1]+s*dir[1];
01761 r2=xi*xi+yi*yi;
01762 cpsi=xi*cm+yi*sm;
01763 if (cpsi>=(cdfi*TMath::Sqrt(r2))) sr2=s;
01764 }
01765 }
01766 if (sr2>1E10) {
01767 s = -b+delta;
01768 if (s>0) {
01769 zi=point[2]+s*dir[2];
01770 if (TMath::Abs(zi)<=dz) {
01771 xi=point[0]+s*dir[0];
01772 yi=point[1]+s*dir[1];
01773 r2=xi*xi+yi*yi;
01774 cpsi=xi*cm+yi*sm;
01775 if (cpsi>=(cdfi*TMath::Sqrt(r2))) sr2=s;
01776 }
01777 }
01778 }
01779 }
01780 snxt = TMath::Min(sr1,sr2);
01781
01782 s = TGeoShape::DistToPhiMin(point,dir,s1,c1,s2,c2,sm,cm,kFALSE);
01783 if (s>snxt) return snxt;
01784 zi=point[2]+s*dir[2];
01785 if (TMath::Abs(zi)>dz) return snxt;
01786 xi=point[0]+s*dir[0];
01787 yi=point[1]+s*dir[1];
01788 r2=xi*xi+yi*yi;
01789 rout = ro2+tg2*zi;
01790 if (r2>rout*rout) return snxt;
01791 rin = ro1+tg1*zi;
01792 if (r2>=rin*rin) return s;
01793 return snxt;
01794 }
01795
01796
01797 Double_t TGeoConeSeg::DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
01798 {
01799
01800
01801 if (iact<3 && safe) {
01802 *safe = Safety(point, kFALSE);
01803 if (iact==0) return TGeoShape::Big();
01804 if ((iact==1) && (*safe>step)) return TGeoShape::Big();
01805 }
01806
01807 Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
01808 if (sdist>=step) return TGeoShape::Big();
01809 if ((fPhi2-fPhi1)>=360.) return TGeoCone::DistFromOutsideS(point,dir,fDz,fRmin1,fRmax1,fRmin2,fRmax2);
01810 Double_t phi1 = fPhi1*TMath::DegToRad();
01811 Double_t phi2 = fPhi2*TMath::DegToRad();
01812 Double_t c1 = TMath::Cos(phi1);
01813 Double_t c2 = TMath::Cos(phi2);
01814 Double_t s1 = TMath::Sin(phi1);
01815 Double_t s2 = TMath::Sin(phi2);
01816 Double_t phim = 0.5*(phi1+phi2);
01817 Double_t cm = TMath::Cos(phim);
01818 Double_t sm = TMath::Sin(phim);
01819 Double_t dfi = 0.5*(phi2-phi1);
01820 Double_t cdfi = TMath::Cos(dfi);
01821 return TGeoConeSeg::DistFromOutsideS(point,dir,fDz,fRmin1,fRmax1,fRmin2,fRmax2,c1,s1,c2,s2,cm,sm,cdfi);
01822 }
01823
01824
01825 Int_t TGeoConeSeg::DistancetoPrimitive(Int_t px, Int_t py)
01826 {
01827
01828 Int_t n = gGeoManager->GetNsegments()+1;
01829 const Int_t numPoints = 4*n;
01830 return ShapeDistancetoPrimitive(numPoints, px, py);
01831 }
01832
01833
01834 TGeoVolume *TGeoConeSeg::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv,
01835 Double_t start, Double_t step)
01836 {
01837
01838
01839
01840
01841
01842
01843 TGeoShape *shape;
01844 TGeoVolume *vol;
01845 TGeoVolumeMulti *vmulti;
01846 TGeoPatternFinder *finder;
01847 TString opt = "";
01848 Double_t dphi;
01849 Int_t id;
01850 Double_t end = start+ndiv*step;
01851 switch (iaxis) {
01852 case 1:
01853 Error("Divide","division of a cone segment on R not implemented");
01854 return 0;
01855 case 2:
01856 dphi = fPhi2-fPhi1;
01857 if (dphi<0) dphi+=360.;
01858 finder = new TGeoPatternCylPhi(voldiv, ndiv, start, end);
01859 voldiv->SetFinder(finder);
01860 finder->SetDivIndex(voldiv->GetNdaughters());
01861 shape = new TGeoConeSeg(fDz, fRmin1, fRmax1, fRmin2, fRmax2, -step/2, step/2);
01862 vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
01863 vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
01864 vmulti->AddVolume(vol);
01865 opt = "Phi";
01866 for (id=0; id<ndiv; id++) {
01867 voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
01868 ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
01869 }
01870 return vmulti;
01871 case 3:
01872 finder = new TGeoPatternZ(voldiv, ndiv, start, end);
01873 vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
01874 voldiv->SetFinder(finder);
01875 finder->SetDivIndex(voldiv->GetNdaughters());
01876 for (id=0; id<ndiv; id++) {
01877 Double_t z1 = start+id*step;
01878 Double_t z2 = start+(id+1)*step;
01879 Double_t rmin1n = 0.5*(fRmin1*(fDz-z1)+fRmin2*(fDz+z1))/fDz;
01880 Double_t rmax1n = 0.5*(fRmax1*(fDz-z1)+fRmax2*(fDz+z1))/fDz;
01881 Double_t rmin2n = 0.5*(fRmin1*(fDz-z2)+fRmin2*(fDz+z2))/fDz;
01882 Double_t rmax2n = 0.5*(fRmax1*(fDz-z2)+fRmax2*(fDz+z2))/fDz;
01883 shape = new TGeoConeSeg(step/2, rmin1n, rmax1n, rmin2n, rmax2n, fPhi1, fPhi2);
01884 vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
01885 vmulti->AddVolume(vol);
01886 opt = "Z";
01887 voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
01888 ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
01889 }
01890 return vmulti;
01891 default:
01892 Error("Divide", "Wrong axis type for division");
01893 return 0;
01894 }
01895 }
01896
01897
01898 Double_t TGeoConeSeg::GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
01899 {
01900
01901 xlo = 0;
01902 xhi = 0;
01903 Double_t dx = 0;
01904 switch (iaxis) {
01905 case 2:
01906 xlo = fPhi1;
01907 xhi = fPhi2;
01908 dx = xhi-xlo;
01909 return dx;
01910 case 3:
01911 xlo = -fDz;
01912 xhi = fDz;
01913 dx = xhi-xlo;
01914 return dx;
01915 }
01916 return dx;
01917 }
01918
01919
01920 void TGeoConeSeg::GetBoundingCylinder(Double_t *param) const
01921 {
01922
01923
01924 param[0] = TMath::Min(fRmin1, fRmin2);
01925 param[0] *= param[0];
01926 param[1] = TMath::Max(fRmax1, fRmax2);
01927 param[1] *= param[1];
01928 param[2] = (fPhi1<0)?(fPhi1+360.):fPhi1;
01929 param[3] = fPhi2;
01930 while (param[3]<param[2]) param[3]+=360.;
01931 }
01932
01933
01934 TGeoShape *TGeoConeSeg::GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix * ) const
01935 {
01936
01937
01938 if (!TestShapeBit(kGeoRunTimeShape)) return 0;
01939 if (!mother->TestShapeBit(kGeoConeSeg)) {
01940 Error("GetMakeRuntimeShape", "invalid mother");
01941 return 0;
01942 }
01943 Double_t rmin1, rmax1, rmin2, rmax2, dz;
01944 rmin1 = fRmin1;
01945 rmax1 = fRmax1;
01946 rmin2 = fRmin2;
01947 rmax2 = fRmax2;
01948 dz = fDz;
01949 if (fDz<0) dz=((TGeoCone*)mother)->GetDz();
01950 if (fRmin1<0)
01951 rmin1 = ((TGeoCone*)mother)->GetRmin1();
01952 if ((fRmax1<0) || (fRmax1<fRmin1))
01953 rmax1 = ((TGeoCone*)mother)->GetRmax1();
01954 if (fRmin2<0)
01955 rmin2 = ((TGeoCone*)mother)->GetRmin2();
01956 if ((fRmax2<0) || (fRmax2<fRmin2))
01957 rmax2 = ((TGeoCone*)mother)->GetRmax2();
01958
01959 return (new TGeoConeSeg(GetName(), dz, rmin1, rmax1, rmin2, rmax2, fPhi1, fPhi2));
01960 }
01961
01962
01963 void TGeoConeSeg::InspectShape() const
01964 {
01965
01966 printf("*** Shape %s: TGeoConeSeg ***\n", GetName());
01967 printf(" dz = %11.5f\n", fDz);
01968 printf(" Rmin1 = %11.5f\n", fRmin1);
01969 printf(" Rmax1 = %11.5f\n", fRmax1);
01970 printf(" Rmin2 = %11.5f\n", fRmin2);
01971 printf(" Rmax2 = %11.5f\n", fRmax2);
01972 printf(" phi1 = %11.5f\n", fPhi1);
01973 printf(" phi2 = %11.5f\n", fPhi2);
01974 printf(" Bounding box:\n");
01975 TGeoBBox::InspectShape();
01976 }
01977
01978
01979 TBuffer3D *TGeoConeSeg::MakeBuffer3D() const
01980 {
01981
01982
01983
01984 Int_t n = gGeoManager->GetNsegments()+1;
01985 Int_t nbPnts = 4*n;
01986 Int_t nbSegs = 2*nbPnts;
01987 Int_t nbPols = nbPnts-2;
01988 TBuffer3D* buff = new TBuffer3D(TBuffer3DTypes::kGeneric,
01989 nbPnts, 3*nbPnts,
01990 nbSegs, 3*nbSegs,
01991 nbPols, 6*nbPols);
01992
01993 if (buff)
01994 {
01995 SetPoints(buff->fPnts);
01996 SetSegsAndPols(*buff);
01997 }
01998
01999 return buff;
02000 }
02001
02002
02003 void TGeoConeSeg::SetSegsAndPols(TBuffer3D &buffer) const
02004 {
02005
02006 Int_t i, j;
02007 Int_t n = gGeoManager->GetNsegments()+1;
02008 Int_t c = GetBasicColor();
02009
02010 memset(buffer.fSegs, 0, buffer.NbSegs()*3*sizeof(Int_t));
02011 for (i = 0; i < 4; i++) {
02012 for (j = 1; j < n; j++) {
02013 buffer.fSegs[(i*n+j-1)*3 ] = c;
02014 buffer.fSegs[(i*n+j-1)*3+1] = i*n+j-1;
02015 buffer.fSegs[(i*n+j-1)*3+2] = i*n+j;
02016 }
02017 }
02018 for (i = 4; i < 6; i++) {
02019 for (j = 0; j < n; j++) {
02020 buffer.fSegs[(i*n+j)*3 ] = c+1;
02021 buffer.fSegs[(i*n+j)*3+1] = (i-4)*n+j;
02022 buffer.fSegs[(i*n+j)*3+2] = (i-2)*n+j;
02023 }
02024 }
02025 for (i = 6; i < 8; i++) {
02026 for (j = 0; j < n; j++) {
02027 buffer.fSegs[(i*n+j)*3 ] = c;
02028 buffer.fSegs[(i*n+j)*3+1] = 2*(i-6)*n+j;
02029 buffer.fSegs[(i*n+j)*3+2] = (2*(i-6)+1)*n+j;
02030 }
02031 }
02032
02033 Int_t indx = 0;
02034 memset(buffer.fPols, 0, buffer.NbPols()*6*sizeof(Int_t));
02035 i = 0;
02036 for (j = 0; j < n-1; j++) {
02037 buffer.fPols[indx++] = c;
02038 buffer.fPols[indx++] = 4;
02039 buffer.fPols[indx++] = (4+i)*n+j+1;
02040 buffer.fPols[indx++] = (2+i)*n+j;
02041 buffer.fPols[indx++] = (4+i)*n+j;
02042 buffer.fPols[indx++] = i*n+j;
02043 }
02044 i = 1;
02045 for (j = 0; j < n-1; j++) {
02046 buffer.fPols[indx++] = c;
02047 buffer.fPols[indx++] = 4;
02048 buffer.fPols[indx++] = i*n+j;
02049 buffer.fPols[indx++] = (4+i)*n+j;
02050 buffer.fPols[indx++] = (2+i)*n+j;
02051 buffer.fPols[indx++] = (4+i)*n+j+1;
02052 }
02053 i = 2;
02054 for (j = 0; j < n-1; j++) {
02055 buffer.fPols[indx++] = c+i;
02056 buffer.fPols[indx++] = 4;
02057 buffer.fPols[indx++] = (i-2)*2*n+j;
02058 buffer.fPols[indx++] = (4+i)*n+j;
02059 buffer.fPols[indx++] = ((i-2)*2+1)*n+j;
02060 buffer.fPols[indx++] = (4+i)*n+j+1;
02061 }
02062 i = 3;
02063 for (j = 0; j < n-1; j++) {
02064 buffer.fPols[indx++] = c+i;
02065 buffer.fPols[indx++] = 4;
02066 buffer.fPols[indx++] = (4+i)*n+j+1;
02067 buffer.fPols[indx++] = ((i-2)*2+1)*n+j;
02068 buffer.fPols[indx++] = (4+i)*n+j;
02069 buffer.fPols[indx++] = (i-2)*2*n+j;
02070 }
02071 buffer.fPols[indx++] = c+2;
02072 buffer.fPols[indx++] = 4;
02073 buffer.fPols[indx++] = 6*n;
02074 buffer.fPols[indx++] = 4*n;
02075 buffer.fPols[indx++] = 7*n;
02076 buffer.fPols[indx++] = 5*n;
02077 buffer.fPols[indx++] = c+2;
02078 buffer.fPols[indx++] = 4;
02079 buffer.fPols[indx++] = 6*n-1;
02080 buffer.fPols[indx++] = 8*n-1;
02081 buffer.fPols[indx++] = 5*n-1;
02082 buffer.fPols[indx++] = 7*n-1;
02083 }
02084
02085
02086 Double_t TGeoConeSeg::Safety(Double_t *point, Bool_t in) const
02087 {
02088
02089
02090
02091 Double_t saf[3];
02092 Double_t ro1 = 0.5*(fRmin1+fRmin2);
02093 Double_t tg1 = 0.5*(fRmin2-fRmin1)/fDz;
02094 Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
02095 Double_t ro2 = 0.5*(fRmax1+fRmax2);
02096 Double_t tg2 = 0.5*(fRmax2-fRmax1)/fDz;
02097 Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
02098
02099 Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
02100 Double_t rin = tg1*point[2]+ro1;
02101 Double_t rout = tg2*point[2]+ro2;
02102 Double_t safe = TGeoShape::Big();
02103 if (in) {
02104 saf[0] = fDz-TMath::Abs(point[2]);
02105 saf[1] = (r-rin)*cr1;
02106 saf[2] = (rout-r)*cr2;
02107 safe = saf[TMath::LocMin(3,saf)];
02108 } else {
02109 saf[0] = TMath::Abs(point[2])-fDz;
02110 saf[1] = (rin-r)*cr1;
02111 saf[2] = (r-rout)*cr2;
02112 safe = saf[TMath::LocMax(3,saf)];
02113 }
02114 if ((fPhi2-fPhi1)>=360.) return safe;
02115 Double_t safphi = TGeoShape::SafetyPhi(point, in, fPhi1, fPhi2);
02116
02117 if (in) return TMath::Min(safe, safphi);
02118 return TMath::Max(safe, safphi);
02119 }
02120
02121
02122 Double_t TGeoConeSeg::SafetyS(Double_t *point, Bool_t in, Double_t dz, Double_t rmin1, Double_t rmax1,
02123 Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2, Int_t skipz)
02124 {
02125
02126 Double_t saf[3];
02127 Double_t ro1 = 0.5*(rmin1+rmin2);
02128 Double_t tg1 = 0.5*(rmin2-rmin1)/dz;
02129 Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
02130 Double_t ro2 = 0.5*(rmax1+rmax2);
02131 Double_t tg2 = 0.5*(rmax2-rmax1)/dz;
02132 Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
02133
02134 Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
02135 Double_t rin = tg1*point[2]+ro1;
02136 Double_t rout = tg2*point[2]+ro2;
02137
02138 Double_t safe = TGeoShape::Big();
02139 switch (skipz) {
02140 case 1:
02141 saf[0] = dz - point[2];
02142 break;
02143 case 2:
02144 saf[0] = dz + point[2];
02145 break;
02146 case 3:
02147 saf[0] = TGeoShape::Big();
02148 break;
02149 default:
02150 saf[0] = dz-TMath::Abs(point[2]);
02151 }
02152 saf[1] = (r-rin)*cr1;
02153 saf[2] = (rout-r)*cr2;
02154 Double_t safphi = TGeoShape::SafetyPhi(point,in,phi1,phi2);
02155 if (in) {
02156 safe = saf[TMath::LocMin(3,saf)];
02157 return TMath::Min(safe,safphi);
02158 }
02159 for (Int_t i=0; i<3; i++) saf[i]=-saf[i];
02160 safe = saf[TMath::LocMax(3,saf)];
02161 return TMath::Max(safe,safphi);
02162 }
02163
02164
02165 void TGeoConeSeg::SavePrimitive(ostream &out, Option_t * )
02166 {
02167
02168 if (TObject::TestBit(kGeoSavePrimitive)) return;
02169 out << " // Shape: " << GetName() << " type: " << ClassName() << endl;
02170 out << " dz = " << fDz << ";" << endl;
02171 out << " rmin1 = " << fRmin1 << ";" << endl;
02172 out << " rmax1 = " << fRmax1 << ";" << endl;
02173 out << " rmin2 = " << fRmin2 << ";" << endl;
02174 out << " rmax2 = " << fRmax2 << ";" << endl;
02175 out << " phi1 = " << fPhi1 << ";" << endl;
02176 out << " phi2 = " << fPhi2 << ";" << endl;
02177 out << " TGeoShape *" << GetPointerName() << " = new TGeoConeSeg(\"" << GetName() << "\", dz,rmin1,rmax1,rmin2,rmax2,phi1,phi2);" << endl;
02178 TObject::SetBit(TGeoShape::kGeoSavePrimitive);
02179 }
02180
02181
02182 void TGeoConeSeg::SetConsDimensions(Double_t dz, Double_t rmin1, Double_t rmax1,
02183 Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
02184 {
02185
02186 fDz = dz;
02187 fRmin1 = rmin1;
02188 fRmax1 = rmax1;
02189 fRmin2 = rmin2;
02190 fRmax2 = rmax2;
02191 fPhi1 = phi1;
02192 if (fPhi1<0) fPhi1+=360.;
02193 fPhi2 = phi2;
02194 while (fPhi2<=fPhi1) fPhi2+=360.;
02195 if (TGeoShape::IsSameWithinTolerance(fPhi1,fPhi2)) Error("SetConsDimensions", "In shape %s invalid phi1=%g, phi2=%g\n", GetName(), fPhi1, fPhi2);
02196 }
02197
02198
02199 void TGeoConeSeg::SetDimensions(Double_t *param)
02200 {
02201
02202 Double_t dz = param[0];
02203 Double_t rmin1 = param[1];
02204 Double_t rmax1 = param[2];
02205 Double_t rmin2 = param[3];
02206 Double_t rmax2 = param[4];
02207 Double_t phi1 = param[5];
02208 Double_t phi2 = param[6];
02209 SetConsDimensions(dz, rmin1, rmax1,rmin2, rmax2, phi1, phi2);
02210 }
02211
02212
02213 void TGeoConeSeg::SetPoints(Double_t *points) const
02214 {
02215
02216 Int_t j, n;
02217 Float_t dphi,phi,phi1, phi2,dz;
02218
02219 n = gGeoManager->GetNsegments()+1;
02220 dz = fDz;
02221 phi1 = fPhi1;
02222 phi2 = fPhi2;
02223
02224 dphi = (phi2-phi1)/(n-1);
02225
02226 Int_t indx = 0;
02227
02228 if (points) {
02229 for (j = 0; j < n; j++) {
02230 phi = (fPhi1+j*dphi)*TMath::DegToRad();
02231 points[indx++] = fRmin1 * TMath::Cos(phi);
02232 points[indx++] = fRmin1 * TMath::Sin(phi);
02233 points[indx++] = -dz;
02234 }
02235 for (j = 0; j < n; j++) {
02236 phi = (fPhi1+j*dphi)*TMath::DegToRad();
02237 points[indx++] = fRmax1 * TMath::Cos(phi);
02238 points[indx++] = fRmax1 * TMath::Sin(phi);
02239 points[indx++] = -dz;
02240 }
02241 for (j = 0; j < n; j++) {
02242 phi = (fPhi1+j*dphi)*TMath::DegToRad();
02243 points[indx++] = fRmin2 * TMath::Cos(phi);
02244 points[indx++] = fRmin2 * TMath::Sin(phi);
02245 points[indx++] = dz;
02246 }
02247 for (j = 0; j < n; j++) {
02248 phi = (fPhi1+j*dphi)*TMath::DegToRad();
02249 points[indx++] = fRmax2 * TMath::Cos(phi);
02250 points[indx++] = fRmax2 * TMath::Sin(phi);
02251 points[indx++] = dz;
02252 }
02253 }
02254 }
02255
02256
02257 void TGeoConeSeg::SetPoints(Float_t *points) const
02258 {
02259
02260 Int_t j, n;
02261 Float_t dphi,phi,phi1, phi2,dz;
02262
02263 n = gGeoManager->GetNsegments()+1;
02264 dz = fDz;
02265 phi1 = fPhi1;
02266 phi2 = fPhi2;
02267
02268 dphi = (phi2-phi1)/(n-1);
02269
02270 Int_t indx = 0;
02271
02272 if (points) {
02273 for (j = 0; j < n; j++) {
02274 phi = (fPhi1+j*dphi)*TMath::DegToRad();
02275 points[indx++] = fRmin1 * TMath::Cos(phi);
02276 points[indx++] = fRmin1 * TMath::Sin(phi);
02277 points[indx++] = -dz;
02278 }
02279 for (j = 0; j < n; j++) {
02280 phi = (fPhi1+j*dphi)*TMath::DegToRad();
02281 points[indx++] = fRmax1 * TMath::Cos(phi);
02282 points[indx++] = fRmax1 * TMath::Sin(phi);
02283 points[indx++] = -dz;
02284 }
02285 for (j = 0; j < n; j++) {
02286 phi = (fPhi1+j*dphi)*TMath::DegToRad();
02287 points[indx++] = fRmin2 * TMath::Cos(phi);
02288 points[indx++] = fRmin2 * TMath::Sin(phi);
02289 points[indx++] = dz;
02290 }
02291 for (j = 0; j < n; j++) {
02292 phi = (fPhi1+j*dphi)*TMath::DegToRad();
02293 points[indx++] = fRmax2 * TMath::Cos(phi);
02294 points[indx++] = fRmax2 * TMath::Sin(phi);
02295 points[indx++] = dz;
02296 }
02297 }
02298 }
02299
02300
02301 void TGeoConeSeg::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
02302 {
02303
02304 Int_t n = gGeoManager->GetNsegments()+1;
02305 nvert = n*4;
02306 nsegs = n*8;
02307 npols = n*4-2;
02308 }
02309
02310
02311 Int_t TGeoConeSeg::GetNmeshVertices() const
02312 {
02313
02314 Int_t n = gGeoManager->GetNsegments()+1;
02315 Int_t numPoints = n*4;
02316 return numPoints;
02317 }
02318
02319
02320 void TGeoConeSeg::Sizeof3D() const
02321 {
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332 }
02333
02334
02335 const TBuffer3D & TGeoConeSeg::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
02336 {
02337
02338 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
02339
02340 TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
02341
02342 if (reqSections & TBuffer3D::kRawSizes) {
02343 Int_t n = gGeoManager->GetNsegments()+1;
02344 Int_t nbPnts = 4*n;
02345 Int_t nbSegs = 2*nbPnts;
02346 Int_t nbPols = nbPnts-2;
02347 if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
02348 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
02349 }
02350 }
02351 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
02352 SetPoints(buffer.fPnts);
02353 if (!buffer.fLocalFrame) {
02354 TransformPoints(buffer.fPnts, buffer.NbPnts());
02355 }
02356
02357 SetSegsAndPols(buffer);
02358 buffer.SetSectionsValid(TBuffer3D::kRaw);
02359 }
02360
02361 return buffer;
02362 }
02363
02364
02365 Bool_t TGeoConeSeg::GetPointsOnSegments(Int_t npoints, Double_t *array) const
02366 {
02367
02368
02369
02370 if (npoints > (npoints/2)*2) {
02371 Error("GetPointsOnSegments","Npoints must be even number");
02372 return kFALSE;
02373 }
02374 Int_t nc = (Int_t)TMath::Sqrt(0.5*npoints);
02375 Double_t dphi = (fPhi2-fPhi1)*TMath::DegToRad()/(nc-1);
02376 Double_t phi = 0;
02377 Double_t phi1 = fPhi1 * TMath::DegToRad();
02378 Int_t ntop = npoints/2 - nc*(nc-1);
02379 Double_t dz = 2*fDz/(nc-1);
02380 Double_t z = 0;
02381 Double_t rmin = 0.;
02382 Double_t rmax = 0.;
02383 Int_t icrt = 0;
02384 Int_t nphi = nc;
02385
02386 for (Int_t i=0; i<nc; i++) {
02387 if (i == (nc-1)) {
02388 nphi = ntop;
02389 dphi = (fPhi2-fPhi1)*TMath::DegToRad()/(nphi-1);
02390 }
02391 z = -fDz + i*dz;
02392 rmin = 0.5*(fRmin1+fRmin2) + 0.5*(fRmin2-fRmin1)*z/fDz;
02393 rmax = 0.5*(fRmax1+fRmax2) + 0.5*(fRmax2-fRmax1)*z/fDz;
02394
02395 for (Int_t j=0; j<nphi; j++) {
02396 phi = phi1 + j*dphi;
02397 array[icrt++] = rmin * TMath::Cos(phi);
02398 array[icrt++] = rmin * TMath::Sin(phi);
02399 array[icrt++] = z;
02400 array[icrt++] = rmax * TMath::Cos(phi);
02401 array[icrt++] = rmax * TMath::Sin(phi);
02402 array[icrt++] = z;
02403 }
02404 }
02405 return kTRUE;
02406 }