148 for (Int_t i=0; i<8; i++) {
152 SetShapeBit(kGeoArb8);
159 TGeoArb8::TGeoArb8(Double_t dz, Double_t *vertices)
163 SetShapeBit(kGeoArb8);
165 for (Int_t i=0; i<8; i++) {
166 fXY[i][0] = vertices[2*i];
167 fXY[i][1] = vertices[2*i+1];
172 for (Int_t i=0; i<8; i++) {
183 TGeoArb8::TGeoArb8(
const char *name, Double_t dz, Double_t *vertices)
184 :TGeoBBox(name, 0,0,0)
187 SetShapeBit(kGeoArb8);
189 for (Int_t i=0; i<8; i++) {
190 fXY[i][0] = vertices[2*i];
191 fXY[i][1] = vertices[2*i+1];
196 for (Int_t i=0; i<8; i++) {
206 TGeoArb8::TGeoArb8(
const TGeoArb8& ga8) :
210 for(Int_t i=0; i<8; i++) {
211 fXY[i][0]=ga8.fXY[i][0];
212 fXY[i][1]=ga8.fXY[i][1];
214 CopyTwist(ga8.fTwist);
220 TGeoArb8& TGeoArb8::operator=(
const TGeoArb8& ga8)
223 TGeoBBox::operator=(ga8);
225 CopyTwist(ga8.fTwist);
226 for(Int_t i=0; i<8; i++) {
227 fXY[i][0]=ga8.fXY[i][0];
228 fXY[i][1]=ga8.fXY[i][1];
237 TGeoArb8::~TGeoArb8()
239 if (fTwist)
delete [] fTwist;
245 void TGeoArb8::CopyTwist(Double_t *twist)
248 if (!fTwist) fTwist =
new Double_t[4];
249 memcpy(fTwist, twist, 4*
sizeof(Double_t));
259 Double_t TGeoArb8::Capacity()
const
262 Double_t capacity = 0;
263 for (i=0; i<4; i++) {
265 capacity += 0.25*fDz*((fXY[i][0]+fXY[i+4][0])*(fXY[j][1]+fXY[j+4][1]) -
266 (fXY[j][0]+fXY[j+4][0])*(fXY[i][1]+fXY[i+4][1]) +
267 (1./3)*((fXY[i+4][0]-fXY[i][0])*(fXY[j+4][1]-fXY[j][1]) -
268 (fXY[j][0]-fXY[j+4][0])*(fXY[i][1]-fXY[i+4][1])));
270 return TMath::Abs(capacity);
276 void TGeoArb8::ComputeBBox()
278 Double_t xmin, xmax, ymin, ymax;
279 xmin = xmax = fXY[0][0];
280 ymin = ymax = fXY[0][1];
282 for (Int_t i=1; i<8; i++) {
283 if (xmin>fXY[i][0]) xmin=fXY[i][0];
284 if (xmax<fXY[i][0]) xmax=fXY[i][0];
285 if (ymin>fXY[i][1]) ymin=fXY[i][1];
286 if (ymax<fXY[i][1]) ymax=fXY[i][1];
288 fDX = 0.5*(xmax-xmin);
289 fDY = 0.5*(ymax-ymin);
291 fOrigin[0] = 0.5*(xmax+xmin);
292 fOrigin[1] = 0.5*(ymax+ymin);
294 SetShapeBit(kGeoClosedShape);
302 void TGeoArb8::ComputeTwist()
305 Bool_t twisted = kFALSE;
306 Double_t dx1, dy1, dx2, dy2;
307 Bool_t singleBottom = kTRUE;
308 Bool_t singleTop = kTRUE;
310 for (i=0; i<4; i++) {
311 dx1 = fXY[(i+1)%4][0]-fXY[i][0];
312 dy1 = fXY[(i+1)%4][1]-fXY[i][1];
313 if (TMath::Abs(dx1)<TGeoShape::Tolerance() && TMath::Abs(dy1)<TGeoShape::Tolerance()) {
317 singleBottom = kFALSE;
318 dx2 = fXY[4+(i+1)%4][0]-fXY[4+i][0];
319 dy2 = fXY[4+(i+1)%4][1]-fXY[4+i][1];
320 if (TMath::Abs(dx2)<TGeoShape::Tolerance() && TMath::Abs(dy2)<TGeoShape::Tolerance()) {
325 twist[i] = dy1*dx2 - dx1*dy2;
326 if (TMath::Abs(twist[i])<TGeoShape::Tolerance()) {
330 twist[i] = TMath::Sign(1.,twist[i]);
334 CopyTwist(twisted ? twist :
nullptr);
337 for (i=0; i<4; i++) {
338 fXY[i][0] += 1.E-8*fXY[i+4][0];
339 fXY[i][1] += 1.E-8*fXY[i+4][1];
343 for (i=0; i<4; i++) {
344 fXY[i+4][0] += 1.E-8*fXY[i][0];
345 fXY[i+4][1] += 1.E-8*fXY[i][1];
351 for (i=0; i<4; i++) {
353 sum1 += fXY[i][0]*fXY[j][1]-fXY[j][0]*fXY[i][1];
354 sum2 += fXY[i+4][0]*fXY[j+4][1]-fXY[j+4][0]*fXY[i+4][1];
356 if (sum1*sum2 < -TGeoShape::Tolerance()) {
357 Fatal(
"ComputeTwist",
"Shape %s type Arb8: Lower/upper faces defined with opposite clockwise", GetName());
360 if (sum1>TGeoShape::Tolerance()) {
361 Error(
"ComputeTwist",
"Shape %s type Arb8: Vertices must be defined clockwise in XY planes. Re-ordering...", GetName());
362 Double_t xtemp, ytemp;
365 fXY[1][0] = fXY[3][0];
366 fXY[1][1] = fXY[3][1];
371 fXY[5][0] = fXY[7][0];
372 fXY[5][1] = fXY[7][1];
377 Bool_t illegal_cross = kFALSE;
378 illegal_cross = TGeoShape::IsSegCrossing(fXY[0][0],fXY[0][1],fXY[1][0],fXY[1][1],
379 fXY[2][0],fXY[2][1],fXY[3][0],fXY[3][1]);
381 illegal_cross = TGeoShape::IsSegCrossing(fXY[4][0],fXY[4][1],fXY[5][0],fXY[5][1],
382 fXY[6][0],fXY[6][1],fXY[7][0],fXY[7][1]);
384 Error(
"ComputeTwist",
"Shape %s type Arb8: Malformed polygon with crossing opposite segments", GetName());
392 Double_t TGeoArb8::GetTwist(Int_t iseg)
const
394 return (!fTwist || iseg<0 || iseg>3) ? 0. : fTwist[iseg];
402 Double_t TGeoArb8::GetClosestEdge(
const Double_t *point, Double_t *vert, Int_t &isegment)
const
407 Double_t p1[2], p2[2];
408 Double_t lsq, ssq, dx, dy, dpx, dpy, u;
411 for (i1=0; i1<4; i1++) {
412 if (TGeoShape::IsSameWithinTolerance(safe,0)) {
418 p1[1] = vert[2*i1+1];
420 p2[1] = vert[2*i2+1];
423 dpx = point[0] - p1[0];
424 dpy = point[1] - p1[1];
427 if (TGeoShape::IsSameWithinTolerance(lsq,0)) {
428 ssq = dpx*dpx + dpy*dpy;
437 u = (dpx*dx + dpy*dy)/lsq;
441 dpx = point[0]-p2[0];
442 dpy = point[1]-p2[1];
454 ssq = dpx*dpx + dpy*dpy;
469 void TGeoArb8::ComputeNormal(
const Double_t *point,
const Double_t *dir, Double_t *norm)
472 Double_t x0, y0, z0, x1, y1, z1, x2, y2, z2;
473 Double_t ax, ay, az, bx, by, bz;
475 safc = fDz-TMath::Abs(point[2]);
476 if (safc<10.*TGeoShape::Tolerance()) {
477 memset(norm,0,3*
sizeof(Double_t));
478 norm[2] = (dir[2]>0)?1:(-1);
482 SetPlaneVertices(point[2], vert);
485 Double_t frac = GetClosestEdge(point, vert, iseg);
486 if (frac<0) frac = 0.;
487 Int_t jseg = (iseg+1)%4;
499 x1 += frac*(fXY[jseg+4][0]-x1);
500 y1 += frac*(fXY[jseg+4][1]-y1);
509 norm[0] = ay*bz-az*by;
510 norm[1] = az*bx-ax*bz;
511 norm[2] = ax*by-ay*bx;
512 fn = TMath::Sqrt(norm[0]*norm[0]+norm[1]*norm[1]+norm[2]*norm[2]);
524 if (dir[0]>-2. && dir[0]*norm[0]+dir[1]*norm[1]+dir[2]*norm[2] < 0) {
534 Bool_t TGeoArb8::Contains(
const Double_t *point)
const
537 if (TMath::Abs(point[2]) > fDz)
return kFALSE;
542 Double_t cf = 0.5*(fDz-point[2])/fDz;
544 for (i=0; i<4; i++) {
545 poly[2*i] = fXY[i+4][0]+cf*(fXY[i][0]-fXY[i+4][0]);
546 poly[2*i+1] = fXY[i+4][1]+cf*(fXY[i][1]-fXY[i+4][1]);
548 return InsidePolygon(point[0],point[1],poly);
558 Double_t TGeoArb8::DistToPlane(
const Double_t *point,
const Double_t *dir, Int_t ipl, Bool_t in)
const
560 Double_t xa,xb,xc,xd;
561 Double_t ya,yb,yc,yd;
562 Double_t eps = 10.*TGeoShape::Tolerance();
575 Double_t dz2 =0.5/fDz;
576 Double_t tx1 =dz2*(xb-xa);
577 Double_t ty1 =dz2*(yb-ya);
578 Double_t tx2 =dz2*(xd-xc);
579 Double_t ty2 =dz2*(yd-yc);
580 Double_t dzp =fDz+point[2];
581 Double_t xs1 =xa+tx1*dzp;
582 Double_t ys1 =ya+ty1*dzp;
583 Double_t xs2 =xc+tx2*dzp;
584 Double_t ys2 =yc+ty2*dzp;
585 Double_t dxs =xs2-xs1;
586 Double_t dys =ys2-ys1;
587 Double_t dtx =tx2-tx1;
588 Double_t dty =ty2-ty1;
589 Double_t a=(dtx*dir[1]-dty*dir[0]+(tx1*ty2-tx2*ty1)*dir[2])*dir[2];
590 Double_t signa = TMath::Sign(1.,a);
591 Double_t b=dxs*dir[1]-dys*dir[0]+(dtx*point[1]-dty*point[0]+ty2*xs1-ty1*xs2
592 +tx1*ys2-tx2*ys1)*dir[2];
593 Double_t c=dxs*point[1]-dys*point[0]+xs1*ys2-xs2*ys1;
594 Double_t s=TGeoShape::Big();
595 Double_t x1,x2,y1,y2,xp,yp,zi;
596 if (TMath::Abs(a)<eps) {
598 if (TMath::Abs(b)<eps)
return TGeoShape::Big();
600 if (TMath::Abs(s)<1.E-6 && TMath::Abs(TMath::Abs(point[2])-fDz)>eps) {
601 memcpy(dirp,dir,3*
sizeof(Double_t));
604 ((TGeoArb8*)
this)->ComputeNormal(point,dirp,norm);
605 ndotd = dir[0]*norm[0]+dir[1]*norm[1]+dir[2]*norm[2];
608 s = TMath::Max(0.,s);
609 zi = (point[0]-xs1)*(point[0]-xs2)+(point[1]-ys1)*(point[1]-ys2);
612 return TGeoShape::Big();
614 if (s<0)
return TGeoShape::Big();
616 Double_t d=b*b-4*a*c;
617 if (d<0)
return TGeoShape::Big();
618 Double_t smin=0.5*(-b-signa*TMath::Sqrt(d))/a;
619 Double_t smax=0.5*(-b+signa*TMath::Sqrt(d))/a;
621 if (TMath::Abs(s)<1.E-6 && TMath::Abs(TMath::Abs(point[2])-fDz)>eps) {
622 memcpy(dirp,dir,3*
sizeof(Double_t));
625 ((TGeoArb8*)
this)->ComputeNormal(point,dirp,norm);
626 ndotd = dir[0]*norm[0]+dir[1]*norm[1]+dir[2]*norm[2];
628 if (ndotd>0)
return TMath::Max(0.,s);
633 zi=point[2]+s*dir[2];
634 if (TMath::Abs(zi)<fDz) {
637 xp=point[0]+s*dir[0];
640 yp=point[1]+s*dir[1];
641 zi = (xp-x1)*(xp-x2)+(yp-y1)*(yp-y2);
647 if (TMath::Abs(s)<1.E-6 && TMath::Abs(TMath::Abs(point[2])-fDz)>eps) {
648 memcpy(dirp,dir,3*
sizeof(Double_t));
651 ((TGeoArb8*)
this)->ComputeNormal(point,dirp,norm);
652 ndotd = dir[0]*norm[0]+dir[1]*norm[1]+dir[2]*norm[2];
654 if (ndotd>0) s = TMath::Max(0.,s);
655 else s = TGeoShape::Big();
661 zi=point[2]+s*dir[2];
662 if (TMath::Abs(zi)<fDz) {
665 xp=point[0]+s*dir[0];
668 yp=point[1]+s*dir[1];
669 zi = (xp-x1)*(xp-x2)+(yp-y1)*(yp-y2);
673 return TGeoShape::Big();
679 Double_t TGeoArb8::DistFromOutside(
const Double_t *point,
const Double_t *dir, Int_t , Double_t step, Double_t * )
const
681 Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
682 if (sdist>=step)
return TGeoShape::Big();
685 if (TMath::Abs(point[2])>fDz-1.E-8) {
687 if (point[2]*dir[2]<0) {
688 pt[2]=fDz*TMath::Sign(1.,point[2]);
689 snext = TMath::Max((pt[2]-point[2])/dir[2],0.);
690 for (Int_t j=0; j<2; j++) pt[j]=point[j]+snext*dir[j];
691 if (Contains(&pt[0]))
return snext;
696 snext = TGeoShape::Big();
697 for (Int_t i=0; i<4; i++) {
698 dist = DistToPlane(point, dir, i, kFALSE);
699 if (dist<snext) snext = dist;
707 Double_t TGeoArb8::DistFromInside(
const Double_t *point,
const Double_t *dir, Int_t , Double_t , Double_t * )
const
710 Double_t distz = TGeoShape::Big();
711 Double_t distl = TGeoShape::Big();
713 Double_t pt[3] = {0.,0.,0.};
715 distz=(-fDz-point[2])/dir[2];
718 if (dir[2]>0) distz=(fDz-point[2])/dir[2];
721 for (i=0; i<4; i++) {
722 dist=DistToPlane(point, dir, i, kTRUE);
723 if (dist<distl) distl = dist;
726 pt[0] = point[0]+distz*dir[0];
727 pt[1] = point[1]+distz*dir[1];
728 if (!Contains(pt)) distz = TGeoShape::Big();
730 dist = TMath::Min(distz, distl);
731 if (dist<0 || dist>1.E10)
return 0.;
741 Bool_t lateral_cross = kFALSE;
743 distmin=(-fDz-point[2])/dir[2];
745 if (dir[2]>0) distmin =(fDz-point[2])/dir[2];
746 else distmin = TGeoShape::Big();
748 Double_t dz2 =0.5/fDz;
749 Double_t xa,xb,xc,xd;
750 Double_t ya,yb,yc,yd;
751 Double_t eps = 100.*TGeoShape::Tolerance();
752 for (Int_t ipl=0;ipl<4;ipl++) {
763 Double_t tx1 =dz2*(xb-xa);
764 Double_t ty1 =dz2*(yb-ya);
765 Double_t tx2 =dz2*(xd-xc);
766 Double_t ty2 =dz2*(yd-yc);
767 Double_t dzp =fDz+point[2];
768 Double_t xs1 =xa+tx1*dzp;
769 Double_t ys1 =ya+ty1*dzp;
770 Double_t xs2 =xc+tx2*dzp;
771 Double_t ys2 =yc+ty2*dzp;
772 Double_t dxs =xs2-xs1;
773 Double_t dys =ys2-ys1;
774 Double_t dtx =tx2-tx1;
775 Double_t dty =ty2-ty1;
776 Double_t a=(dtx*dir[1]-dty*dir[0]+(tx1*ty2-tx2*ty1)*dir[2])*dir[2];
777 Double_t b=dxs*dir[1]-dys*dir[0]+(dtx*point[1]-dty*point[0]+ty2*xs1-ty1*xs2
778 +tx1*ys2-tx2*ys1)*dir[2];
779 Double_t c=dxs*point[1]-dys*point[0]+xs1*ys2-xs2*ys1;
780 Double_t s=TGeoShape::Big();
781 if (TMath::Abs(a)<eps) {
782 if (TMath::Abs(b)<eps)
continue;
784 if (s>eps && s < distmin) {
790 Double_t d=b*b-4*a*c;
792 if (a>0) s=0.5*(-b-TMath::Sqrt(d))/a;
793 else s=0.5*(-b+TMath::Sqrt(d))/a;
797 lateral_cross = kTRUE;
800 if (a>0) s=0.5*(-b+TMath::Sqrt(d))/a;
801 else s=0.5*(-b-TMath::Sqrt(d))/a;
802 if (s>eps && s < distmin) {
804 lateral_cross = kTRUE;
810 if (!lateral_cross) {
812 if (distmin > 1.E10)
return TGeoShape::Tolerance();
814 pt[0] = point[0]+distmin*dir[0];
815 pt[1] = point[1]+distmin*dir[1];
820 for (Int_t j=0; j<4; j++) {
821 poly[2*j] = fXY[j+i][0];
822 poly[2*j+1] = fXY[j+i][1];
824 if (!InsidePolygon(pt[0],pt[1],poly))
return TGeoShape::Tolerance();
833 TGeoVolume *TGeoArb8::Divide(TGeoVolume *voldiv,
const char * , Int_t , Int_t ,
834 Double_t , Double_t )
836 Error(
"Divide",
"Division of an arbitrary trapezoid not implemented");
843 Double_t TGeoArb8::GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi)
const
861 void TGeoArb8::GetBoundingCylinder(Double_t *param)
const
867 for (i=0; i<8; i++) {
868 rsq = fXY[i][0]*fXY[i][0] + fXY[i][1]*fXY[i][1];
869 rmaxsq = TMath::Max(rsq, rmaxsq);
880 Int_t TGeoArb8::GetFittingBox(
const TGeoBBox *parambox, TGeoMatrix *mat, Double_t &dx, Double_t &dy, Double_t &dz)
const
883 if (mat->IsRotation()) {
884 Error(
"GetFittingBox",
"cannot handle parametrized rotated volumes");
889 mat->LocalToMaster(parambox->GetOrigin(), origin);
890 if (!Contains(origin)) {
891 Error(
"GetFittingBox",
"wrong matrix - parametrized box is outside this");
896 dd[0] = parambox->GetDX();
897 dd[1] = parambox->GetDY();
898 dd[2] = parambox->GetDZ();
901 dd[2] = TMath::Min(origin[2]+fDz, fDz-origin[2]);
903 Error(
"GetFittingBox",
"wrong matrix");
907 if (dd[0]>=0 && dd[1]>=0) {
916 SetPlaneVertices(origin[2]-dd[2], lower);
917 SetPlaneVertices(origin[2]+dd[2], upper);
918 Double_t ddmin=TGeoShape::Big();
919 for (Int_t iaxis=0; iaxis<2; iaxis++) {
920 if (dd[iaxis]>=0)
continue;
921 ddmin=TGeoShape::Big();
922 for (Int_t ivert=0; ivert<4; ivert++) {
923 ddmin = TMath::Min(ddmin, TMath::Abs(origin[iaxis]-lower[2*ivert+iaxis]));
924 ddmin = TMath::Min(ddmin, TMath::Abs(origin[iaxis]-upper[2*ivert+iaxis]));
937 void TGeoArb8::GetPlaneNormal(Double_t *p1, Double_t *p2, Double_t *p3, Double_t *norm)
940 Double_t v1[3], v2[3];
942 for (i=0; i<3; i++) {
943 v1[i] = p2[i] - p1[i];
944 v2[i] = p3[i] - p1[i];
946 norm[0] = v1[1]*v2[2]-v1[2]*v2[1];
947 cross += norm[0]*norm[0];
948 norm[1] = v1[2]*v2[0]-v1[0]*v2[2];
949 cross += norm[1]*norm[1];
950 norm[2] = v1[0]*v2[1]-v1[1]*v2[0];
951 cross += norm[2]*norm[2];
952 if (TMath::Abs(cross) < TGeoShape::Tolerance())
return;
953 cross = 1./TMath::Sqrt(cross);
954 for (i=0; i<3; i++) norm[i] *= cross;
965 Bool_t TGeoArb8::GetPointsOnFacet(Int_t , Int_t , Double_t * )
const
1021 Bool_t TGeoArb8::InsidePolygon(Double_t x, Double_t y, Double_t *pts)
1024 Double_t x1,y1,x2,y2;
1026 for (i=0; i<4; i++) {
1032 cross = (x-x1)*(y2-y1)-(y-y1)*(x2-x1);
1033 if (cross<0)
return kFALSE;
1041 void TGeoArb8::InspectShape()
const
1043 printf(
"*** Shape %s: TGeoArb8 ***\n", GetName());
1044 if (IsTwisted()) printf(
" = TWISTED\n");
1045 for (Int_t ip=0; ip<8; ip++) {
1046 printf(
" point #%i : x=%11.5f y=%11.5f z=%11.5f\n",
1047 ip, fXY[ip][0], fXY[ip][1], fDz*((ip<4)?-1:1));
1049 printf(
" Bounding box:\n");
1050 TGeoBBox::InspectShape();
1056 Double_t TGeoArb8::Safety(
const Double_t *point, Bool_t in)
const
1058 Double_t safz = fDz-TMath::Abs(point[2]);
1059 if (!in) safz = -safz;
1061 Double_t safe = TGeoShape::Big();
1062 Double_t lsq, ssq, dx, dy, dpx, dpy, u;
1065 if (!TGeoBBox::Contains(point))
return TGeoBBox::Safety(point,kFALSE);
1073 SetPlaneVertices (point[2], vert);
1074 for (iseg=0; iseg<4; iseg++) {
1075 if (safe<TGeoShape::Tolerance())
return 0.;
1077 p2 = &vert[2*((iseg+1)%4)];
1080 dpx = point[0] - p1[0];
1081 dpy = point[1] - p1[1];
1083 lsq = dx*dx + dy*dy;
1084 u = (dpx*dx + dpy*dy)/lsq;
1086 dpx = point[0]-p2[0];
1087 dpy = point[1]-p2[1];
1094 ssq = dpx*dpx + dpy*dpy;
1101 if (umin<0) umin = 0.;
1103 isegmin = (isegmin+1)%4;
1107 Int_t i2 = (isegmin+1)%4;
1108 Double_t dx1 = fXY[i2][0]-fXY[i1][0];
1109 Double_t dx2 = fXY[i2+4][0]-fXY[i1+4][0];
1110 Double_t dy1 = fXY[i2][1]-fXY[i1][1];
1111 Double_t dy2 = fXY[i2+4][1]-fXY[i1+4][1];
1112 dx = dx1 + umin*(dx2-dx1);
1113 dy = dy1 + umin*(dy2-dy1);
1114 safe *= 1.- 4.*fDz*fDz/(dx*dx+dy*dy+4.*fDz*fDz);
1115 safe = TMath::Sqrt(safe);
1116 if (in)
return TMath::Min(safz,safe);
1117 return TMath::Max(safz,safe);
1123 for (iseg=0; iseg<4; iseg++) saf[iseg+1] = SafetyToFace(point,iseg,in);
1124 if (in) safe = saf[TMath::LocMin(5, saf)];
1125 else safe = saf[TMath::LocMax(5, saf)];
1126 if (safe<0)
return 0.;
1134 Double_t TGeoArb8::SafetyToFace(
const Double_t *point, Int_t iseg, Bool_t in)
const
1136 Double_t vertices[12];
1137 Int_t ipln = (iseg+1)%4;
1139 vertices[0] = fXY[iseg][0];
1140 vertices[1] = fXY[iseg][1];
1143 vertices[3] = fXY[ipln][0];
1144 vertices[4] = fXY[ipln][1];
1147 vertices[6] = fXY[ipln+4][0];
1148 vertices[7] = fXY[ipln+4][1];
1151 vertices[9] = fXY[iseg+4][0];
1152 vertices[10] = fXY[iseg+4][1];
1156 Double_t *p1, *p2, *p3;
1160 if (IsSamePoint(p2,p3)) {
1162 if (IsSamePoint(p1,p3))
return -TGeoShape::Big();
1164 GetPlaneNormal(p1,p2,p3,norm);
1165 safe = (point[0]-p1[0])*norm[0]+(point[1]-p1[1])*norm[1]+(point[2]-p1[2])*norm[2];
1166 if (in)
return (-safe);
1173 void TGeoArb8::SavePrimitive(std::ostream &out, Option_t * )
1175 if (TObject::TestBit(kGeoSavePrimitive))
return;
1176 out <<
" // Shape: " << GetName() <<
" type: " << ClassName() << std::endl;
1177 out <<
" dz = " << fDz <<
";" << std::endl;
1178 out <<
" vert[0] = " << fXY[0][0] <<
";" << std::endl;
1179 out <<
" vert[1] = " << fXY[0][1] <<
";" << std::endl;
1180 out <<
" vert[2] = " << fXY[1][0] <<
";" << std::endl;
1181 out <<
" vert[3] = " << fXY[1][1] <<
";" << std::endl;
1182 out <<
" vert[4] = " << fXY[2][0] <<
";" << std::endl;
1183 out <<
" vert[5] = " << fXY[2][1] <<
";" << std::endl;
1184 out <<
" vert[6] = " << fXY[3][0] <<
";" << std::endl;
1185 out <<
" vert[7] = " << fXY[3][1] <<
";" << std::endl;
1186 out <<
" vert[8] = " << fXY[4][0] <<
";" << std::endl;
1187 out <<
" vert[9] = " << fXY[4][1] <<
";" << std::endl;
1188 out <<
" vert[10] = " << fXY[5][0] <<
";" << std::endl;
1189 out <<
" vert[11] = " << fXY[5][1] <<
";" << std::endl;
1190 out <<
" vert[12] = " << fXY[6][0] <<
";" << std::endl;
1191 out <<
" vert[13] = " << fXY[6][1] <<
";" << std::endl;
1192 out <<
" vert[14] = " << fXY[7][0] <<
";" << std::endl;
1193 out <<
" vert[15] = " << fXY[7][1] <<
";" << std::endl;
1194 out <<
" TGeoShape *" << GetPointerName() <<
" = new TGeoArb8(\"" << GetName() <<
"\", dz,vert);" << std::endl;
1195 TObject::SetBit(TGeoShape::kGeoSavePrimitive);
1201 void TGeoArb8::SetPlaneVertices(Double_t zpl, Double_t *vertices)
const
1203 Double_t cf = 0.5*(fDz-zpl)/fDz;
1204 for (Int_t i=0; i<4; i++) {
1205 vertices[2*i] = fXY[i+4][0]+cf*(fXY[i][0]-fXY[i+4][0]);
1206 vertices[2*i+1] = fXY[i+4][1]+cf*(fXY[i][1]-fXY[i+4][1]);
1217 void TGeoArb8::SetDimensions(Double_t *param)
1220 for (Int_t i=0; i<8; i++) {
1221 fXY[i][0] = param[2*i+1];
1222 fXY[i][1] = param[2*i+2];
1231 void TGeoArb8::SetPoints(Double_t *points)
const
1233 for (Int_t i=0; i<8; i++) {
1234 points[3*i] = fXY[i][0];
1235 points[3*i+1] = fXY[i][1];
1236 points[3*i+2] = (i<4)?-fDz:fDz;
1243 void TGeoArb8::SetPoints(Float_t *points)
const
1245 for (Int_t i=0; i<8; i++) {
1246 points[3*i] = fXY[i][0];
1247 points[3*i+1] = fXY[i][1];
1248 points[3*i+2] = (i<4)?-fDz:fDz;
1255 void TGeoArb8::SetVertex(Int_t vnum, Double_t x, Double_t y)
1257 if (vnum<0 || vnum >7) {
1258 Error(
"SetVertex",
"Invalid vertex number");
1272 void TGeoArb8::Sizeof3D()
const
1274 TGeoBBox::Sizeof3D();
1280 void TGeoArb8::Streamer(TBuffer &R__b)
1282 if (R__b.IsReading()) {
1283 R__b.ReadClassBuffer(TGeoArb8::Class(),
this);
1286 R__b.WriteClassBuffer(TGeoArb8::Class(),
this);
1295 void TGeoArb8::Contains_v(
const Double_t *points, Bool_t *inside, Int_t vecsize)
const
1297 for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
1305 void TGeoArb8::ComputeNormal_v(
const Double_t *points,
const Double_t *dirs, Double_t *norms, Int_t vecsize)
1307 for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
1313 void TGeoArb8::DistFromInside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
1315 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1321 void TGeoArb8::DistFromOutside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
1323 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1331 void TGeoArb8::Safety_v(
const Double_t *points,
const Bool_t *inside, Double_t *safe, Int_t vecsize)
const
1333 for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
1341 TGeoTrap::TGeoTrap()
1346 fH1 = fH2 = fBl1 = fBl2 = fTl1 = fTl2 = fAlpha1 = fAlpha2 = 0;
1352 TGeoTrap::TGeoTrap(Double_t dz, Double_t theta, Double_t phi)
1358 fH1 = fH2 = fBl1 = fBl2 = fTl1 = fTl2 = fAlpha1 = fAlpha2 = 0;
1364 TGeoTrap::TGeoTrap(Double_t dz, Double_t theta, Double_t phi, Double_t h1,
1365 Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
1366 Double_t tl2, Double_t alpha2)
1380 Double_t tx = TMath::Tan(theta*TMath::DegToRad())*TMath::Cos(phi*TMath::DegToRad());
1381 Double_t ty = TMath::Tan(theta*TMath::DegToRad())*TMath::Sin(phi*TMath::DegToRad());
1382 Double_t ta1 = TMath::Tan(alpha1*TMath::DegToRad());
1383 Double_t ta2 = TMath::Tan(alpha2*TMath::DegToRad());
1384 fXY[0][0] = -dz*tx-h1*ta1-bl1; fXY[0][1] = -dz*ty-h1;
1385 fXY[1][0] = -dz*tx+h1*ta1-tl1; fXY[1][1] = -dz*ty+h1;
1386 fXY[2][0] = -dz*tx+h1*ta1+tl1; fXY[2][1] = -dz*ty+h1;
1387 fXY[3][0] = -dz*tx-h1*ta1+bl1; fXY[3][1] = -dz*ty-h1;
1388 fXY[4][0] = dz*tx-h2*ta2-bl2; fXY[4][1] = dz*ty-h2;
1389 fXY[5][0] = dz*tx+h2*ta2-tl2; fXY[5][1] = dz*ty+h2;
1390 fXY[6][0] = dz*tx+h2*ta2+tl2; fXY[6][1] = dz*ty+h2;
1391 fXY[7][0] = dz*tx-h2*ta2+bl2; fXY[7][1] = dz*ty-h2;
1393 if ((dz<0) || (h1<0) || (bl1<0) || (tl1<0) ||
1394 (h2<0) || (bl2<0) || (tl2<0)) {
1395 SetShapeBit(kGeoRunTimeShape);
1397 else TGeoArb8::ComputeBBox();
1403 TGeoTrap::TGeoTrap(
const char *name, Double_t dz, Double_t theta, Double_t phi, Double_t h1,
1404 Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
1405 Double_t tl2, Double_t alpha2)
1406 :TGeoArb8(name, 0, 0)
1420 for (Int_t i=0; i<8; i++) {
1424 Double_t tx = TMath::Tan(theta*TMath::DegToRad())*TMath::Cos(phi*TMath::DegToRad());
1425 Double_t ty = TMath::Tan(theta*TMath::DegToRad())*TMath::Sin(phi*TMath::DegToRad());
1426 Double_t ta1 = TMath::Tan(alpha1*TMath::DegToRad());
1427 Double_t ta2 = TMath::Tan(alpha2*TMath::DegToRad());
1428 fXY[0][0] = -dz*tx-h1*ta1-bl1; fXY[0][1] = -dz*ty-h1;
1429 fXY[1][0] = -dz*tx+h1*ta1-tl1; fXY[1][1] = -dz*ty+h1;
1430 fXY[2][0] = -dz*tx+h1*ta1+tl1; fXY[2][1] = -dz*ty+h1;
1431 fXY[3][0] = -dz*tx-h1*ta1+bl1; fXY[3][1] = -dz*ty-h1;
1432 fXY[4][0] = dz*tx-h2*ta2-bl2; fXY[4][1] = dz*ty-h2;
1433 fXY[5][0] = dz*tx+h2*ta2-tl2; fXY[5][1] = dz*ty+h2;
1434 fXY[6][0] = dz*tx+h2*ta2+tl2; fXY[6][1] = dz*ty+h2;
1435 fXY[7][0] = dz*tx-h2*ta2+bl2; fXY[7][1] = dz*ty-h2;
1437 if ((dz<0) || (h1<0) || (bl1<0) || (tl1<0) ||
1438 (h2<0) || (bl2<0) || (tl2<0)) {
1439 SetShapeBit(kGeoRunTimeShape);
1441 else TGeoArb8::ComputeBBox();
1447 TGeoTrap::~TGeoTrap()
1454 Double_t TGeoTrap::DistFromInside(
const Double_t *point,
const Double_t *dir, Int_t iact, Double_t step, Double_t *safe)
const
1456 if (iact<3 && safe) {
1458 *safe = Safety(point, kTRUE);
1459 if (iact==0)
return TGeoShape::Big();
1460 if (iact==1 && step<*safe)
return TGeoShape::Big();
1472 distmin=(-fDz-point[2])/dir[2];
1474 if (dir[2]>0) distmin =(fDz-point[2])/dir[2];
1475 else distmin = TGeoShape::Big();
1479 for (Int_t ipl=0;ipl<4;ipl++) {
1480 Int_t j = (ipl+1)%4;
1494 Double_t ddotn = -dir[0]*az*by + dir[1]*az*bx+dir[2]*(ax*by-ay*bx);
1495 if (ddotn<=0)
continue;
1496 Double_t saf = -(point[0]-xa)*az*by + (point[1]-ya)*az*bx + (point[2]+fDz)*(ax*by-ay*bx);
1497 if (saf>=0.0)
return 0.0;
1498 Double_t s = -saf/ddotn;
1499 if (s<distmin) distmin=s;
1507 Double_t TGeoTrap::DistFromOutside(
const Double_t *point,
const Double_t *dir, Int_t iact, Double_t step, Double_t *safe)
const
1509 if (iact<3 && safe) {
1511 *safe = Safety(point, kFALSE);
1512 if (iact==0)
return TGeoShape::Big();
1513 if (iact==1 && step<*safe)
return TGeoShape::Big();
1516 Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
1517 if (sdist>=step)
return TGeoShape::Big();
1522 Double_t xnew, ynew, znew;
1524 if (point[2]<-fDz+TGeoShape::Tolerance()) {
1525 if (dir[2] < TGeoShape::Tolerance())
return TGeoShape::Big();
1527 snxt = -(fDz+point[2])/dir[2];
1528 xnew = point[0] + snxt*dir[0];
1529 ynew = point[1] + snxt*dir[1];
1533 pts[j+1] = fXY[i][1];
1535 if (InsidePolygon(xnew,ynew,pts))
return snxt;
1536 }
else if (point[2]>fDz-TGeoShape::Tolerance()) {
1537 if (dir[2] > -TGeoShape::Tolerance())
return TGeoShape::Big();
1539 snxt = (fDz-point[2])/dir[2];
1540 xnew = point[0] + snxt*dir[0];
1541 ynew = point[1] + snxt*dir[1];
1544 pts[j] = fXY[i+4][0];
1545 pts[j+1] = fXY[i+4][1];
1547 if (InsidePolygon(xnew,ynew,pts))
return snxt;
1549 snxt = TGeoShape::Big();
1553 Double_t dz2 =0.5/fDz;
1554 Double_t xa,xb,xc,xd;
1555 Double_t ya,yb,yc,yd;
1558 Double_t ddotn, saf;
1559 Double_t safmin = TGeoShape::Big();
1560 Bool_t exiting = kFALSE;
1561 for (i=0; i<4; i++) {
1576 ddotn = -dir[0]*az*by + dir[1]*az*bx+dir[2]*(ax*by-ay*bx);
1577 saf = (point[0]-xa)*az*by - (point[1]-ya)*az*bx - (point[2]+fDz)*(ax*by-ay*bx);
1582 if (ddotn>=0)
return TGeoShape::Big();
1584 znew = point[2]+snxt*dir[2];
1585 if (TMath::Abs(znew)<=fDz) {
1586 xnew = point[0]+snxt*dir[0];
1587 ynew = point[1]+snxt*dir[1];
1588 Double_t tx1 =dz2*(xb-xa);
1589 Double_t ty1 =dz2*(yb-ya);
1590 Double_t tx2 =dz2*(xd-xc);
1591 Double_t ty2 =dz2*(yd-yc);
1592 Double_t dzp =fDz+znew;
1593 Double_t xs1 =xa+tx1*dzp;
1594 Double_t ys1 =ya+ty1*dzp;
1595 Double_t xs2 =xc+tx2*dzp;
1596 Double_t ys2 =yc+ty2*dzp;
1597 if (TMath::Abs(xs1-xs2)>TMath::Abs(ys1-ys2)) {
1598 if ((xnew-xs1)*(xs2-xnew)>=0)
return snxt;
1600 if ((ynew-ys1)*(ys2-ynew)>=0)
return snxt;
1606 if (ddotn>=0) exiting = kTRUE;
1607 else exiting = kFALSE;
1612 saf = fDz - TMath::Abs(point[2]);
1613 if (saf>0 && saf<safmin) exiting = (point[2]*dir[2] > 0)?kTRUE:kFALSE;
1614 if (!in)
return TGeoShape::Big();
1615 if (exiting)
return TGeoShape::Big();
1626 TGeoVolume *TGeoTrap::Divide(TGeoVolume *voldiv,
const char *divname, Int_t iaxis, Int_t ndiv,
1627 Double_t start, Double_t step)
1631 TGeoVolumeMulti *vmulti;
1632 TGeoPatternFinder *finder;
1635 Error(
"Divide",
"cannot divide trapezoids on other axis than Z");
1638 Double_t end = start+ndiv*step;
1639 Double_t points_lo[8];
1640 Double_t points_hi[8];
1641 finder =
new TGeoPatternTrapZ(voldiv, ndiv, start, end);
1642 voldiv->SetFinder(finder);
1643 finder->SetDivIndex(voldiv->GetNdaughters());
1645 vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
1646 Double_t txz = ((TGeoPatternTrapZ*)finder)->GetTxz();
1647 Double_t tyz = ((TGeoPatternTrapZ*)finder)->GetTyz();
1648 Double_t zmin, zmax, ox,oy,oz;
1649 for (Int_t idiv=0; idiv<ndiv; idiv++) {
1650 zmin = start+idiv*step;
1651 zmax = start+(idiv+1)*step;
1652 oz = start+idiv*step+step/2;
1655 SetPlaneVertices(zmin, &points_lo[0]);
1656 SetPlaneVertices(zmax, &points_hi[0]);
1657 shape =
new TGeoTrap(step/2, fTheta, fPhi);
1658 for (Int_t vert1=0; vert1<4; vert1++)
1659 ((TGeoArb8*)shape)->SetVertex(vert1, points_lo[2*vert1]-ox, points_lo[2*vert1+1]-oy);
1660 for (Int_t vert2=0; vert2<4; vert2++)
1661 ((TGeoArb8*)shape)->SetVertex(vert2+4, points_hi[2*vert2]-ox, points_hi[2*vert2+1]-oy);
1662 vol =
new TGeoVolume(divname, shape, voldiv->GetMedium());
1663 vmulti->AddVolume(vol);
1664 voldiv->AddNodeOffset(vol, idiv, oz, opt.Data());
1665 ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
1674 TGeoShape *TGeoTrap::GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix * )
const
1676 if (!TestShapeBit(kGeoRunTimeShape))
return 0;
1677 if (mother->IsRunTimeShape()) {
1678 Error(
"GetMakeRuntimeShape",
"invalid mother");
1681 Double_t dz, h1, bl1, tl1, h2, bl2, tl2;
1682 if (fDz<0) dz=((TGeoTrap*)mother)->GetDz();
1685 if (fH1<0) h1 = ((TGeoTrap*)mother)->GetH1();
1688 if (fH2<0) h2 = ((TGeoTrap*)mother)->GetH2();
1691 if (fBl1<0) bl1 = ((TGeoTrap*)mother)->GetBl1();
1694 if (fBl2<0) bl2 = ((TGeoTrap*)mother)->GetBl2();
1697 if (fTl1<0) tl1 = ((TGeoTrap*)mother)->GetTl1();
1700 if (fTl2<0) tl2 = ((TGeoTrap*)mother)->GetTl2();
1703 return (
new TGeoTrap(dz, fTheta, fPhi, h1, bl1, tl1, fAlpha1, h2, bl2, tl2, fAlpha2));
1709 Double_t TGeoTrap::Safety(
const Double_t *point, Bool_t in)
const
1711 Double_t safe = TGeoShape::Big();
1715 Double_t x0, y0, z0=-fDz, x1, y1, z1=fDz, x2, y2;
1716 Double_t ax, ay, az=z1-z0, bx, by;
1719 for (i=0; i<4; i++) {
1720 if (in) saf[i] = TGeoShape::Big();
1734 if (TMath::Abs(bx)<TGeoShape::Tolerance() && TMath::Abs(by)<TGeoShape::Tolerance()) {
1739 if (TMath::Abs(bx)<TGeoShape::Tolerance() && TMath::Abs(by)<TGeoShape::Tolerance())
continue;
1743 norm[2] = ax*by-ay*bx;
1744 fn = TMath::Sqrt(norm[0]*norm[0]+norm[1]*norm[1]+norm[2]*norm[2]);
1745 if (fn<1E-10)
continue;
1746 saf[i] = (x0-point[0])*norm[0]+(y0-point[1])*norm[1]+(-fDz-point[2])*norm[2];
1748 saf[i]=TMath::Abs(saf[i])/fn;
1750 saf[i] = -saf[i]/fn;
1753 saf[4] = fDz-TMath::Abs(point[2]);
1756 for (j=1;j<5;j++)
if (saf[j] <safe) safe = saf[j];
1760 for (j=1;j<5;j++) if (saf[j] >safe) safe = saf[j];
1768 void TGeoTrap::SavePrimitive(std::ostream &out, Option_t * )
1770 if (TObject::TestBit(kGeoSavePrimitive))
return;
1771 out <<
" // Shape: " << GetName() <<
" type: " << ClassName() << std::endl;
1772 out <<
" dz = " << fDz <<
";" << std::endl;
1773 out <<
" theta = " << fTheta <<
";" << std::endl;
1774 out <<
" phi = " << fPhi <<
";" << std::endl;
1775 out <<
" h1 = " << fH1<<
";" << std::endl;
1776 out <<
" bl1 = " << fBl1<<
";" << std::endl;
1777 out <<
" tl1 = " << fTl1<<
";" << std::endl;
1778 out <<
" alpha1 = " << fAlpha1 <<
";" << std::endl;
1779 out <<
" h2 = " << fH2 <<
";" << std::endl;
1780 out <<
" bl2 = " << fBl2<<
";" << std::endl;
1781 out <<
" tl2 = " << fTl2<<
";" << std::endl;
1782 out <<
" alpha2 = " << fAlpha2 <<
";" << std::endl;
1783 out <<
" TGeoShape *" << GetPointerName() <<
" = new TGeoTrap(\"" << GetName() <<
"\", dz,theta,phi,h1,bl1,tl1,alpha1,h2,bl2,tl2,alpha2);" << std::endl;
1784 TObject::SetBit(TGeoShape::kGeoSavePrimitive);
1801 void TGeoTrap::SetDimensions(Double_t *param)
1813 fAlpha2 = param[10];
1814 Double_t tx = TMath::Tan(fTheta*TMath::DegToRad())*TMath::Cos(fPhi*TMath::DegToRad());
1815 Double_t ty = TMath::Tan(fTheta*TMath::DegToRad())*TMath::Sin(fPhi*TMath::DegToRad());
1816 Double_t ta1 = TMath::Tan(fAlpha1*TMath::DegToRad());
1817 Double_t ta2 = TMath::Tan(fAlpha2*TMath::DegToRad());
1818 fXY[0][0] = -fDz*tx-fH1*ta1-fBl1; fXY[0][1] = -fDz*ty-fH1;
1819 fXY[1][0] = -fDz*tx+fH1*ta1-fTl1; fXY[1][1] = -fDz*ty+fH1;
1820 fXY[2][0] = -fDz*tx+fH1*ta1+fTl1; fXY[2][1] = -fDz*ty+fH1;
1821 fXY[3][0] = -fDz*tx-fH1*ta1+fBl1; fXY[3][1] = -fDz*ty-fH1;
1822 fXY[4][0] = fDz*tx-fH2*ta2-fBl2; fXY[4][1] = fDz*ty-fH2;
1823 fXY[5][0] = fDz*tx+fH2*ta2-fTl2; fXY[5][1] = fDz*ty+fH2;
1824 fXY[6][0] = fDz*tx+fH2*ta2+fTl2; fXY[6][1] = fDz*ty+fH2;
1825 fXY[7][0] = fDz*tx-fH2*ta2+fBl2; fXY[7][1] = fDz*ty-fH2;
1827 if ((fDz<0) || (fH1<0) || (fBl1<0) || (fTl1<0) ||
1828 (fH2<0) || (fBl2<0) || (fTl2<0)) {
1829 SetShapeBit(kGeoRunTimeShape);
1831 else TGeoArb8::ComputeBBox();
1837 void TGeoTrap::DistFromInside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
1839 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1845 void TGeoTrap::DistFromOutside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
1847 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1855 void TGeoTrap::Safety_v(
const Double_t *points,
const Bool_t *inside, Double_t *safe, Int_t vecsize)
const
1857 for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
1865 TGeoGtra::TGeoGtra()
1874 TGeoGtra::TGeoGtra(Double_t dz, Double_t theta, Double_t phi, Double_t twist, Double_t h1,
1875 Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
1876 Double_t tl2, Double_t alpha2)
1877 :TGeoTrap(dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2)
1879 fTwistAngle = twist;
1881 Double_t th = theta*TMath::DegToRad();
1882 Double_t ph = phi*TMath::DegToRad();
1884 Double_t xc = -dz*TMath::Sin(th)*TMath::Cos(ph);
1885 Double_t yc = -dz*TMath::Sin(th)*TMath::Sin(ph);
1889 for (i=0; i<4; i++) {
1892 fXY[i][0] = x*TMath::Cos(-0.5*twist*TMath::DegToRad()) + y*TMath::Sin(-0.5*twist*TMath::DegToRad()) + xc;
1893 fXY[i][1] = -x*TMath::Sin(-0.5*twist*TMath::DegToRad()) + y*TMath::Cos(-0.5*twist*TMath::DegToRad()) + yc;
1898 for (i=4; i<8; i++) {
1901 fXY[i][0] = x*TMath::Cos(0.5*twist*TMath::DegToRad()) + y*TMath::Sin(0.5*twist*TMath::DegToRad()) + xc;
1902 fXY[i][1] = -x*TMath::Sin(0.5*twist*TMath::DegToRad()) + y*TMath::Cos(0.5*twist*TMath::DegToRad()) + yc;
1905 if ((dz<0) || (h1<0) || (bl1<0) || (tl1<0) ||
1906 (h2<0) || (bl2<0) || (tl2<0)) SetShapeBit(kGeoRunTimeShape);
1907 else TGeoArb8::ComputeBBox();
1913 TGeoGtra::TGeoGtra(
const char *name, Double_t dz, Double_t theta, Double_t phi, Double_t twist, Double_t h1,
1914 Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
1915 Double_t tl2, Double_t alpha2)
1916 :TGeoTrap(name, dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2)
1918 fTwistAngle = twist;
1920 Double_t th = theta*TMath::DegToRad();
1921 Double_t ph = phi*TMath::DegToRad();
1923 Double_t xc = -dz*TMath::Sin(th)*TMath::Cos(ph);
1924 Double_t yc = -dz*TMath::Sin(th)*TMath::Sin(ph);
1928 for (i=0; i<4; i++) {
1931 fXY[i][0] = x*TMath::Cos(-0.5*twist*TMath::DegToRad()) + y*TMath::Sin(-0.5*twist*TMath::DegToRad()) + xc;
1932 fXY[i][1] = -x*TMath::Sin(-0.5*twist*TMath::DegToRad()) + y*TMath::Cos(-0.5*twist*TMath::DegToRad()) + yc;
1937 for (i=4; i<8; i++) {
1940 fXY[i][0] = x*TMath::Cos(0.5*twist*TMath::DegToRad()) + y*TMath::Sin(0.5*twist*TMath::DegToRad()) + xc;
1941 fXY[i][1] = -x*TMath::Sin(0.5*twist*TMath::DegToRad()) + y*TMath::Cos(0.5*twist*TMath::DegToRad()) + yc;
1944 if ((dz<0) || (h1<0) || (bl1<0) || (tl1<0) ||
1945 (h2<0) || (bl2<0) || (tl2<0)) SetShapeBit(kGeoRunTimeShape);
1946 else TGeoArb8::ComputeBBox();
1952 TGeoGtra::~TGeoGtra()
1959 Double_t TGeoGtra::DistFromInside(
const Double_t *point,
const Double_t *dir, Int_t iact, Double_t step, Double_t *safe)
const
1961 if (iact<3 && safe) {
1963 *safe = Safety(point, kTRUE);
1964 if (iact==0)
return TGeoShape::Big();
1965 if (iact==1 && step<*safe)
return TGeoShape::Big();
1968 return TGeoArb8::DistFromInside(point, dir, iact, step, safe);
1974 Double_t TGeoGtra::DistFromOutside(
const Double_t *point,
const Double_t *dir, Int_t iact, Double_t step, Double_t *safe)
const
1976 if (iact<3 && safe) {
1978 *safe = Safety(point, kTRUE);
1979 if (iact==0)
return TGeoShape::Big();
1980 if (iact==1 && step<*safe)
return TGeoShape::Big();
1983 return TGeoArb8::DistFromOutside(point, dir, iact, step, safe);
1990 TGeoShape *TGeoGtra::GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix * )
const
1992 if (!TestShapeBit(kGeoRunTimeShape))
return 0;
1993 if (mother->IsRunTimeShape()) {
1994 Error(
"GetMakeRuntimeShape",
"invalid mother");
1997 Double_t dz, h1, bl1, tl1, h2, bl2, tl2;
1998 if (fDz<0) dz=((TGeoTrap*)mother)->GetDz();
2001 h1 = ((TGeoTrap*)mother)->GetH1();
2005 h2 = ((TGeoTrap*)mother)->GetH2();
2009 bl1 = ((TGeoTrap*)mother)->GetBl1();
2013 bl2 = ((TGeoTrap*)mother)->GetBl2();
2017 tl1 = ((TGeoTrap*)mother)->GetTl1();
2021 tl2 = ((TGeoTrap*)mother)->GetTl2();
2024 return (
new TGeoGtra(dz, fTheta, fPhi, fTwistAngle ,h1, bl1, tl1, fAlpha1, h2, bl2, tl2, fAlpha2));
2030 Double_t TGeoGtra::Safety(
const Double_t *point, Bool_t in)
const
2032 return TGeoArb8::Safety(point,in);
2038 void TGeoGtra::SavePrimitive(std::ostream &out, Option_t * )
2040 if (TObject::TestBit(kGeoSavePrimitive))
return;
2041 out <<
" // Shape: " << GetName() <<
" type: " << ClassName() << std::endl;
2042 out <<
" dz = " << fDz <<
";" << std::endl;
2043 out <<
" theta = " << fTheta <<
";" << std::endl;
2044 out <<
" phi = " << fPhi <<
";" << std::endl;
2045 out <<
" twist = " << fTwistAngle <<
";" << std::endl;
2046 out <<
" h1 = " << fH1<<
";" << std::endl;
2047 out <<
" bl1 = " << fBl1<<
";" << std::endl;
2048 out <<
" tl1 = " << fTl1<<
";" << std::endl;
2049 out <<
" alpha1 = " << fAlpha1 <<
";" << std::endl;
2050 out <<
" h2 = " << fH2 <<
";" << std::endl;
2051 out <<
" bl2 = " << fBl2<<
";" << std::endl;
2052 out <<
" tl2 = " << fTl2<<
";" << std::endl;
2053 out <<
" alpha2 = " << fAlpha2 <<
";" << std::endl;
2054 out <<
" TGeoShape *" << GetPointerName() <<
" = new TGeoGtra(\"" << GetName() <<
"\", dz,theta,phi,twist,h1,bl1,tl1,alpha1,h2,bl2,tl2,alpha2);" << std::endl;
2055 TObject::SetBit(TGeoShape::kGeoSavePrimitive);
2073 void TGeoGtra::SetDimensions(Double_t *param)
2075 TGeoTrap::SetDimensions(param);
2076 fTwistAngle = param[11];
2078 Double_t twist = fTwistAngle;
2079 Double_t th = fTheta*TMath::DegToRad();
2080 Double_t ph = fPhi*TMath::DegToRad();
2082 Double_t xc = -fDz*TMath::Sin(th)*TMath::Cos(ph);
2083 Double_t yc = -fDz*TMath::Sin(th)*TMath::Sin(ph);
2087 for (i=0; i<4; i++) {
2090 fXY[i][0] = x*TMath::Cos(-0.5*twist*TMath::DegToRad()) + y*TMath::Sin(-0.5*twist*TMath::DegToRad()) + xc;
2091 fXY[i][1] = -x*TMath::Sin(-0.5*twist*TMath::DegToRad()) + y*TMath::Cos(-0.5*twist*TMath::DegToRad()) + yc;
2096 for (i=4; i<8; i++) {
2099 fXY[i][0] = x*TMath::Cos(0.5*twist*TMath::DegToRad()) + y*TMath::Sin(0.5*twist*TMath::DegToRad()) + xc;
2100 fXY[i][1] = -x*TMath::Sin(0.5*twist*TMath::DegToRad()) + y*TMath::Cos(0.5*twist*TMath::DegToRad()) + yc;
2103 if ((fDz<0) || (fH1<0) || (fBl1<0) || (fTl1<0) ||
2104 (fH2<0) || (fBl2<0) || (fTl2<0)) SetShapeBit(kGeoRunTimeShape);
2105 else TGeoArb8::ComputeBBox();
2111 void TGeoGtra::DistFromInside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
2113 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
2119 void TGeoGtra::DistFromOutside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
2121 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
2129 void TGeoGtra::Safety_v(
const Double_t *points,
const Bool_t *inside, Double_t *safe, Int_t vecsize)
const
2131 for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);