From 9270ef4a755e5e4d56b470270a0bef0c150c0c08 Mon Sep 17 00:00:00 2001
From: Rene Brun <Rene.Brun@cern.ch>
Date: Fri, 18 Jul 2008 15:08:05 +0000
Subject: [PATCH] From Andrei: a fix in safety computation of
 TGeoArb8::Safety(point, inside) when 'inside' was not matching the real point
 position.

git-svn-id: http://root.cern.ch/svn/root/trunk@24893 27541ba8-7e3a-0410-8455-c3a389f83636
---
 geom/geom/src/TGeoArb8.cxx           | 50 ++++++++++------------------
 geom/geompainter/inc/TGeoOverlap.h   |  1 +
 geom/geompainter/src/TGeoOverlap.cxx | 26 +++++++++++++++
 3 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/geom/geom/src/TGeoArb8.cxx b/geom/geom/src/TGeoArb8.cxx
index c84e1e327ef..76b0b560f5b 100644
--- a/geom/geom/src/TGeoArb8.cxx
+++ b/geom/geom/src/TGeoArb8.cxx
@@ -258,7 +258,7 @@ void TGeoArb8::ComputeTwist()
          continue;
       }
       twist[i] = dy1*dx2 - dx1*dy2;
-      if (TMath::Abs(twist[i])<1E-3) {
+      if (TMath::Abs(twist[i])<TGeoShape::Tolerance()) {
          twist[i] = 0;
          continue;
       }
@@ -801,7 +801,6 @@ Double_t TGeoArb8::Safety(Double_t *point, Bool_t in) const
    Double_t safz = fDz-TMath::Abs(point[2]);
    if (!in) safz = -safz;
    Int_t iseg;
-   Double_t safmin = TGeoShape::Big();
    Double_t safe = TGeoShape::Big();
    Double_t lsq, ssq, dx, dy, dpx, dpy, u;
    if (IsTwisted()) {
@@ -860,22 +859,14 @@ Double_t TGeoArb8::Safety(Double_t *point, Bool_t in) const
       return safe;   
    }  
       
+   Double_t saf[5];
+   saf[0] = safz;
       
-   for (iseg=0; iseg<4; iseg++) {
-      safe = SafetyToFace(point,iseg,in);
-      if (safe>0) {
-         if (in && safe<safmin) {
-            safmin = safe;
-            continue;
-         }
-         if (!in && safe<1E10) {
-            if (safmin<1E10) safe = TMath::Max(safe,safmin);
-            else safmin=safe;
-         }
-      }           
-   }
-   if (in) return TMath::Min(safmin, safz);
-   return TMath::Max(safmin, safz);   
+   for (iseg=0; iseg<4; iseg++) saf[iseg+1] = SafetyToFace(point,iseg,in);
+   if (in) safe = saf[TMath::LocMin(5, saf)];
+   else    safe = saf[TMath::LocMax(5, saf)];   
+   if (safe<0) return 0.;
+   return safe;
 }
 
 //_____________________________________________________________________________
@@ -901,25 +892,20 @@ Double_t TGeoArb8::SafetyToFace(Double_t *point, Int_t iseg, Bool_t in) const
    vertices[9] = fXY[iseg+4][0];
    vertices[10] = fXY[iseg+4][1];
    vertices[11] = fDz;
-   Double_t twist = GetTwist(iseg);
    Double_t safe;
    Double_t norm[3];
    Double_t *p1, *p2, *p3;
-   if (twist ==0) {
-      p1 = &vertices[0];
-      p2 = &vertices[9];
-      p3 = &vertices[6];
-      if (IsSamePoint(p2,p3)) {
-         p3 = &vertices[3];
-         if (IsSamePoint(p1,p3)) return TGeoShape::Big(); // skip single segment
-      }
-      GetPlaneNormal(p1,p2,p3,norm);
-      safe = (point[0]-p1[0])*norm[0]+(point[1]-p1[1])*norm[1]+(point[2]-p1[2])*norm[2];
-      if (in) return (-safe);
-      return safe;
+   p1 = &vertices[0];
+   p2 = &vertices[9];
+   p3 = &vertices[6];
+   if (IsSamePoint(p2,p3)) {
+      p3 = &vertices[3];
+      if (IsSamePoint(p1,p3)) return -TGeoShape::Big(); // skip single segment
    }
-   // The face is twisted
-   return TGeoShape::Big();
+   GetPlaneNormal(p1,p2,p3,norm);
+   safe = (point[0]-p1[0])*norm[0]+(point[1]-p1[1])*norm[1]+(point[2]-p1[2])*norm[2];
+   if (in) return (-safe);
+   return safe;
 }
    
 //_____________________________________________________________________________
diff --git a/geom/geompainter/inc/TGeoOverlap.h b/geom/geompainter/inc/TGeoOverlap.h
index 49124b02808..ec13b6f1c04 100644
--- a/geom/geompainter/inc/TGeoOverlap.h
+++ b/geom/geompainter/inc/TGeoOverlap.h
@@ -102,6 +102,7 @@ public:
    void              SetFirstMatrix(TGeoMatrix *matrix) {*fMatrix1 = matrix;}
    void              SetSecondMatrix(TGeoMatrix *matrix) {*fMatrix2 = matrix;}
    void              SetOverlap(Double_t ovlp)  {fOverlap=ovlp;}
+   void              Validate() const; // *MENU*
    
    ClassDef(TGeoOverlap, 2)         // base class for geometical overlaps
 };
diff --git a/geom/geompainter/src/TGeoOverlap.cxx b/geom/geompainter/src/TGeoOverlap.cxx
index 08a0ab72756..c747f849cff 100644
--- a/geom/geompainter/src/TGeoOverlap.cxx
+++ b/geom/geompainter/src/TGeoOverlap.cxx
@@ -223,3 +223,29 @@ void TGeoOverlap::Sizeof3D() const
    fVolume1->GetShape()->Sizeof3D();
    fVolume2->GetShape()->Sizeof3D();
 }
+
+//______________________________________________________________________________
+void TGeoOverlap::Validate() const
+{
+// Validate this overlap.
+   Double_t point[3];
+   Double_t local[3];
+   Double_t safe1,safe2;
+   Int_t npoints = fMarker->GetN();
+   for (Int_t i=0; i<npoints; i++) {
+      fMarker->GetPoint(i, point[0], point[1], point[2]);
+      if (IsExtrusion()) {
+         fMatrix1->MasterToLocal(point,local);
+         safe1 = fVolume1->GetShape()->Safety(local, kFALSE);
+         printf("point %d: safe1=%f\n", i, safe1);
+      } else {
+         fMatrix1->MasterToLocal(point,local);  
+         safe1 = fVolume1->GetShape()->Safety(local, kTRUE);
+         fMatrix2->MasterToLocal(point,local);  
+         safe2 = fVolume2->GetShape()->Safety(local, kTRUE);
+         printf("point %d: safe1=%f safe2=%f\n", i, safe1,safe2);
+      }
+   }
+}
+         
+         
-- 
GitLab