00001 //# Euler.h: Vector of Euler rotation angles 00002 //# Copyright (C) 1995,1996,1997,1998,1999 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id$ 00027 00028 #ifndef CASA_EULER_H 00029 #define CASA_EULER_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/casa/Arrays/Vector.h> 00035 #include <casacore/casa/Quanta/Quantum.h> 00036 #include <utility> 00037 00038 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00039 00040 //# Forward Declarations 00041 00042 00043 // <summary> 00044 // Vector of Euler rotation angles 00045 // </summary> 00046 00047 // <use visibility=local> 00048 00049 // <reviewed reviewer="tcornwel" date="1996/02/15" tests="tMeasMath" demos=""> 00050 // </reviewed> 00051 00052 // <prerequisite> 00053 // <li> <linkto class=Vector>Vector</linkto> class 00054 // <li> <linkto class=Quantum>Quantum</linkto> class for units 00055 // <li> <linkto class=RotMatrix>RotMatrix</linkto> class for usage 00056 // </prerequisite> 00057 // 00058 // <etymology> 00059 // Euler angles describe the rotation of a coordinate system 00060 // </etymology> 00061 // 00062 // <synopsis> 00063 // The Euler class is a vector of three angles, together with a vector of 00064 // three signed integers. The angles describe the rotation around an axis of a 00065 // coordinate system, the integers the actual axis around which to rotate. 00066 // The integer can be 0 (do not use this angle) or 1,2,3 to indicate the 00067 // axis. 00068 // Given angles (a1,a2,a3) and axes (i1,i2,i3), the actual rotation matrix 00069 // constructed will be:<br> 00070 // R = R<sub>i3</sub>(a3).R<sub>i2</sub>(a2).R<sub>i1</sub>(a1) <br> 00071 // It has the following constructors: 00072 // <ul> 00073 // <li> Euler() creates a zero filled vector of length 3. Axes: (1,2,3) 00074 // <li> Euler(Euler) creates a copy 00075 // <li> Euler(Double, uInt, Double=0, uInt=0, Double=0, uInt=0) creates an 00076 // Euler with specified values 00077 // <li> Euler(Double, Double=0, Double=0) creates an Euler with (1,2,3) 00078 // <li> Euler(Quantity, uInt, Quantity=0, uInt=0, Quantity=0, uInt=0) creates 00079 // an Euler with specified values 00080 // <li> Euler(Quantity, Quantity=0, Quantity=0) creates an Euler with 00081 // interpretation of angle units in the Quantities 00082 // <li> Euler(<src>Quantum<Vector<Double> ></src>) creates a zero expanded 00083 // Euler from at most the first three elements of Quantity 00084 // vector; with (1,2,3) 00085 // <li> Euler(<src>Quantum<Vector<Double> >, Vector<uInt></src>) creates a 00086 // zero expanded Euler with given values 00087 // </ul> 00088 // It has a unary minus operator, which reverses the sign and order of the 00089 // three angles, and the order of the axes, to produce the Euler angles 00090 // for a rotation with opposite signs, so that <src>RotMatrix(-Euler)</src> 00091 // will generate the inverse rotation matrix as compared with 00092 // <src>RotMatrix(Euler)</src>.<br> 00093 // getAngle() functions return the Euler angles as a Quantum vector.<br> 00094 // Eulers have addition and subtraction (on the angles). Note that this 00095 // produces the correct angles for a combined rotation only if the 00096 // axes are identical.<br> 00097 // A (which) operator returns the indicated angle. Set/get functions 00098 // manipulate the axes. 00099 // </synopsis> 00100 // 00101 // <example> 00102 // <srcblock> 00103 // Quantity angle(25,"deg"); // 25 degrees 00104 // Euler eul(angle.get().getValue(),2); // rotate over axis 2 (radians) 00105 // RotMatrix rot(eul); // generates rotation matrix 00106 // </srcblock> 00107 // </example> 00108 // 00109 // <motivation> 00110 // To use generated precession and nutation results 00111 // </motivation> 00112 // 00113 // <todo asof="1995/09/04"> 00114 // </todo> 00115 00116 class Euler 00117 { 00118 public: 00119 //# Friends 00120 // Output Euler angles 00121 friend ostream &operator<<(ostream &os, const Euler &eul); 00122 00123 //# Constructors 00124 // Default constructor generates zero filled Double vector of length 3, with 00125 // (1,2,3) axes 00126 Euler(); 00127 // Copy constructor 00128 Euler(const Euler &other); 00129 // Copy assignment 00130 Euler &operator=(const Euler &other); 00131 // Constructs an Euler with specified angles and (1,2,3) axes 00132 Euler(Double in0, Double in1 = 0, Double in2 = 0); 00133 // Constructs an Euler with specified angles and axes 00134 Euler(Double in0, uInt ax0, Double in1 = 0, uInt ax1=0, Double in2 = 0, 00135 uInt ax2=0); 00136 // <thrown> 00137 // <li> AipsError if non-angle units used 00138 // </thrown> 00139 // Constructs an Euler from specified angle quantities 00140 // <group> 00141 Euler(const Quantity &in0); 00142 Euler(const Quantity &in0, const Quantity &in1); 00143 Euler(const Quantity &in0, const Quantity &in1, 00144 const Quantity &in2); 00145 Euler(const Quantity &in0, uInt ax0); 00146 Euler(const Quantity &in0, uInt ax0, const Quantity &in1, uInt ax1=0); 00147 Euler(const Quantity &in0, uInt ax0, const Quantity &in1, uInt ax1, 00148 const Quantity &in2, uInt ax2=0); 00149 // Constructs an Euler (zero filled) from elements of Quantity vector 00150 // <group> 00151 Euler(const Quantum<Vector<Double> > &in); 00152 Euler(const Quantum<Vector<Double> > &in, const Vector<uInt> &ax); 00153 // </group> 00154 // </group> 00155 00156 // Destructor 00157 ~Euler(); 00158 00159 //# Operators 00160 // The unary minus reverses the sign and order of the Euler angles 00161 Euler operator-() const; 00162 // Addition and subtraction 00163 // <group> 00164 Euler &operator+=(const Euler &right); 00165 Euler operator+(const Euler &right) const; 00166 Euler &operator-=(const Euler &right); 00167 Euler operator-(const Euler &right) const; 00168 // </group> 00169 // Return the which' angle 00170 // <group> 00171 Double &operator()(uInt which); 00172 const Double &operator()(uInt which) const; 00173 // </group> 00174 00175 //# General Member Functions 00176 // with the optional conversion units. 00177 // <group> 00178 Quantum<Vector<Double> > getAngle() const; 00179 Quantum<Vector<Double> > getAngle(const Unit &unit) const; 00180 // </group> 00181 00182 // Set an axis 00183 void set(uInt which, uInt ax); 00184 00185 // Set all axes 00186 void set(uInt ax0, uInt ax1, uInt ax2); 00187 00188 // Get an axis 00189 Int get(uInt which) const; 00190 00191 private: 00192 //# Data 00193 typedef std::pair<Vector<Double> *, Vector<Int> *> DataArrays; 00194 // data container 00195 DataArrays data; 00196 // vector with 3 Euler angles (data.first) 00197 Vector<Double> & euler; 00198 // Axes (data.second) 00199 Vector<Int> & axes; 00200 00201 //# Private Member Functions 00202 // The makeRad functions check and convert the input Quantities to radians 00203 // <group> 00204 static Double makeRad(const Quantity &in); 00205 static Vector<Double> makeRad(const Quantum<Vector<Double> > &in); 00206 // </group> 00207 DataArrays get_arrays(); 00208 void return_arrays(DataArrays array); 00209 #if defined(AIPS_CXX11) && !defined(__APPLE__) 00210 static thread_local DataArrays arrays[50]; 00211 static thread_local size_t available; 00212 #endif 00213 }; 00214 00215 00216 } //# NAMESPACE CASACORE - END 00217 00218 #endif 00219 00220