File indexing completed on 2026-04-09 07:48:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <cstdlib>
0015 #include <vector>
0016 #include <array>
0017 #include <iostream>
0018 #include <iomanip>
0019 #include <string>
0020 #include <sstream>
0021
0022 #include <glm/glm.hpp>
0023 #include <glm/gtx/string_cast.hpp>
0024 #include <glm/gtc/type_ptr.hpp>
0025
0026
0027 template<typename T>
0028 struct Tangential
0029 {
0030 static const T pi ;
0031 static void GetEVector( std::vector<T>& vec, const char* ekey, const char* fallback );
0032 static glm::tmat4x4<T> Rotation( T theta, T phi ) ;
0033 static glm::tmat4x4<T> IRotation( T theta, T phi ) ;
0034 static glm::tmat4x4<T> Translation( T radius, T theta, T phi ) ;
0035 static glm::tmat4x4<T> ITranslation( T radius, T theta, T phi ) ;
0036
0037 static void CartesianToSpherical( glm::tvec3<T>& radius_theta_phi, const glm::tvec4<T>& xyzw );
0038
0039 Tangential( T radius, T theta, T phi );
0040
0041 void conventional_to_tangential( glm::tvec4<T>& rtpw , const glm::tvec4<T>& xyzw );
0042 void tangential_to_conventional( glm::tvec4<T>& xyzw , const glm::tvec4<T>& rtpw );
0043 void dump() const ;
0044
0045 glm::tmat4x4<T> rot ;
0046 glm::tmat4x4<T> iro ;
0047 glm::tmat4x4<T> tra ;
0048 glm::tmat4x4<T> itr ;
0049
0050 glm::tmat4x4<T> rot_itr ;
0051 glm::tmat4x4<T> tra_iro ;
0052 };
0053
0054 template<typename T>
0055 const T Tangential<T>::pi = glm::pi<T>() ;
0056
0057
0058 template<typename T>
0059 void Tangential<T>::CartesianToSpherical( glm::tvec3<T>& radius_theta_phi, const glm::tvec4<T>& xyzw )
0060 {
0061 const T x = xyzw.x ;
0062 const T y = xyzw.y ;
0063 const T z = xyzw.z ;
0064 const T radius = sqrt( x*x + y*y + z*z ) ;
0065 const T zero(0.) ;
0066
0067 const T theta = radius == zero ? zero : acos( z/radius );
0068 const T phi = atan2(y, x) ;
0069
0070 radius_theta_phi.x = radius ;
0071 radius_theta_phi.y = theta ;
0072 radius_theta_phi.z = phi ;
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 template<typename T>
0093 glm::tmat4x4<T> Tangential<T>::Rotation( T theta, T phi )
0094 {
0095 std::array<T, 16> _rot = {{
0096 sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta), 0. ,
0097 cos(theta)*cos(phi), cos(theta)*sin(phi), -sin(theta), 0. ,
0098 -sin(phi), cos(phi), 0., 0. ,
0099 0., 0., 0., 1.
0100 }} ;
0101 return glm::make_mat4x4<T>(_rot.data()) ;
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 template<typename T>
0121 glm::tmat4x4<T> Tangential<T>::IRotation( T theta, T phi )
0122 {
0123 std::array<T, 16> _iro = {{
0124 sin(theta)*cos(phi), cos(theta)*cos(phi), -sin(phi), 0. ,
0125 sin(theta)*sin(phi), cos(theta)*sin(phi), cos(phi), 0. ,
0126 cos(theta), -sin(theta), 0., 0. ,
0127 0., 0., 0., 1.
0128 }} ;
0129 return glm::make_mat4x4<T>(_iro.data()) ;
0130 }
0131
0132 template<typename T>
0133 glm::tmat4x4<T> Tangential<T>::Translation( T radius, T theta, T phi )
0134 {
0135 std::array<T, 16> _tra = {{
0136 1., 0., 0., 0. ,
0137 0., 1., 0., 0. ,
0138 0., 0., 1., 0. ,
0139 radius*sin(theta)*cos(phi), radius*sin(theta)*sin(phi), radius*cos(theta), 1.
0140 }} ;
0141 return glm::make_mat4x4<T>(_tra.data()) ;
0142 }
0143
0144 template<typename T>
0145 glm::tmat4x4<T> Tangential<T>::ITranslation( T radius, T theta, T phi )
0146 {
0147 std::array<T, 16> _itr = {{
0148 1., 0., 0., 0. ,
0149 0., 1., 0., 0. ,
0150 0., 0., 1., 0. ,
0151 -radius*sin(theta)*cos(phi), -radius*sin(theta)*sin(phi), -radius*cos(theta), 1.
0152 }} ;
0153 return glm::make_mat4x4<T>(_itr.data()) ;
0154 }
0155
0156
0157 template<typename T>
0158 Tangential<T>::Tangential(T radius, T theta, T phi )
0159 :
0160 rot(Rotation(pi*theta,pi*phi)),
0161 iro(IRotation(pi*theta,pi*phi)),
0162 tra(Translation(radius,pi*theta,pi*phi)),
0163 itr(ITranslation(radius,pi*theta,pi*phi)),
0164 rot_itr(rot * itr),
0165 tra_iro(tra * iro)
0166 {
0167 }
0168
0169
0170 template<typename T>
0171 void Tangential<T>::tangential_to_conventional( glm::tvec4<T>& xyzw , const glm::tvec4<T>& rtpw )
0172 {
0173
0174 xyzw = rot_itr * rtpw ;
0175 }
0176
0177 template<typename T>
0178 void Tangential<T>::conventional_to_tangential( glm::tvec4<T>& rtpw , const glm::tvec4<T>& xyzw )
0179 {
0180
0181 rtpw = tra_iro * xyzw ;
0182 }
0183
0184
0185 template<typename T>
0186 void Tangential<T>::dump() const
0187 {
0188 std::cout << " rot " << glm::to_string(rot) << std::endl ;
0189 std::cout << " iro " << glm::to_string(iro) << std::endl ;
0190 std::cout << " tra " << glm::to_string(tra) << std::endl ;
0191 std::cout << " itr " << glm::to_string(itr) << std::endl ;
0192 }
0193
0194 template<typename T>
0195 void Tangential<T>::GetEVector( std::vector<T>& vec, const char* ekey, const char* fallback )
0196 {
0197 const char* sval = getenv(ekey);
0198 std::stringstream ss(sval ? sval : fallback);
0199 std::string s ;
0200 while(getline(ss, s, ','))
0201 {
0202 T val(0) ;
0203 std::stringstream vv(s.c_str());
0204 vv >> val ;
0205 vec.push_back(val);
0206 }
0207 }
0208
0209 int main(int argc, char** argv)
0210 {
0211 std::vector<double> rtp ;
0212 Tangential<double>::GetEVector(rtp, "RTP", "20,0.25,0.0") ;
0213 for(unsigned i=0 ; i < rtp.size() ; i++) std::cout << std::setw(4) << i << " : " << rtp[i] << std::endl ;
0214 assert( rtp.size() == 3 );
0215 double radius = rtp[0] ;
0216 double theta = rtp[1] ;
0217 double phi = rtp[2] ;
0218
0219 Tangential<double> ta(radius, theta, phi );
0220 ta.dump();
0221
0222 glm::tvec4<double> rtpw(0., 0., 0., 1.) ;
0223 glm::tvec4<double> xyzw(0., 0., 0., 1.) ;
0224 glm::tvec4<double> rtpw2(0., 0., 0., 1.) ;
0225
0226 for(int t=-3 ; t <= 3 ; t++)
0227 for(int p=-3 ; p <= 3 ; p++)
0228 {
0229 rtpw.y = double(t) ;
0230 rtpw.z = double(p) ;
0231
0232 ta.tangential_to_conventional(xyzw, rtpw );
0233 ta.conventional_to_tangential(rtpw2, xyzw );
0234
0235 std::cout
0236 << "rtpw"
0237 << "(" << std::setw(10) << std::fixed << std::setprecision(4) << rtpw.x
0238 << " " << std::setw(10) << std::fixed << std::setprecision(4) << rtpw.y
0239 << " " << std::setw(10) << std::fixed << std::setprecision(4) << rtpw.z
0240 << " " << std::setw(10) << std::fixed << std::setprecision(4) << rtpw.w
0241 << ")"
0242 << " xyzw "
0243 << "(" << std::setw(10) << std::fixed << std::setprecision(4) << xyzw.x
0244 << " " << std::setw(10) << std::fixed << std::setprecision(4) << xyzw.y
0245 << " " << std::setw(10) << std::fixed << std::setprecision(4) << xyzw.z
0246 << " " << std::setw(10) << std::fixed << std::setprecision(4) << xyzw.w
0247 << ")"
0248 << "rtpw2"
0249 << "(" << std::setw(10) << std::fixed << std::setprecision(4) << rtpw2.x
0250 << " " << std::setw(10) << std::fixed << std::setprecision(4) << rtpw2.y
0251 << " " << std::setw(10) << std::fixed << std::setprecision(4) << rtpw2.z
0252 << " " << std::setw(10) << std::fixed << std::setprecision(4) << rtpw2.w
0253 << ")"
0254 << std::endl
0255 ;
0256 }
0257
0258 return 0 ;
0259 }