159 TGeoMatrix *TGeoShape::fgTransform = NULL;
160 Double_t TGeoShape::fgEpsMch = 2.220446049250313e-16;
165 TGeoShape::TGeoShape()
170 gGeoManager =
new TGeoManager(
"Geometry",
"default geometry");
180 TGeoShape::TGeoShape(
const char *name)
186 gGeoManager =
new TGeoManager(
"Geometry",
"default geometry");
189 fShapeId = gGeoManager->GetListOfShapes()->GetSize();
190 gGeoManager->AddShape(
this);
196 TGeoShape::~TGeoShape()
198 if (gGeoManager && !gGeoManager->IsCleaning()) gGeoManager->GetListOfShapes()->Remove(
this);
209 void TGeoShape::CheckShape(Int_t testNo, Int_t nsamples, Option_t *option)
212 Error(
"CheckShape",
"No geometry manager");
215 TGeoShape *shape = (TGeoShape*)
this;
216 gGeoManager->CheckShape(shape, testNo, nsamples, option);
223 Double_t TGeoShape::ComputeEpsMch()
225 Double_t temp1 = 1.0;
226 Double_t temp2 = 1.0 + temp1;
227 Double_t mchEps = 0.;
240 Double_t TGeoShape::EpsMch()
248 const char *TGeoShape::GetName()
const
251 return ((TObject *)
this)->ClassName();
253 return TNamed::GetName();
259 Int_t TGeoShape::ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py)
const
261 TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
262 if (!painter)
return 9999;
263 return painter->ShapeDistancetoPrimitive(
this, numpoints, px, py);
269 Bool_t TGeoShape::IsCloseToPhi(Double_t epsil,
const Double_t *point, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
271 Double_t saf1 = TGeoShape::Big();
272 Double_t saf2 = TGeoShape::Big();
273 if (point[0]*c1+point[1]*s1 >= 0) saf1 = TMath::Abs(-point[0]*s1 + point[1]*c1);
274 if (point[0]*c2+point[1]*s2 >= 0) saf2 = TMath::Abs(point[0]*s2 - point[1]*c2);
275 Double_t saf = TMath::Min(saf1,saf2);
276 if (saf<epsil)
return kTRUE;
283 Bool_t TGeoShape::IsInPhiRange(
const Double_t *point, Double_t phi1, Double_t phi2)
285 Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
286 while (phi<phi1) phi+=360.;
287 Double_t ddp = phi-phi1;
288 if (ddp>phi2-phi1)
return kFALSE;
297 Bool_t TGeoShape::IsCrossingSemiplane(
const Double_t *point,
const Double_t *dir, Double_t cphi, Double_t sphi, Double_t &snext, Double_t &rxy)
299 snext = rxy = TGeoShape::Big();
302 Double_t rxy0 = point[0]*cphi+point[1]*sphi;
303 Double_t rdotn = point[0]*nx + point[1]*ny;
304 if (TMath::Abs(rdotn)<TGeoShape::Tolerance()) {
315 Double_t ddotn = dir[0]*nx + dir[1]*ny;
316 if (ddotn<=0)
return kFALSE;
318 rxy = rxy0+snext*(dir[0]*cphi+dir[1]*sphi);
319 if (rxy<0)
return kFALSE;
326 Bool_t TGeoShape::IsSameWithinTolerance(Double_t a, Double_t b)
328 if (TMath::Abs(a-b)<1.E-10)
return kTRUE;
336 Bool_t TGeoShape::IsSegCrossing(Double_t x1, Double_t y1, Double_t x2, Double_t y2,Double_t x3, Double_t y3,Double_t x4, Double_t y4)
338 Double_t eps = TGeoShape::Tolerance();
339 Bool_t stand1 = kFALSE;
340 Double_t dx1 = x2-x1;
341 Bool_t stand2 = kFALSE;
342 Double_t dx2 = x4-x3;
349 if (TMath::Abs(dx1) < eps) stand1 = kTRUE;
350 if (TMath::Abs(dx2) < eps) stand2 = kTRUE;
352 a1 = (x2*y1-x1*y2)/dx1;
356 a2 = (x4*y3-x3*y4)/dx2;
359 if (stand1 && stand2) {
361 if (TMath::Abs(x1-x3)<eps) {
363 if ((y3-y1)*(y3-y2)<-eps || (y4-y1)*(y4-y2)<-eps ||
364 (y1-y3)*(y1-y4)<-eps || (y2-y3)*(y2-y4)<-eps)
return kTRUE;
382 if (TMath::Abs(b1-b2)<eps) {
384 if (TMath::Abs(y3-(a1+b1*x3))>eps)
return kFALSE;
386 if ((x3-x1)*(x3-x2)<-eps || (x4-x1)*(x4-x2)<-eps ||
387 (x1-x3)*(x1-x4)<-eps || (x2-x3)*(x2-x4)<-eps)
return kTRUE;
390 xm = (a1-a2)/(b2-b1);
391 ym = (a1*b2-a2*b1)/(b2-b1);
395 Double_t check = (xm-x1)*(xm-x2)+(ym-y1)*(ym-y2);
396 if (check > -eps)
return kFALSE;
397 check = (xm-x3)*(xm-x4)+(ym-y3)*(ym-y4);
398 if (check > -eps)
return kFALSE;
405 Double_t TGeoShape::DistToPhiMin(
const Double_t *point,
const Double_t *dir, Double_t s1, Double_t c1,
406 Double_t s2, Double_t c2, Double_t sm, Double_t cm, Bool_t in)
408 Double_t sfi1=TGeoShape::Big();
409 Double_t sfi2=TGeoShape::Big();
411 Double_t un = dir[0]*s1-dir[1]*c1;
414 s=-point[0]*s1+point[1]*c1;
418 if (((point[0]+s*dir[0])*sm-(point[1]+s*dir[1])*cm)>=0) sfi1=s;
421 un = -dir[0]*s2+dir[1]*c2;
424 s=point[0]*s2-point[1]*c2;
428 if ((-(point[0]+s*dir[0])*sm+(point[1]+s*dir[1])*cm)>=0) sfi2=s;
431 return TMath::Min(sfi1, sfi2);
437 void TGeoShape::NormalPhi(
const Double_t *point,
const Double_t *dir, Double_t *norm, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
439 Double_t saf1 = TGeoShape::Big();
440 Double_t saf2 = TGeoShape::Big();
441 if (point[0]*c1+point[1]*s1 >= 0) saf1 = TMath::Abs(-point[0]*s1 + point[1]*c1);
442 if (point[0]*c2+point[1]*s2 >= 0) saf2 = TMath::Abs(point[0]*s2 - point[1]*c2);
454 if (dir[0]*norm[0]+dir[1]*norm[1] < 0) {
464 Double_t TGeoShape::SafetyPhi(
const Double_t *point, Bool_t in, Double_t phi1, Double_t phi2)
466 Bool_t inphi = TGeoShape::IsInPhiRange(point, phi1, phi2);
467 if (inphi && !in)
return -TGeoShape::Big();
468 phi1 *= TMath::DegToRad();
469 phi2 *= TMath::DegToRad();
470 Double_t c1 = TMath::Cos(phi1);
471 Double_t s1 = TMath::Sin(phi1);
472 Double_t c2 = TMath::Cos(phi2);
473 Double_t s2 = TMath::Sin(phi2);
474 Double_t rsq = point[0]*point[0]+point[1]*point[1];
475 Double_t rproj = point[0]*c1+point[1]*s1;
476 Double_t safsq = rsq-rproj*rproj;
477 if (safsq<0)
return 0.;
478 Double_t saf1 = (rproj<0)?TGeoShape::Big():TMath::Sqrt(safsq);
479 rproj = point[0]*c2+point[1]*s2;
480 safsq = rsq-rproj*rproj;
481 if (safsq<0)
return 0.;
482 Double_t saf2 = (rproj<0)?TGeoShape::Big():TMath::Sqrt(safsq);
483 Double_t safe = TMath::Min(saf1, saf2);
485 if (in)
return TGeoShape::Big();
486 return -TGeoShape::Big();
494 Double_t TGeoShape::SafetySeg(Double_t r, Double_t z, Double_t r1, Double_t z1, Double_t r2, Double_t z2, Bool_t outer)
496 Double_t crossp = (z2-z1)*(r-r1)-(z-z1)*(r2-r1);
497 crossp *= (outer) ? 1. : -1.;
499 if (crossp < -TGeoShape::Tolerance()) {
501 if (outer)
return TGeoShape::Big();
505 Double_t c1 = (z-z1)*(z2-z1)+(r-r1)*(r2-r1);
507 if (c1<1.E-10)
return TMath::Sqrt((r-r1)*(r-r1)+(z-z1)*(z-z1));
509 Double_t c2 = (z-z2)*(z2-z1)+(r-r2)*(r2-r1);
511 if (c2>-1.E-10)
return TMath::Sqrt((r-r2)*(r-r2)+(z-z2)*(z-z2));
513 c2 = (z2-z1)*(z2-z1)+(r2-r1)*(r2-r1);
515 Double_t alpha = c1/c2;
516 Double_t rp = r1 + alpha*(r2-r1);
517 Double_t zp = z1 + alpha*(z2-z1);
518 return TMath::Sqrt((r-rp)*(r-rp)+(z-zp)*(z-zp));
524 void TGeoShape::SetShapeBit(UInt_t f, Bool_t set)
536 TGeoMatrix *TGeoShape::GetTransform()
544 void TGeoShape::SetTransform(TGeoMatrix *matrix)
546 fgTransform = matrix;
552 void TGeoShape::TransformPoints(Double_t *points, UInt_t NbPnts)
const
557 for (j = 0; j < NbPnts; j++) {
559 fgTransform->LocalToMaster(&points[i], dmaster);
560 points[i] = dmaster[0];
561 points[i+1] = dmaster[1];
562 points[i+2] = dmaster[2];
566 if (!gGeoManager)
return;
567 Bool_t bomb = (gGeoManager->GetBombMode()==0)?kFALSE:kTRUE;
569 for (j = 0; j < NbPnts; j++) {
571 if (gGeoManager->IsMatrixTransform()) {
572 TGeoHMatrix *glmat = gGeoManager->GetGLMatrix();
573 if (bomb) glmat->LocalToMasterBomb(&points[i], dmaster);
574 else glmat->LocalToMaster(&points[i], dmaster);
576 if (bomb) gGeoManager->LocalToMasterBomb(&points[i], dmaster);
577 else gGeoManager->LocalToMaster(&points[i],dmaster);
579 points[i] = dmaster[0];
580 points[i+1] = dmaster[1];
581 points[i+2] = dmaster[2];
589 void TGeoShape::FillBuffer3D(TBuffer3D & buffer, Int_t reqSections, Bool_t localFrame)
const
594 if (reqSections & TBuffer3D::kRaw) {
595 if (!(reqSections & TBuffer3D::kRawSizes) && !buffer.SectionsValid(TBuffer3D::kRawSizes)) {
600 if (reqSections & TBuffer3D::kCore) {
602 buffer.ClearSectionsValid();
609 const TGeoVolume * paintVolume = gGeoManager->GetPaintVolume();
610 if (!paintVolume) paintVolume = gGeoManager->GetTopVolume();
612 buffer.fID =
const_cast<TGeoShape *
>(
this);
614 buffer.fTransparency = 0;
618 buffer.fID =
const_cast<TGeoVolume *
>(paintVolume);
619 buffer.fColor = paintVolume->GetLineColor();
621 buffer.fTransparency = paintVolume->GetTransparency();
622 Double_t visdensity = gGeoManager->GetVisDensity();
623 if (visdensity>0 && paintVolume->GetMedium()) {
624 if (paintVolume->GetMaterial()->GetDensity() < visdensity) {
625 buffer.fTransparency = 90;
630 buffer.fLocalFrame = localFrame;
632 r1 = gGeoManager->IsMatrixReflection();
633 if (paintVolume && paintVolume->GetShape()) {
634 if (paintVolume->GetShape()->IsReflected()) {
637 if (buffer.Type() < TBuffer3DTypes::kTube) r2 = kTRUE;
640 buffer.fReflection = ((r1&(!r2))|(r2&!(r1)));
644 TGeoMatrix * localMasterMat = 0;
645 if (TGeoShape::GetTransform()) {
646 localMasterMat = TGeoShape::GetTransform();
648 localMasterMat = gGeoManager->GetCurrentMatrix();
653 if (gGeoManager->IsMatrixTransform() && !IsComposite()) {
654 localMasterMat = gGeoManager->GetGLMatrix();
657 if (!localMasterMat) {
661 localMasterMat->GetHomogenousMatrix(buffer.fLocalMaster);
663 buffer.SetLocalMasterIdentity();
666 buffer.SetSectionsValid(TBuffer3D::kCore);
673 Int_t TGeoShape::GetBasicColor()
const
675 Int_t basicColor = 0;
677 const TGeoVolume * volume = gGeoManager->GetPaintVolume();
679 basicColor = ((volume->GetLineColor() %8) -1) * 4;
680 if (basicColor < 0) basicColor = 0;
689 const TBuffer3D &TGeoShape::GetBuffer3D(Int_t , Bool_t )
const
691 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
692 Warning(
"GetBuffer3D",
"this must be implemented for shapes in a TGeoPainter hierarchy. This will be come a pure virtual fn eventually.");
699 const char *TGeoShape::GetPointerName()
const
702 Int_t uid = GetUniqueID();
703 if (uid) name = TString::Format(
"p%s_%d", GetName(),uid);
704 else name = TString::Format(
"p%s", GetName());
711 void TGeoShape::ExecuteEvent(Int_t event, Int_t px, Int_t py)
713 if (!gGeoManager)
return;
714 TVirtualGeoPainter *painter = gGeoManager->GetPainter();
715 painter->ExecuteShapeEvent(
this, event, px, py);
721 void TGeoShape::Draw(Option_t *option)
723 TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
724 if (option && option[0]) {
725 painter->DrawShape(
this, option);
727 painter->DrawShape(
this, gEnv->GetValue(
"Viewer3D.DefaultDrawOption",
""));
734 void TGeoShape::Paint(Option_t *option)
736 TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
737 if (option && option[0]) {
738 painter->PaintShape(
this, option);
740 painter->PaintShape(
this, gEnv->GetValue(
"Viewer3D.DefaultDrawOption",
""));