LevelS C++ support library  3.83
rotmatrix.cc
1 /*
2  * This file is part of libcxxsupport.
3  *
4  * libcxxsupport is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * libcxxsupport is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with libcxxsupport; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /*
20  * libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
21  * and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
22  * (DLR).
23  */
24 
25 /*
26  * Class for rotation transforms in 3D space
27  *
28  * Copyright (C) 2003-2011 Max-Planck-Society
29  * Author: Martin Reinecke
30  */
31 
32 #include <algorithm>
33 #include "rotmatrix.h"
34 #include "lsconstants.h"
35 
36 using namespace std;
37 
38 rotmatrix::rotmatrix (const vec3 &a, const vec3 &b, const vec3 &c)
39  {
40  entry[0][0]=a.x; entry[0][1]=b.x; entry[0][2]=c.x;
41  entry[1][0]=a.y; entry[1][1]=b.y; entry[1][2]=c.y;
42  entry[2][0]=a.z; entry[2][1]=b.z; entry[2][2]=c.z;
43  }
44 
46  {
47  entry[0][0] = entry[1][1] = entry[2][2] = 1.;
48  entry[0][1] = entry[1][0] = entry[0][2] =
49  entry[2][0] = entry[1][2] = entry[2][1] = 0.;
50  }
51 
53  {
54  for (int m=0; m<3; ++m)
55  entry[m][0] = entry[m][1] = entry[m][2] = 0;
56  }
57 
59  {
60  swap(entry[0][1], entry[1][0]);
61  swap(entry[0][2], entry[2][0]);
62  swap(entry[1][2], entry[2][1]);
63  }
64 
65 void rotmatrix::toAxisAngle (vec3 &axis, double &angle) const
66  {
67  double c2 = entry[0][0] + entry[1][1] + entry[2][2] - 1;
68  axis.x = entry[2][1] - entry[1][2];
69  axis.y = entry[0][2] - entry[2][0];
70  axis.z = entry[1][0] - entry[0][1];
71 
72  double s2 = axis.Length();
73 
74  if (s2>0)
75  {
76  angle = atan2(s2,c2);
77  axis *= 1/s2;
78  return;
79  }
80 
81  if (c2>=2) // angle is 0
82  {
83  axis = vec3(1,0,0);
84  angle = 0;
85  return;
86  }
87 
88  angle = pi;
89 
90  int choice = 0; // assume entry[0][0] is the largest
91  if ((entry[1][1]>entry[0][0]) && (entry[1][1]>entry[2][2])) choice=1;
92  if ((entry[2][2]>entry[0][0]) && (entry[2][2]>entry[1][1])) choice=2;
93 
94  if (choice==0)
95  {
96  axis.x = 0.5*sqrt(entry[0][0]-entry[1][1]-entry[2][2]+1);
97  double half_inv = 0.5/axis.x;
98  axis.y = half_inv*entry[0][1];
99  axis.z = half_inv*entry[0][2];
100  return;
101  }
102  if (choice==1)
103  {
104  axis.y = 0.5*sqrt(entry[1][1]-entry[0][0]-entry[2][2]+1);
105  double half_inv = 0.5/axis.y;
106  axis.x = half_inv*entry[0][1];
107  axis.z = half_inv*entry[1][2];
108  return;
109  }
110 
111  axis.z = 0.5*sqrt(entry[2][2]-entry[0][0]-entry[1][1]+1);
112  double half_inv = 0.5/axis.z;
113  axis.x = half_inv*entry[0][2];
114  axis.y = half_inv*entry[1][2];
115  }
116 
117 void rotmatrix::Make_Axis_Rotation_Transform (const vec3 &axis, double angle)
118  {
119  double sa=sin(angle), ca=cos(angle);
120  double ica=1-ca;
121  entry[0][0] = axis.x*axis.x*ica + ca;
122  entry[1][1] = axis.y*axis.y*ica + ca;
123  entry[2][2] = axis.z*axis.z*ica + ca;
124  double t1 = axis.x*axis.y*ica, t2 = axis.z*sa;
125  entry[1][0] = t1 + t2;
126  entry[0][1] = t1 - t2;
127  t1 = axis.x*axis.z*ica; t2 = axis.y*sa;
128  entry[2][0] = t1 - t2;
129  entry[0][2] = t1 + t2;
130  t1 = axis.y*axis.z*ica; t2 = axis.x*sa;
131  entry[1][2] = t1 - t2;
132  entry[2][1] = t1 + t2;
133  }
134 
136  (double alpha, double beta, double gamma)
137  {
138  double ca=cos(alpha), cb=cos(beta), cg=cos(gamma);
139  double sa=sin(alpha), sb=sin(beta), sg=sin(gamma);
140 
141  entry[0][0]= ca*cb*cg-sa*sg; entry[0][1]=-ca*cb*sg-sa*cg; entry[0][2]= ca*sb;
142  entry[1][0]= sa*cb*cg+ca*sg; entry[1][1]=-sa*cb*sg+ca*cg; entry[1][2]= sa*sb;
143  entry[2][0]=-sb*cg; entry[2][1]= sb*sg; entry[2][2]= cb;
144  }
145 
147  (double &alpha, double &beta, double &gamma) const
148  {
149  double cb = entry[2][2];
150  double sb = sqrt(entry[0][2]*entry[0][2] + entry[1][2]*entry[1][2]);
151  beta=atan2(sb,cb);
152  if (abs(sb)<=1e-6)
153  {
154  alpha=0;
155  if (cb>0)
156  gamma=atan2(entry[1][0],entry[0][0]);
157  else
158  gamma=atan2(entry[0][1],-entry[0][0]);
159  }
160  else
161  {
162  alpha=atan2(entry[1][2],entry[0][2]);
163  gamma=atan2(entry[2][1],-entry[2][0]);
164  }
165  }
166 
167 rotmatrix operator* (const rotmatrix &a, const rotmatrix &b)
168  {
169  rotmatrix res;
170  for (int i=0; i<3; ++i)
171  for (int j=0; j<3; ++j)
172  res.entry[i][j] = a.entry[i][0] * b.entry[0][j]
173  + a.entry[i][1] * b.entry[1][j]
174  + a.entry[i][2] * b.entry[2][j];
175  return res;
176  }
177 
178 void matmult (const rotmatrix &a, const rotmatrix &b, rotmatrix &res)
179  {
180  for (int i=0; i<3; ++i)
181  for (int j=0; j<3; ++j)
182  res.entry[i][j] = a.entry[i][0] * b.entry[0][j]
183  + a.entry[i][1] * b.entry[1][j]
184  + a.entry[i][2] * b.entry[2][j];
185  }
186 
187 void TransposeTimes (const rotmatrix &a, const rotmatrix &b, rotmatrix &res)
188  {
189  for (int i=0; i<3; ++i)
190  for (int j=0; j<3; ++j)
191  res.entry[i][j] = a.entry[0][i] * b.entry[0][j]
192  + a.entry[1][i] * b.entry[1][j]
193  + a.entry[2][i] * b.entry[2][j];
194  }
195 
196 ostream &operator<< (ostream &os, const rotmatrix &mat)
197  {
198  for (int i=0;i<3;++i)
199  os << mat.entry[i][0] << ' '
200  << mat.entry[i][1] << ' '
201  << mat.entry[i][2] << endl;
202  return os;
203  }
T y
Definition: vec3.h:46
T z
Definition: vec3.h:46
void SetToIdentity()
Definition: rotmatrix.cc:45
T x
Definition: vec3.h:46
vec3_t< float64 > vec3
Definition: vec3.h:143
void Extract_CPAC_Euler_Angles(double &alpha, double &beta, double &gamma) const
Definition: rotmatrix.cc:147
T Length() const
Definition: vec3.h:87
Definition: vec3.h:43
void Make_CPAC_Euler_Matrix(double alpha, double beta, double gamma)
Definition: rotmatrix.cc:136
void toAxisAngle(vec3 &axis, double &angle) const
Definition: rotmatrix.cc:65
void Transpose()
Definition: rotmatrix.cc:58
void Make_Axis_Rotation_Transform(const vec3 &axis, double angle)
Definition: rotmatrix.cc:117
void SetToZero()
Definition: rotmatrix.cc:52

Generated on Wed Nov 13 2024 12:18:16 for LevelS C++ support library