Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/lina/qrot

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/lina/qrot (Version 11.3.0) and /externals/g4tools/include/tools/lina/qrot (Version 8.3)


  1 // Copyright (C) 2010, Guy Barrand. All rights    
  2 // See the file tools.license for terms.          
  3                                                   
  4 #ifndef tools_qrot                                
  5 #define tools_qrot                                
  6                                                   
  7 // rotation done with quaternion.                 
  8                                                   
  9 namespace tools {                                 
 10                                                   
 11 template <class VEC3,class VEC4>                  
 12 class qrot {                                      
 13 protected:                                        
 14 //typedef typename VEC3::elem_t T3;               
 15   typedef typename VEC4::elem_t T; //we assume    
 16 public:                                           
 17   qrot()                                          
 18   :m_quat(0,0,0,1)   //zero rotation around th    
 19   {}                                              
 20   qrot(const VEC3& a_axis,T a_radians,T(*a_sin    
 21     if(!set_value(a_axis,a_radians,a_sin,a_cos    
 22   }                                               
 23   qrot(const VEC3& a_from,const VEC3& a_to,T(*    
 24   virtual ~qrot(){}                               
 25 public:                                           
 26   qrot(const qrot& a_from)                        
 27   :m_quat(a_from.m_quat)                          
 28   {}                                              
 29   qrot& operator=(const qrot& a_from){            
 30     m_quat = a_from.m_quat;                       
 31     return *this;                                 
 32   }                                               
 33 protected:                                        
 34   qrot(T a_q0,T a_q1,T a_q2,T a_q3)               
 35   :m_quat(a_q0,a_q1,a_q2,a_q3)                    
 36   {                                               
 37     if(!m_quat.normalize()) {} //FIXME throw      
 38   }                                               
 39                                                   
 40 public:                                           
 41   qrot& operator*=(const qrot& a_q) {             
 42     //Multiplies the quaternions.                 
 43     //Note that order is important when combin    
 44     //multiplication operator.                    
 45     // Formula from <http://www.lboro.ac.uk/de    
 46                                                   
 47     T tx = m_quat.v0();                           
 48     T ty = m_quat.v1();                           
 49     T tz = m_quat.v2();                           
 50     T tw = m_quat.v3();                           
 51                                                   
 52     T qx = a_q.m_quat.v0();                       
 53     T qy = a_q.m_quat.v1();                       
 54     T qz = a_q.m_quat.v2();                       
 55     T qw = a_q.m_quat.v3();                       
 56                                                   
 57     m_quat.set_value(qw*tx + qx*tw + qy*tz - q    
 58                      qw*ty - qx*tz + qy*tw + q    
 59                      qw*tz + qx*ty - qy*tx + q    
 60                      qw*tw - qx*tx - qy*ty - q    
 61     m_quat.normalize();                           
 62     return *this;                                 
 63   }                                               
 64                                                   
 65   bool operator==(const qrot& a_r) const {        
 66     return m_quat.equal(a_r.m_quat);              
 67   }                                               
 68   bool operator!=(const qrot& a_r) const {        
 69     return !operator==(a_r);                      
 70   }                                               
 71   qrot operator*(const qrot& a_r) const {         
 72     qrot tmp(*this);                              
 73     tmp *= a_r;                                   
 74     return tmp;                                   
 75   }                                               
 76                                                   
 77   bool invert(){                                  
 78     T length = m_quat.length();                   
 79     if(length==T()) return false;                 
 80                                                   
 81     // Optimize by doing 1 div and 4 muls inst    
 82     T inv = one() / length;                       
 83                                                   
 84     m_quat.set_value(-m_quat.v0() * inv,          
 85                      -m_quat.v1() * inv,          
 86                      -m_quat.v2() * inv,          
 87                       m_quat.v3() * inv);         
 88                                                   
 89     return true;                                  
 90   }                                               
 91                                                   
 92   bool inverse(qrot& a_r) const {                 
 93     //Non-destructively inverses the rotation     
 94     T length = m_quat.length();                   
 95     if(length==T()) return false;                 
 96                                                   
 97     // Optimize by doing 1 div and 4 muls inst    
 98     T inv = one() / length;                       
 99                                                   
100     a_r.m_quat.set_value(-m_quat.v0() * inv,      
101                          -m_quat.v1() * inv,      
102                          -m_quat.v2() * inv,      
103                           m_quat.v3() * inv);     
104                                                   
105     return true;                                  
106   }                                               
107                                                   
108                                                   
109   bool set_value(const VEC3& a_axis,T a_radian    
110     // Reset rotation with the given axis-of-r    
111     // Make sure axis is not the null vector w    
112     // From <http://www.automation.hut.fi/~jar    
113     if(a_axis.length()==T()) return false;        
114     m_quat.v3(a_cos(a_radians/2));                
115     T sineval = a_sin(a_radians/2);               
116     VEC3 a = a_axis;                              
117     a.normalize();                                
118     m_quat.v0(a.v0() * sineval);                  
119     m_quat.v1(a.v1() * sineval);                  
120     m_quat.v2(a.v2() * sineval);                  
121     return true;                                  
122   }                                               
123                                                   
124   bool set_value(const VEC3& a_from,const VEC3    
125     // code taken from coin3d/SbRotation.         
126     //NOTE : coin3d/SbMatrix logic is transpos    
127                                                   
128     VEC3 from(a_from);                            
129     if(from.normalize()==T()) return false;       
130     VEC3 to(a_to);                                
131     if(to.normalize()==T()) return false;         
132                                                   
133     T dot = from.dot(to);                         
134     VEC3 crossvec;from.cross(to,crossvec);        
135     T crosslen = crossvec.normalize();            
136                                                   
137     if(crosslen == T()) { // Parallel vectors     
138       // Check if they are pointing in the sam    
139       if (dot > T()) {                            
140         m_quat.set_value(0,0,0,1);                
141       } else {                                    
142         // Ok, so they are parallel and pointi    
143         // of each other.                         
144         // Try crossing with x axis.              
145         VEC3 t;from.cross(VEC3(1,0,0),t);         
146         // If not ok, cross with y axis.          
147         if(t.normalize() == T()) {                
148           from.cross(VEC3(0,1,0),t);              
149           t.normalize();                          
150         }                                         
151         m_quat.set_value(t[0],t[1],t[2],0);       
152       }                                           
153     } else { // Vectors are not parallel          
154       // The fabs() wrapping is to avoid probl    
155       // a tiny wee bit, which can lead to sqr    
156       crossvec *= (T)a_sqrt(half() * a_fabs(on    
157       // The fabs() wrapping is to avoid probl    
158       // a tiny wee bit, which can lead to sqr    
159       m_quat.set_value(crossvec[0], crossvec[1    
160     }                                             
161                                                   
162     return true;                                  
163   }                                               
164                                                   
165                                                   
166   bool value(VEC3& a_axis,T& a_radians,T(*a_si    
167     //WARNING : can fail.                         
168     if( (m_quat.v3()<minus_one()) || (m_quat.v    
169       a_axis.set_value(0,0,1);                    
170       a_radians = 0;                              
171       return false;                               
172     }                                             
173                                                   
174     a_radians = a_acos(m_quat.v3()) * 2; //in     
175     T sineval = a_sin(a_radians/2);               
176                                                   
177     if(sineval==T()) { //a_radian = 0 or 2*pi.    
178       a_axis.set_value(0,0,1);                    
179       a_radians = 0;                              
180       return false;                               
181     }                                             
182     a_axis.set_value(m_quat.v0()/sineval,         
183                      m_quat.v1()/sineval,         
184                      m_quat.v2()/sineval);        
185     return true;                                  
186   }                                               
187                                                   
188   template <class MAT4>                           
189   void set_value(const MAT4& a_m,T(*a_sqrt)(T)    
190     // See tests/qrot.icc.                        
191     // code taken from coin3d/SbRotation.         
192                                                   
193     //Set the rotation from the components of     
194                                                   
195     T scalerow = a_m.v00() + a_m.v11() + a_m.v    
196     if (scalerow > T()) {                         
197       T _s = a_sqrt(scalerow + a_m.v33());        
198       m_quat.v3(_s * half());                     
199       _s = half() / _s;                           
200                                                   
201       m_quat.v0((a_m.v21() - a_m.v12()) * _s);    
202       m_quat.v1((a_m.v02() - a_m.v20()) * _s);    
203       m_quat.v2((a_m.v10() - a_m.v01()) * _s);    
204     } else {                                      
205       unsigned int i = 0;                         
206       if (a_m.v11() > a_m.v00()) i = 1;           
207       if (a_m.v22() > a_m.value(i,i)) i = 2;      
208                                                   
209       unsigned int j = (i+1)%3;                   
210       unsigned int k = (j+1)%3;                   
211                                                   
212       T _s = a_sqrt((a_m.value(i,i) - (a_m.val    
213                                                   
214       m_quat.set_value(i,_s * half());            
215       _s = half() / _s;                           
216                                                   
217       m_quat.v3((a_m.value(k,j) - a_m.value(j,    
218       m_quat.set_value(j,(a_m.value(j,i) + a_m    
219       m_quat.set_value(k,(a_m.value(k,i) + a_m    
220     }                                             
221                                                   
222     if (a_m.v33()!=one()) {                       
223       m_quat.multiply(one()/a_sqrt(a_m.v33()))    
224     }                                             
225   }                                               
226                                                   
227   template <class MAT4>                           
228   void value(MAT4& a_m) const {                   
229     //Return this rotation in the form of a ma    
230     //NOTE : in coin3d/SbRotation, it looks as    
231                                                   
232     const T x = m_quat.v0();                      
233     const T y = m_quat.v1();                      
234     const T z = m_quat.v2();                      
235     const T w = m_quat.v3();                      
236     // q = w + x * i + y * j + z * k              
237                                                   
238     // first row :                                
239     a_m.v00(w*w + x*x - y*y - z*z);               
240     a_m.v01(2*x*y - 2*w*z);                       
241     a_m.v02(2*x*z + 2*w*y);                       
242     a_m.v03(0);                                   
243                                                   
244     // second row :                               
245     a_m.v10(2*x*y + 2*w*z);                       
246     a_m.v11(w*w - x*x + y*y - z*z);               
247     a_m.v12(2*y*z - 2*w*x);                       
248     a_m.v13(0);                                   
249                                                   
250     // third row :                                
251     a_m.v20(2*x*z - 2*w*y);                       
252     a_m.v21(2*y*z + 2*w*x);                       
253     a_m.v22(w*w - x*x - y*y + z*z);               
254     a_m.v23(0);                                   
255                                                   
256     // fourth row :                               
257     a_m.v30(0);                                   
258     a_m.v31(0);                                   
259     a_m.v32(0);                                   
260     a_m.v33(w*w + x*x + y*y + z*z);               
261   }                                               
262                                                   
263   template <class MAT3>                           
264   T value_3(MAT3& a_m) const {                    
265     //Return this rotation in the form of a 3D    
266     //NOTE : in coin3d/SbRotation, it looks as    
267                                                   
268     const T x = m_quat.v0();                      
269     const T y = m_quat.v1();                      
270     const T z = m_quat.v2();                      
271     const T w = m_quat.v3();                      
272     // q = w + x * i + y * j + z * k              
273                                                   
274     // first row :                                
275     a_m.v00(w*w + x*x - y*y - z*z);               
276     a_m.v01(2*x*y - 2*w*z);                       
277     a_m.v02(2*x*z + 2*w*y);                       
278                                                   
279     // second row :                               
280     a_m.v10(2*x*y + 2*w*z);                       
281     a_m.v11(w*w - x*x + y*y - z*z);               
282     a_m.v12(2*y*z - 2*w*x);                       
283                                                   
284     // third row :                                
285     a_m.v20(2*x*z - 2*w*y);                       
286     a_m.v21(2*y*z + 2*w*x);                       
287     a_m.v22(w*w - x*x - y*y + z*z);               
288                                                   
289     // fourth row :                               
290     //a_m.v30(0);                                 
291     //a_m.v31(0);                                 
292     //a_m.v32(0);                                 
293     //a_m.v33(w*w + x*x + y*y + z*z);             
294     return w*w + x*x + y*y + z*z;  //should be    
295   }                                               
296                                                   
297   void mul_vec(const VEC3& a_in,VEC3& a_out) c    
298     const T x = m_quat.v0();                      
299     const T y = m_quat.v1();                      
300     const T z = m_quat.v2();                      
301     const T w = m_quat.v3();                      
302                                                   
303     // first row :                                
304     T v0 =     (w*w + x*x - y*y - z*z) * a_in.    
305               +        (2*x*y - 2*w*z) * a_in.    
306               +        (2*x*z + 2*w*y) * a_in.    
307                                                   
308     T v1 =             (2*x*y + 2*w*z) * a_in.    
309               +(w*w - x*x + y*y - z*z) * a_in.    
310               +        (2*y*z - 2*w*x) * a_in.    
311                                                   
312     T v2 =             (2*x*z - 2*w*y) * a_in.    
313               +        (2*y*z + 2*w*x) * a_in.    
314               +(w*w - x*x - y*y + z*z) * a_in.    
315                                                   
316     a_out.set_value(v0,v1,v2);                    
317   }                                               
318                                                   
319   void mul_vec(VEC3& a_v) const {                 
320     const T x = m_quat.v0();                      
321     const T y = m_quat.v1();                      
322     const T z = m_quat.v2();                      
323     const T w = m_quat.v3();                      
324                                                   
325     // first row :                                
326     T v0 =     (w*w + x*x - y*y - z*z) * a_v.v    
327               +        (2*x*y - 2*w*z) * a_v.v    
328               +        (2*x*z + 2*w*y) * a_v.v    
329                                                   
330     T v1 =             (2*x*y + 2*w*z) * a_v.v    
331               +(w*w - x*x + y*y - z*z) * a_v.v    
332               +        (2*y*z - 2*w*x) * a_v.v    
333                                                   
334     T v2 =             (2*x*z - 2*w*y) * a_v.v    
335               +        (2*y*z + 2*w*x) * a_v.v    
336               +(w*w - x*x - y*y + z*z) * a_v.v    
337                                                   
338     a_v.set_value(v0,v1,v2);                      
339   }                                               
340                                                   
341   void mul_3(T& a_x,T& a_y,T& a_z) const {        
342     const T x = m_quat.v0();                      
343     const T y = m_quat.v1();                      
344     const T z = m_quat.v2();                      
345     const T w = m_quat.v3();                      
346                                                   
347     // first row :                                
348     T v0 =     (w*w + x*x - y*y - z*z) * a_x      
349               +        (2*x*y - 2*w*z) * a_y      
350               +        (2*x*z + 2*w*y) * a_z;     
351                                                   
352     T v1 =             (2*x*y + 2*w*z) * a_x      
353               +(w*w - x*x + y*y - z*z) * a_y      
354               +        (2*y*z - 2*w*x) * a_z;     
355                                                   
356     T v2 =             (2*x*z - 2*w*y) * a_x      
357               +        (2*y*z + 2*w*x) * a_y      
358               +(w*w - x*x - y*y + z*z) * a_z;     
359                                                   
360     a_x = v0;                                     
361     a_y = v1;                                     
362     a_z = v2;                                     
363   }                                               
364                                                   
365 public: //for io::streamer                        
366   const VEC4& quat() const {return m_quat;}       
367   VEC4& quat() {return m_quat;}                   
368                                                   
369 protected:                                        
370   static T one() {return T(1);}                   
371   static T minus_one() {return T(-1);}            
372   static T half() {return T(0.5);}                
373                                                   
374 protected:                                        
375   VEC4 m_quat;                                    
376                                                   
377 public:                                           
378   //NOTE : don't handle a static object becaus    
379   //static const qrot<double>& identity() {       
380   //  static const qrot<double> s_v(0,0,0,1);     
381   //  return s_v;                                 
382   //}                                             
383                                                   
384 //private:static void check_instantiation() {q    
385 };                                                
386                                                   
387 }                                                 
388                                                   
389 #endif