Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/lina/vec3 is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_vec3
0005 #define tools_vec3
0006 
0007 #include <cstddef> //size_t
0008 
0009 namespace tools {
0010 
0011 template <class T>
0012 class vec3 {
0013 public:
0014   typedef T elem_t;
0015   unsigned int dimension() const {return 3;}
0016 public:
0017   vec3(){
0018     m_data[0] = T();
0019     m_data[1] = T();
0020     m_data[2] = T();
0021   }
0022   vec3(const T a_vec[3]) {
0023     m_data[0] = a_vec[0];
0024     m_data[1] = a_vec[1];
0025     m_data[2] = a_vec[2];
0026   }
0027   vec3(const T& a0,const T& a1,const T& a2) {
0028     m_data[0] = a0;
0029     m_data[1] = a1;
0030     m_data[2] = a2;
0031   }
0032   virtual ~vec3() {
0033   }
0034 public:
0035   vec3(const vec3& a_from){
0036     m_data[0] = a_from.m_data[0];
0037     m_data[1] = a_from.m_data[1];
0038     m_data[2] = a_from.m_data[2];
0039   }
0040   vec3& operator=(const vec3& a_from) {
0041     m_data[0] = a_from.m_data[0];
0042     m_data[1] = a_from.m_data[1];
0043     m_data[2] = a_from.m_data[2];
0044     return *this;
0045   }
0046 public:
0047   const T& v0() const { return m_data[0];}
0048   const T& v1() const { return m_data[1];}
0049   const T& v2() const { return m_data[2];}
0050 
0051   void v0(const T& a_value) { m_data[0] = a_value;}
0052   void v1(const T& a_value) { m_data[1] = a_value;}
0053   void v2(const T& a_value) { m_data[2] = a_value;}
0054 
0055   const T& x() const {return m_data[0];}
0056   const T& y() const {return m_data[1];}
0057   const T& z() const {return m_data[2];}
0058 
0059   T& x() {return m_data[0];}
0060   T& y() {return m_data[1];}
0061   T& z() {return m_data[2];}
0062 
0063   void set_value(const T& a0,const T& a1,const T& a2) {
0064     m_data[0] = a0;
0065     m_data[1] = a1;
0066     m_data[2] = a2;
0067   }
0068   void set_value(const T aV[3]) {
0069     m_data[0] = aV[0];
0070     m_data[1] = aV[1];
0071     m_data[2] = aV[2];
0072   }
0073   void value(T& a0,T& a1,T& a2) const {
0074     a0 = m_data[0];
0075     a1 = m_data[1];
0076     a2 = m_data[2];
0077   }
0078 
0079   T length(T(*a_sqrt)(T)) const {
0080     return a_sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]+m_data[2]*m_data[2]);
0081   }
0082 
0083   T normalize(T(*a_sqrt)(T)) {
0084     T norme = length(a_sqrt);
0085     if(norme==T()) return T();
0086     divide(norme);
0087     return norme;
0088   }
0089 
0090   T dot(const vec3& aV) const {
0091     return (m_data[0] * aV.m_data[0] +
0092             m_data[1] * aV.m_data[1] +
0093             m_data[2] * aV.m_data[2]);
0094   }
0095 
0096   void cross(const vec3<T>& aV,vec3<T>& a_value) const {
0097     a_value.set_value(m_data[1] * aV.m_data[2] - m_data[2] * aV.m_data[1],
0098                       m_data[2] * aV.m_data[0] - m_data[0] * aV.m_data[2],
0099                       m_data[0] * aV.m_data[1] - m_data[1] * aV.m_data[0]);
0100   }
0101 
0102   bool equal(const vec3& aV) const {
0103     if(m_data[0]!=aV.m_data[0]) return false;
0104     if(m_data[1]!=aV.m_data[1]) return false;
0105     if(m_data[2]!=aV.m_data[2]) return false;
0106     return true;
0107   }
0108 
0109   template <class PREC>
0110   bool equal_prec(const vec3& a_v,PREC a_prec,PREC(*a_fabs)(const T&)) const {
0111     if(&a_v==this) return true;
0112     for(unsigned int index=0;index<3;index++) {
0113       T diff = m_data[index]-a_v.m_data[index];
0114       if(a_fabs(diff)>=a_prec) return false;
0115     }
0116     return true;
0117   }
0118 
0119   vec3<T> _cross(const vec3<T>& aV) const {
0120     //not effective.
0121     return vec3<T>(m_data[1] * aV.m_data[2] - m_data[2] * aV.m_data[1],
0122                    m_data[2] * aV.m_data[0] - m_data[0] * aV.m_data[2],
0123                    m_data[0] * aV.m_data[1] - m_data[1] * aV.m_data[0]);
0124   }
0125 
0126   bool divide(const T& a_T) {
0127     if(a_T==T()) return false;
0128     m_data[0] /= a_T;
0129     m_data[1] /= a_T;
0130     m_data[2] /= a_T;
0131     return true;
0132   }
0133 
0134   void multiply(const T& a_T) {
0135     m_data[0] *= a_T;
0136     m_data[1] *= a_T;
0137     m_data[2] *= a_T;
0138   }
0139 
0140   void add(const vec3& a_v) {
0141     m_data[0] += a_v.m_data[0];
0142     m_data[1] += a_v.m_data[1];
0143     m_data[2] += a_v.m_data[2];
0144   }
0145 
0146   void add(const T& a0,const T& a1,const T& a2) {
0147     m_data[0] += a0;
0148     m_data[1] += a1;
0149     m_data[2] += a2;
0150   }
0151 
0152   void subtract(const vec3& a_v) {
0153     m_data[0] -= a_v.m_data[0];
0154     m_data[1] -= a_v.m_data[1];
0155     m_data[2] -= a_v.m_data[2];
0156   }
0157 
0158   void subtract(const T& a0,const T& a1,const T& a2) {
0159     m_data[0] -= a0;
0160     m_data[1] -= a1;
0161     m_data[2] -= a2;
0162   }
0163 
0164   bool cos_angle(const vec3& a_v,T& a_cos,T(*a_sqrt)(T)) const {
0165     //WARNING : if ret false, a_cos is not set.
0166     T this_length = length(a_sqrt);
0167     if(this_length==T()) return false;
0168     T a_v_length = a_v.length(a_sqrt);
0169     if(a_v_length==T()) return false;
0170     a_cos = dot(a_v)/(this_length*a_v_length);
0171     return true;
0172   }
0173 
0174   bool theta_phi(T& a_theta,T& a_phi,T(*a_sqrt)(T),T(*a_atan2)(T,T)) const {
0175     //WARNING : if ret false, a_theta, a_phi are not set.
0176     if(length(a_sqrt)==T()) return false;
0177     a_phi = a_atan2(m_data[1],m_data[0]);
0178     T xy = a_sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]);
0179     a_theta = a_atan2(xy,m_data[2]);
0180     return true;
0181   }
0182 
0183 public: //operators
0184   T& operator[](size_t a_index) {
0185     //WARNING : no check on a_index.
0186     return m_data[a_index];
0187   }
0188   const T& operator[](size_t a_index) const {
0189     //WARNING : no check on a_index.
0190     return m_data[a_index];
0191   }
0192 
0193   vec3& operator*=(const T& a_v) {
0194     m_data[0] *= a_v;
0195     m_data[1] *= a_v;
0196     m_data[2] *= a_v;
0197     return *this;
0198   }
0199 
0200   vec3 operator+(const vec3& a_v) const {
0201     return vec3(m_data[0]+a_v.m_data[0],
0202                 m_data[1]+a_v.m_data[1],
0203                 m_data[2]+a_v.m_data[2]);
0204   }
0205 
0206   vec3 operator-(const vec3& a_v) const {
0207     return vec3(m_data[0]-a_v.m_data[0],
0208                 m_data[1]-a_v.m_data[1],
0209                 m_data[2]-a_v.m_data[2]);
0210   }
0211 
0212   vec3 operator*(const T& a_v) const {
0213     return vec3(m_data[0]*a_v,
0214                 m_data[1]*a_v,
0215                 m_data[2]*a_v);
0216   }
0217 
0218   vec3 operator/(const T& a_v) const {
0219     if(a_v==T()) return vec3();
0220     return vec3(m_data[0]/a_v,
0221                 m_data[1]/a_v,
0222                 m_data[2]/a_v);
0223   }
0224 
0225   bool operator==(const vec3& a_v) const {return equal(a_v);}
0226   bool operator!=(const vec3& a_v) const {return !operator==(a_v);}
0227 
0228 public: //for tools/sg/sf_vec
0229   typedef unsigned int size_type;
0230   size_type size() const {return 3;}
0231   const T* data() const {return m_data;}
0232   size_type data_size() const {return 3;} //for eqT.
0233 public: //for iv2sg
0234   const T* getValue() const {return m_data;}
0235   void setValue(const T& a0,const T& a1,const T& a2) {
0236     m_data[0] = a0;
0237     m_data[1] = a1;
0238     m_data[2] = a2;
0239   }
0240   void getValue(T& a0,T& a1,T& a2) const {
0241     a0 = m_data[0];
0242     a1 = m_data[1];
0243     a2 = m_data[2];
0244   }
0245   void setValue(const vec3& a_v) {
0246     m_data[0] = a_v.m_data[0];
0247     m_data[1] = a_v.m_data[1];
0248     m_data[2] = a_v.m_data[2];
0249   }
0250   void setValue(const T aV[3]) {
0251     m_data[0] = aV[0];
0252     m_data[1] = aV[1];
0253     m_data[2] = aV[2];
0254   }
0255 
0256   vec3& setValue(const vec3& a_bary,
0257                  const vec3& a_v0,const vec3& a_v1,const vec3& a_v2) {
0258     m_data[0] = a_bary[0]*a_v0[0]+a_bary[1]*a_v1[0]+a_bary[2]*a_v2[0];
0259     m_data[1] = a_bary[0]*a_v0[1]+a_bary[1]*a_v1[1]+a_bary[2]*a_v2[1];
0260     m_data[2] = a_bary[0]*a_v0[2]+a_bary[1]*a_v1[2]+a_bary[2]*a_v2[2];
0261     return *this;
0262   }
0263 
0264 public:
0265   static const vec3<T>& s_x() {static const vec3<T> s_v(1,0,0);return s_v;}
0266   static const vec3<T>& s_y() {static const vec3<T> s_v(0,1,0);return s_v;}
0267   static const vec3<T>& s_z() {static const vec3<T> s_v(0,0,1);return s_v;}
0268 protected:
0269   T m_data[3];
0270 
0271 private:static void check_instantiation() {vec3<float> v;}
0272 };
0273 
0274 //for sf, mf :
0275 template <class T>
0276 inline const T* get_data(const vec3<T>& a_v) {return a_v.data();}
0277 
0278 template <class T>
0279 inline void get_normal(const vec3<T>& a_p0,const vec3<T>& a_p1,const vec3<T>& a_p2,vec3<T>& a_nm,
0280                        vec3<T>& a_tmp_1,vec3<T>& a_tmp_2,T(*a_sqrt)(T)) {
0281   // Used to optimize sg::bin().
0282   //(a_p1-a_p0).cross(a_p2-a_p1,a_nm);
0283 
0284   a_tmp_1 = a_p1;
0285   a_tmp_1.subtract(a_p0);
0286 
0287   a_tmp_2 = a_p2;
0288   a_tmp_2.subtract(a_p1);
0289 
0290   a_tmp_1.cross(a_tmp_2,a_nm);
0291 
0292   a_nm.normalize(a_sqrt);
0293 }
0294 
0295 template <class VEC3>
0296 inline void direction(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2,VEC3& a_value) {
0297   // Orientation is computed by taking (p1 - p0) x (p2 - p0)
0298   VEC3 P = a_p1;
0299   P.subtract(a_p0);
0300   VEC3 P2 = a_p2;
0301   P2.subtract(a_p0);
0302   P.cross(P2,a_value);
0303 }
0304 
0305 template <class VEC3>
0306 inline void area(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2,typename VEC3::elem_t& a_value,
0307                  VEC3& a_tmp_1,VEC3& a_tmp_2,VEC3& a_tmp_3) {
0308   // area of the triangle (a_p0,a_p1,a_p2)
0309   typedef typename VEC3::elem_t T;
0310 
0311   a_tmp_1 = a_p1;
0312   a_tmp_1.subtract(a_p0);
0313 
0314   a_tmp_2 = a_p2;
0315   a_tmp_2.subtract(a_p1);
0316 
0317   a_tmp_1.cross(a_tmp_2,a_tmp_3);
0318 
0319   a_value = a_tmp_3.length()/T(2);
0320 }
0321 
0322 template <class VEC3>
0323 inline void area(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2,typename VEC3::elem_t& a_value) {
0324   VEC3 tmp1,tmp2,tmp3;
0325   area(a_p0,a_p1,a_p2,a_value,tmp1,tmp2,tmp3);
0326 }
0327 
0328 template <class T>
0329 inline void direction(const T& a_0_x,const T& a_0_y,const T& a_0_z,
0330                       const T& a_1_x,const T& a_1_y,const T& a_1_z,
0331                       const T& a_2_x,const T& a_2_y,const T& a_2_z,vec3<T>& a_value) {
0332   direction(vec3<T>(a_0_x,a_0_y,a_0_z),
0333             vec3<T>(a_1_x,a_1_y,a_1_z),
0334             vec3<T>(a_2_x,a_2_y,a_2_z),a_value);
0335 }
0336 
0337 }
0338 
0339 #include <ostream>
0340 
0341 namespace tools {
0342 
0343 // for sf_vec::dump().
0344 template <class T>
0345 inline std::ostream& operator<<(std::ostream& a_out,const vec3<T>& a_this){
0346   a_out << "x = " << a_this.v0()
0347         << ",y = " << a_this.v1()
0348         << ",z = " << a_this.v2();
0349   return a_out;
0350 }
0351 
0352 }
0353 
0354 #endif