From 8e15e801026e5f6bae18ecd9ef6df97d99faf5d7 Mon Sep 17 00:00:00 2001
From: Frank Gaede <frank.gaede@desy.de>
Date: Tue, 27 May 2014 14:30:54 +0000
Subject: [PATCH]  - added new methods to ISurface:      virtual Vector2D
 globalToLocal( const Vector3D& point) const ;      virtual Vector3D
 localToGlobal( const Vector2D& point) const ;  - implementation in
 VolSurface/Surface for planes  - added simple tests in  test_surface  - to be
 done: cylinders ...

---
 DDRec/include/DDRec/Surface.h            | 12 ++++++
 DDRec/src/Surface.cpp                    | 53 +++++++++++++++++++++++-
 DDSurfaces/include/DDSurfaces/ISurface.h | 21 +++++++++-
 DDTest/src/test_surface.cc               | 48 +++++++++++++++++++++
 4 files changed, 131 insertions(+), 3 deletions(-)

diff --git a/DDRec/include/DDRec/Surface.h b/DDRec/include/DDRec/Surface.h
index d41216f18..f5c3277fc 100644
--- a/DDRec/include/DDRec/Surface.h
+++ b/DDRec/include/DDRec/Surface.h
@@ -158,6 +158,12 @@ namespace DD4hep {
       /** Get Origin of local coordinate system on surface */
       virtual const Vector3D& origin() const { return object<SurfaceData>()._o ;}
 
+      /** 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 */
+      virtual Vector3D localToGlobal( const Vector2D& point) const ;
+
       /// Access to the material in opposite direction of the normal
       virtual const IMaterial& innerMaterial() const{  return  object<SurfaceData>()._innerMat ;  }
 
@@ -396,6 +402,12 @@ namespace DD4hep {
       /** Get Origin of local coordinate system on surface */
       virtual const Vector3D& origin() const { return _o ;}
 
+      /** 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 */
+      virtual Vector3D localToGlobal( const Vector2D& point) const ;
+
       /** Thickness of inner material */
       virtual double innerThickness() const { return _volSurf.innerThickness() ; }
 
diff --git a/DDRec/src/Surface.cpp b/DDRec/src/Surface.cpp
index bdebf7b5c..604a840cd 100644
--- a/DDRec/src/Surface.cpp
+++ b/DDRec/src/Surface.cpp
@@ -66,6 +66,31 @@ namespace DD4hep {
     }      
     
 
+    ISurface::Vector2D VolSurface::globalToLocal( const Vector3D& point) const {
+
+      Vector3D p = point - origin() ;
+
+      // create new orthogonal unit vectors
+      // FIXME: these vectors should be cached really ... 
+
+      double uv = u() * v() ;
+      Vector3D uprime = ( u() - uv * v() ).unit() ; 
+      Vector3D vprime = ( v() - uv * u() ).unit() ; 
+      double uup = u() * uprime ;
+      double vvp = v() * vprime ;
+      
+      return  ISurface::Vector2D(   p*uprime / uup ,  p*vprime / vvp ) ;
+    }
+    
+    Vector3D VolSurface::localToGlobal( const ISurface::Vector2D& point) const {
+
+      Vector3D g = origin() + point[0] * u() + point[1] * v() ;
+
+      return g ;
+    }
+
+
+
     /** Distance to surface */
     double VolPlane::distance(const Vector3D& point ) const {
 
@@ -74,8 +99,7 @@ namespace DD4hep {
     
     /// Checks if the given point lies within the surface
     bool VolPlane::insideBounds(const Vector3D& point, double epsilon) const {
-
-
+      
 #if 0
       double dist = std::abs ( distance( point ) ) ;
       
@@ -320,6 +344,31 @@ namespace DD4hep {
       return  mat ;
     }          
 
+
+    ISurface::Vector2D Surface::globalToLocal( const Vector3D& point) const {
+
+    Vector3D p = point - origin() ;
+
+      // create new orthogonal unit vectors
+      // FIXME: these vectors should be cached really ... 
+
+      double uv = u() * v() ;
+      Vector3D uprime = ( u() - uv * v() ).unit() ; 
+      Vector3D vprime = ( v() - uv * u() ).unit() ; 
+      double uup = u() * uprime ;
+      double vvp = v() * vprime ;
+      
+      return  ISurface::Vector2D(   p*uprime / uup ,  p*vprime / vvp ) ;
+    }
+    
+    
+    Vector3D Surface::localToGlobal( const ISurface::Vector2D& point) const {
+
+      Vector3D g = origin() + point[0] * u() + point[1] * v() ;
+      return g ;
+    }
+
+
     double Surface::distance(const Vector3D& point ) const {
 
       double pa[3] ;
diff --git a/DDSurfaces/include/DDSurfaces/ISurface.h b/DDSurfaces/include/DDSurfaces/ISurface.h
index 1efd20a6d..f33b54d11 100644
--- a/DDSurfaces/include/DDSurfaces/ISurface.h
+++ b/DDSurfaces/include/DDSurfaces/ISurface.h
@@ -13,7 +13,8 @@ namespace DDSurfaces {
 
   typedef long long int long64 ;
 
- /** Interface for tracking surfaces. 
+
+  /** Interface for tracking surfaces. 
    * The surface provides access to vectors for u,v,n and the orgigin and
    * the inner and outer materials with corresponding thicknesses.
    *  
@@ -24,6 +25,18 @@ namespace DDSurfaces {
   class ISurface {
     
   public:
+
+    /** 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 ; } 
+    };
+
+
     /// Destructor
     virtual ~ISurface() {}
     
@@ -45,6 +58,12 @@ namespace DDSurfaces {
     /// Access to the normal direction at the given point
     virtual Vector3D normal(const Vector3D& point = Vector3D() ) const =0 ;
     
+    /** 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 */
+    virtual Vector3D localToGlobal( const Vector2D& point) const=0 ;
+
     /** Get Origin of local coordinate system on surface */
     virtual const Vector3D& origin() const =0 ;
     
diff --git a/DDTest/src/test_surface.cc b/DDTest/src/test_surface.cc
index 4fb1ddd55..05a28561c 100644
--- a/DDTest/src/test_surface.cc
+++ b/DDTest/src/test_surface.cc
@@ -93,6 +93,54 @@ 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 =====
+
+    Vector3D point = o + 34.3 * u - 42.7 * v ; 
+
+    ISurface::Vector2D lp = surf.globalToLocal( point ) ;
+    //    std::cout << " --- local coordinates of " << point << " : (" << lp[0] << "," << lp[1] << ")" << std::endl ;
+    test(  STR( lp[0] ) == STR( 34.3 ) , true , " local u coordinate is 34.4 "  ) ;  
+    test(  STR( lp[1] ) == STR( -42.7 ) , true , " local v coordinate is -42.7 "  ) ;  
+
+    Vector3D pointPrime = surf.localToGlobal( lp ) ;
+    test(  pointPrime.isEqual( point ) , true , " point after global to local to global is the same " ) ;
+
+    // ----- test with rotated coordinates
+    Vector3D ur,vr ; 
+    ur.fill( 0. ,  cos( 3.5/180.*M_PI  ) ,  sin( 3.5/180.*M_PI  ) ) ;
+    vr.fill( 0. , -sin( 3.5/180.*M_PI  ) ,  cos( 3.5/180.*M_PI  ) ) ;
+    VolPlane surfR( vol , SurfaceType( SurfaceType::Sensitive ), thick/2, thick/2 , ur,vr,n,o ) ;
+
+    Vector3D pointR = o + 34.3 * ur - 42.7 * vr ; 
+
+    lp = surfR.globalToLocal( pointR ) ;
+    //    std::cout << " --- local coordinates of " << pointR << " : (" << lp[0] << "," << lp[1] << ")" << std::endl ;
+    test(  STR( lp[0] ) == STR( 34.3 ) , true , " local u coordinate is 34.4 "  ) ;  
+    test(  STR( lp[1] ) == STR( -42.7 ) , true , " local v coordinate is -42.7 "  ) ;  
+
+    Vector3D pointPrimeR = surfR.localToGlobal( lp ) ;
+    test(  pointPrimeR.isEqual( pointR ) , true , " point after global to local to global is the same " ) ;
+
+    // ----- test with non-orthogonal rotated coordinates
+    Vector3D vr2 ; 
+    vr2.fill( 0. , -sin( 35./180.*M_PI  ) ,  cos( 35./180.*M_PI  ) ) ;
+    VolPlane surfR2( vol , SurfaceType( SurfaceType::Sensitive ), thick/2, thick/2 , ur,vr2,n,o ) ;
+
+    Vector3D pointR2 = o + 34.3 * ur - 42.7 * vr2 ; 
+
+    lp = surfR2.globalToLocal( pointR2 ) ;
+    //    std::cout << " --- local coordinates of " << pointR << " : (" << lp[0] << "," << lp[1] << ")" << std::endl ;
+    test(  STR( lp[0] ) == STR( 34.3 ) , true , " local u coordinate is 34.4 "  ) ;  
+    test(  STR( lp[1] ) == STR( -42.7 ) , true , " local v coordinate is -42.7 "  ) ;  
+
+    Vector3D pointPrimeR2 = surfR2.localToGlobal( lp ) ;
+    test(  pointPrimeR2.isEqual( pointR2 ) , true , " point after global to local to global is the same " ) ;
+
+
+    //==================================================
+
+
+
     // --- test SurfaceMaterial
     SurfaceMaterial sm( mat ) ;
 
-- 
GitLab