From d17c81bd939df8bb0cc455ab4a55a78bfd4a85c7 Mon Sep 17 00:00:00 2001
From: Frank Gaede <frank.gaede@desy.de>
Date: Wed, 28 May 2014 17:27:04 +0000
Subject: [PATCH]  - added implementations of localToGlobal/globalToLocal   
 for cylindrical surfaces

---
 DDRec/include/DDRec/Surface.h            | 17 +++++++--
 DDRec/src/Surface.cpp                    | 48 +++++++++++++++++++++++-
 DDSurfaces/include/DDSurfaces/ISurface.h | 14 +++----
 DDTest/src/test_surface.cc               | 26 ++++++++++++-
 4 files changed, 93 insertions(+), 12 deletions(-)

diff --git a/DDRec/include/DDRec/Surface.h b/DDRec/include/DDRec/Surface.h
index f5c3277fc..57f46f5f1 100644
--- a/DDRec/include/DDRec/Surface.h
+++ b/DDRec/include/DDRec/Surface.h
@@ -161,7 +161,7 @@ namespace DD4hep {
       /** Convert the global position to the local position (u,v) on the surface */
       virtual Vector2D globalToLocal( const Vector3D& point) const ;
       
-      /** Convert the global position to the local position (u,v) on the surface */
+      /** Convert the local position (u,v) on the surface to the global position */
       virtual Vector3D localToGlobal( const Vector2D& point) const ;
 
       /// Access to the material in opposite direction of the normal
@@ -334,7 +334,12 @@ namespace DD4hep {
       /// Checks if the given point lies within the surface
       virtual bool insideBounds(const Vector3D& point, double epsilon=1.e-4) const  ;
 
-    } ;
+      /** Convert the global position to the local position (u,v) on the surface - u runs along the axis of the cylinder, v is r*phi */
+      virtual Vector2D globalToLocal( const Vector3D& point) const ;
+      
+      /** Convert the local position (u,v) on the surface to the global position  - u runs along the axis of the cylinder, v is r*phi*/
+      virtual Vector3D localToGlobal( const Vector2D& point) const ;
+   } ;
 
     //======================================================================================================
 
@@ -405,7 +410,7 @@ namespace DD4hep {
       /** Convert the global position to the local position (u,v) on the surface */
       virtual Vector2D globalToLocal( const Vector3D& point) const ;
       
-      /** Convert the global position to the local position (u,v) on the surface */
+      /** Convert the local position (u,v) on the surface to the global position*/
       virtual Vector3D localToGlobal( const Vector2D& point) const ;
 
       /** Thickness of inner material */
@@ -471,6 +476,12 @@ namespace DD4hep {
        */
       virtual Vector3D normal(const Vector3D& point = Vector3D() ) const ;
 
+      /** Convert the global position to the local position (u,v) on the surface - u runs along the axis of the cylinder, v is r*phi */
+      virtual Vector2D globalToLocal( const Vector3D& point) const ;
+      
+      /** Convert the local position (u,v) on the surface to the global position  - u runs along the axis of the cylinder, v is r*phi*/
+      virtual Vector3D localToGlobal( const Vector2D& point) const ;
+
       /// the radius of the cylinder (rho of the origin vector)
       virtual double radius() const {
 	return _volSurf.origin().rho() ;
diff --git a/DDRec/src/Surface.cpp b/DDRec/src/Surface.cpp
index 604a840cd..885dfbfd2 100644
--- a/DDRec/src/Surface.cpp
+++ b/DDRec/src/Surface.cpp
@@ -3,7 +3,7 @@
 
 #include "DDRec/MaterialManager.h"
 
-#include <math.h>
+#include <cmath>
 #include <memory>
 #include <exception>
 #include <memory> 
@@ -145,6 +145,32 @@ namespace DD4hep {
 
 
 
+
+    ISurface::Vector2D VolCylinder::globalToLocal( const Vector3D& point) const {
+      
+      // cylinder is parallel to here so u is dZ and v is r *dPhi
+      double phi = point.phi() - origin().phi() ;
+      
+      while( phi < -M_PI ) phi += 2.*M_PI ;
+      while( phi >  M_PI ) phi -= 2.*M_PI ;
+
+      return  ISurface::Vector2D(  point.z() - origin().z() , origin().rho() * phi  ) ;
+    }
+    
+    
+    Vector3D VolCylinder::localToGlobal( const ISurface::Vector2D& point) const {
+
+      double z = point.u() + origin().z() ;
+      double phi = point.v() / origin().rho() + origin().phi() ;
+
+      while( phi < -M_PI ) phi += 2.*M_PI ;
+      while( phi >  M_PI ) phi -= 2.*M_PI ;
+
+      return Vector3D( origin().rho() , phi, z  , Vector3D::cylindrical )    ;
+    }
+
+
+
     VolCylinder::VolCylinder( Geometry::Volume vol, SurfaceType type, double thickness_inner ,double thickness_outer,  Vector3D o ) :
 
       VolSurface( vol, type, thickness_inner, thickness_outer, Vector3D() , Vector3D() , Vector3D() , o ) {
@@ -752,6 +778,7 @@ namespace DD4hep {
     }
 
     //================================================================================================================
+
     Vector3D CylinderSurface::u( const Vector3D& point  ) const { 
 
       Vector3D lp , u ;
@@ -776,6 +803,25 @@ namespace DD4hep {
       _wtM->LocalToMasterVect( ln , n.array() ) ;
       return n ; 
     }
+
+    ISurface::Vector2D CylinderSurface::globalToLocal( const Vector3D& point) const {
+      
+      Vector3D lp , n ;
+      _wtM->MasterToLocal( point , lp.array() ) ;
+
+      return  _volSurf.globalToLocal( lp )  ;
+    }
+    
+    
+    Vector3D CylinderSurface::localToGlobal( const ISurface::Vector2D& point) const {
+
+      Vector3D lp = _volSurf.localToGlobal( point ) ;
+      Vector3D p ;
+      _wtM->LocalToMasterVect( lp , p.array() ) ;
+
+      return p ;
+    }
+
     //================================================================================================================
 
 
diff --git a/DDSurfaces/include/DDSurfaces/ISurface.h b/DDSurfaces/include/DDSurfaces/ISurface.h
index f33b54d11..3c3bb0355 100644
--- a/DDSurfaces/include/DDSurfaces/ISurface.h
+++ b/DDSurfaces/include/DDSurfaces/ISurface.h
@@ -28,12 +28,12 @@ namespace DDSurfaces {
 
     /** Helper class for 2d vectors */
     struct Vector2D{
-      double _x,_y ;
-      Vector2D() : _x(0.),_y(0.) {}
-      Vector2D(double x, double y ) : _x(x),_y(y) {}
-      double operator[](unsigned i) const { return i==0 ? _x : _y ; }  
-      double x() const { return _x ; } 
-      double y() const { return _y ; } 
+      double _u,_v ;
+      Vector2D() : _u(0.),_v(0.) {}
+      Vector2D(double u, double v ) : _u(u),_v(v) {}
+      double operator[](unsigned i) const { return i==0 ? _u : _v ; }  
+      double u() const { return _u ; } 
+      double v() const { return _v ; } 
     };
 
 
@@ -61,7 +61,7 @@ namespace DDSurfaces {
     /** Convert the global position to the local position (u,v) on the surface */
     virtual Vector2D globalToLocal( const Vector3D& point) const=0 ;
 
-    /** Convert the global position to the local position (u,v) on the surface */
+    /** Convert the local position (u,v) on the surface to the global position*/
     virtual Vector3D localToGlobal( const Vector2D& point) const=0 ;
 
     /** Get Origin of local coordinate system on surface */
diff --git a/DDTest/src/test_surface.cc b/DDTest/src/test_surface.cc
index 05a28561c..06c9e3ac7 100644
--- a/DDTest/src/test_surface.cc
+++ b/DDTest/src/test_surface.cc
@@ -93,7 +93,7 @@ int main(int argc, char** argv ){
     test( surf.insideBounds(  Vector3D(  0.00003 ,  .23 ,  .42  )  ) , true , " insideBounds Vector3D(   0.00003 ,  .23 ,  .42  )   " ) ; 
 
 
-    // === test global to local =====
+    //=============== test global to local ===================
 
     Vector3D point = o + 34.3 * u - 42.7 * v ; 
 
@@ -220,6 +220,30 @@ int main(int argc, char** argv ){
       std::cout << " ** yv = " << yv << std::endl ;
 
 
+    //=============== test global to local ===================
+    
+    Vector3D pointC( radius , -42.7/radius , 34.3  , Vector3D::cylindrical  )  ;
+    
+    ISurface::Vector2D lpC = surfT.globalToLocal( pointC ) ;
+
+    // std::cout << " --- local coordinates of " << pointC << " : (" << lpC[0] << "," << lpC[1] << ")" << std::endl ;
+
+    test(  STR( lpC[0] ) == STR( 34.3 ) , true , " local u coordinate is 34.4 "  ) ;  
+    test(  STR( lpC[1] ) == STR( -42.7 ) , true , " local v coordinate is -42.7 "  ) ;  
+
+    Vector3D pointPrimeC = surfT.localToGlobal( lpC ) ;
+
+    // std::cout << " --- global coordinates of point after local to global ( " << pointC.rho() << ", " << pointC.phi() << ", " << pointC.z()
+    //   	      << " ) : (" << lpC[0] << "," << lpC[1] << ")" << std::endl ;
+
+    test(  pointPrimeC.isEqual( pointC ) , true , " point after global to local to global is the same " ) ;
+
+    //========================================================
+
+
+
+
+
     // test surface type:
 
     test( surfT.type().isSensitive() , true , " surface is sensitive " )  ;
-- 
GitLab