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