Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:31

0001 #pragma once
0002 /**
0003 SCenterExtentFrame : forms glm::tmat4x4<T> model2world and world2model transforms from CE center_extent  
0004 ==========================================================================================================
0005 
0006 rtp_tangential:false
0007     no rotation is included in the model2world and world2model transforms
0008 
0009 rtp_tangential:true 
0010     (radius,theta,phi) is obtained from the CE center_extent and (theta,phi) is used to 
0011     identity a position on an imaginary sphere at which to obtain "RTP" tangential rotations 
0012     that are incorporated into the model2world and world2model transforms.
0013 
0014     This "RTP-tangential" frame facilitates orientation with respect to a shape placed 
0015     on the surface of a sphere.    
0016 
0017  
0018 See also 
0019 
0020 * ana/tangential.py
0021 * ana/pvprim.py
0022 * ana/pvprim1.py
0023 * ana/symtran.py
0024 * ana/tangential.cc
0025 
0026 **/
0027 #include <glm/glm.hpp>
0028 
0029 #include "SYSRAP_API_EXPORT.hh"
0030 
0031 template<typename T>
0032 struct SYSRAP_API SCenterExtentFrame 
0033 {
0034     // convert between coordinate systems
0035     static void CartesianToSpherical( glm::tvec3<T>& radius_theta_phi, const glm::tvec4<T>& xyzw ); 
0036     static void SphericalToCartesian( glm::tvec4<T>& xyzw, const glm::tvec3<T>& radius_theta_phi );
0037 
0038     // rotation matrices between conventional XYZ and tangential RTP cartesian frames 
0039     static glm::tmat4x4<T> XYZ_to_RTP( T theta, T phi );
0040     static glm::tmat4x4<T> RTP_to_XYZ( T theta, T phi );
0041 
0042     SCenterExtentFrame( float  _cx, float  _cy, float  _cz, float  _extent, bool rtp_tangential, bool extent_scale ) ; 
0043     SCenterExtentFrame( double _cx, double _cy, double _cz, double _extent, bool rtp_tangential, bool extent_scale ) ; 
0044 
0045     void init();  
0046     void dump(const char* msg="SCenterExtentFrame::dump") const ; 
0047 
0048     glm::tvec4<T> ce ;    // center extent 
0049     bool          rtp_tangential ; 
0050     bool          extent_scale ; 
0051 
0052     glm::tvec3<T> rtp ;   // radius_theta_phi 
0053     glm::tvec4<T> xyzw ;  
0054 
0055     glm::tmat4x4<T> scale ; 
0056     glm::tmat4x4<T> iscale ; 
0057     glm::tmat4x4<T> translate ; 
0058     glm::tmat4x4<T> itranslate ; 
0059     glm::tmat4x4<T> rotate ; 
0060     glm::tmat4x4<T> irotate ; 
0061 
0062     glm::tmat4x4<T> model2world ; 
0063     glm::tmat4x4<T> world2model ; 
0064 
0065     const T* model2world_data ; 
0066     const T* world2model_data ; 
0067 
0068 
0069 }; 
0070 
0071 #include <iostream>
0072 #include <array>
0073 #include "SPresent.h"
0074 
0075 
0076 /**
0077 SCenterExtentFrame::CartesianToSpherical
0078 -----------------------------------------
0079 
0080 Obtains (radius, theta, phi) from the xyz of the xyzw (NB w is not used). 
0081 
0082 **/
0083 
0084 template<typename T>
0085 inline void SCenterExtentFrame<T>::CartesianToSpherical( glm::tvec3<T>& radius_theta_phi, const glm::tvec4<T>& xyzw ) // static
0086 {
0087     const T x = xyzw.x ; 
0088     const T y = xyzw.y ; 
0089     const T z = xyzw.z ; 
0090     const T radius =  sqrt( x*x + y*y + z*z ) ; 
0091     const T zero(0.) ; 
0092 
0093     const T theta = radius == zero ? zero : acos( z/radius );  
0094     const T phi = atan2(y, x) ; 
0095 
0096     radius_theta_phi.x = radius ; 
0097     radius_theta_phi.y = theta ; 
0098     radius_theta_phi.z = phi ; 
0099 }
0100 /**
0101 SCenterExtentFrame::SphericalToCartesian
0102 -------------------------------------------
0103 
0104 Obtains xyz from the spherical coordinates. NB the xyzw.w is set to 1.
0105 
0106 **/
0107 
0108 template<typename T>
0109 inline void SCenterExtentFrame<T>::SphericalToCartesian( glm::tvec4<T>& xyzw, const glm::tvec3<T>& radius_theta_phi ) // static
0110 {
0111     const T radius = radius_theta_phi.x ;
0112     const T theta  = radius_theta_phi.y ;
0113     const T phi    = radius_theta_phi.z ;
0114     const T one(1.) ; 
0115 
0116     const T x = radius*sin(theta)*cos(phi) ; 
0117     const T y = radius*sin(theta)*sin(phi) ; 
0118     const T z = radius*cos(theta) ; 
0119     const T w = one ; 
0120 
0121     xyzw.x = x ; 
0122     xyzw.y = y ; 
0123     xyzw.z = z ; 
0124     xyzw.w = w ; 
0125 }
0126 
0127 /**
0128 SCenterExtentFrame::XYZ_to_RTP
0129 --------------------------------
0130 
0131 Returns rotation matrix needed for transforming cartesian (x,y,z) 
0132 to a specific tangential frame at a (theta, phi) point on an imaginary sphere. 
0133 NB just the rotation here, no translation 
0134 
0135 **/
0136 
0137 template<typename T>
0138 inline glm::tmat4x4<T> SCenterExtentFrame<T>::XYZ_to_RTP( T theta, T phi )  // static
0139 {
0140     std::array<T, 16> _rot = {{
0141         T(sin(theta)*cos(phi)),  T(sin(theta)*sin(phi)),  T(cos(theta)),  T(0.) ,
0142         T(cos(theta)*cos(phi)),  T(cos(theta)*sin(phi)),  T(-sin(theta)), T(0.) ,
0143         T(-sin(phi)),            T(cos(phi)),             T(0.),          T(0.) ,
0144         T( 0.),                  T(0.),                   T(0.),          T(1.)
0145       }} ;
0146     return glm::make_mat4x4<T>(_rot.data()) ;
0147 }
0148 
0149 
0150 template<typename T>
0151 inline glm::tmat4x4<T> SCenterExtentFrame<T>::RTP_to_XYZ(  T theta, T phi ) // static
0152 {
0153     std::array<T, 16> _iro = {{
0154         T(sin(theta)*cos(phi)),   T(cos(theta)*cos(phi)),  T(-sin(phi)),   T(0.) ,
0155         T(sin(theta)*sin(phi)),   T(cos(theta)*sin(phi)),  T(cos(phi)),    T(0.) ,
0156         T(cos(theta)),            T(-sin(theta)),          T(0.),          T(0.) ,
0157         T(0.),                    T(0.),                   T(0.),          T(1.)
0158       }} ;
0159     return glm::make_mat4x4<T>(_iro.data()) ;
0160 }
0161 
0162 template<typename T>
0163 inline SCenterExtentFrame<T>::SCenterExtentFrame( float _cx, float _cy, float _cz, float _extent, bool _rtp_tangential, bool _extent_scale  )
0164     :
0165     ce(_cx, _cy, _cz, _extent ),
0166     rtp_tangential(_rtp_tangential),
0167     extent_scale(_extent_scale)
0168 {
0169     init(); 
0170 }
0171 
0172 template<typename T>
0173 inline SCenterExtentFrame<T>::SCenterExtentFrame( double _cx, double _cy, double _cz, double _extent, bool _rtp_tangential, bool _extent_scale  )
0174     :
0175     ce(_cx, _cy, _cz, _extent  ),
0176     rtp_tangential(_rtp_tangential),
0177     extent_scale(_extent_scale)
0178 {
0179     init(); 
0180 }
0181 
0182 template<typename T>
0183 inline void SCenterExtentFrame<T>::init()
0184 { 
0185     CartesianToSpherical(rtp, ce);     // ce.w the extent is not used here, just the center ce.xyz
0186     SphericalToCartesian(xyzw, rtp); 
0187 
0188     const T extent = extent_scale ? ce.w : T(1.) ; 
0189 
0190     glm::tvec3<T> sc(extent) ;  
0191     glm::tvec3<T> isc(T(1.)/extent) ;  
0192     glm::tvec3<T> tr(ce) ;  
0193 
0194     T theta = rtp.y ; 
0195     T phi = rtp.z ; 
0196     rotate     = rtp_tangential ? XYZ_to_RTP(theta, phi) : glm::tmat4x4<T>(1.0) ; 
0197     irotate    = rtp_tangential ? RTP_to_XYZ(theta, phi) : glm::tmat4x4<T>(1.0) ; 
0198     scale      = glm::scale(     glm::tmat4x4<T>(1.), sc ) ; 
0199     iscale     = glm::scale(     glm::tmat4x4<T>(1.), isc ) ; 
0200     translate  = glm::translate( glm::tmat4x4<T>(1.), tr ) ; 
0201     itranslate = glm::translate( glm::tmat4x4<T>(1.), -tr ) ; 
0202 
0203     world2model = irotate * iscale * itranslate ; 
0204     model2world = translate * scale * rotate ; 
0205 
0206     world2model_data = glm::value_ptr(world2model) ; 
0207     model2world_data = glm::value_ptr(model2world) ; 
0208 
0209     /**
0210     From Composition::setCenterExtent 
0211 
0212     1409     m_world2model = glm::translate( glm::scale(glm::mat4(1.0), isc), -tr);    
0213     1410     m_model2world = glm::scale(glm::translate(glm::mat4(1.0), tr), sc);
0214 
0215     CANNOT GET THAT WAY OF DOING THINGS TO WORK WITH ROTATION : SO ADOPTED MORE EXPLICIT MULTIPLICATION OF MATRIX FORM
0216     **/
0217 }
0218 
0219 template<typename T>
0220 inline void SCenterExtentFrame<T>::dump(const char* msg) const 
0221 {
0222     std::cout << msg << std::endl ; 
0223     std::cout << SPresent( ce  , "ce") 
0224               << " RTP_TANGENTIAL " << ( rtp_tangential ? "YES" : "NO "  ) 
0225               << " EXTENT_SCALE "   << ( extent_scale ? "YES" : "NO "  ) 
0226               << std::endl 
0227               ; 
0228     std::cout << SPresent( rtp , "rtp") << std::endl ;  
0229     std::cout << SPresent( xyzw , "xyzw") << std::endl ;  
0230 
0231     std::cout << SPresent( rotate, "rotate") << std::endl ;  
0232     std::cout << SPresent( irotate, "irotate") << std::endl ;  
0233 
0234     std::cout << SPresent( scale, "scale") << std::endl ;  
0235     std::cout << SPresent( iscale, "iscale") << std::endl ;  
0236 
0237     std::cout << SPresent( translate, "translate") << std::endl ;  
0238     std::cout << SPresent( itranslate, "itranslate") << std::endl ;  
0239 }
0240 
0241 template struct SCenterExtentFrame<float> ; 
0242 template struct SCenterExtentFrame<double> ; 
0243 
0244