From 51a7727fc3f1292f64b587ae8592cd0862d866ee Mon Sep 17 00:00:00 2001
From: Laurent Chapon <laurent.chapon@stfc.ac.uk>
Date: Wed, 7 Nov 2007 10:23:35 +0000
Subject: [PATCH] re #35 Adding the Qaut.cpp again

---
 Code/Mantid/Geometry/src/Quat.cpp | 339 ++++++++++++++++++++++++++++++
 1 file changed, 339 insertions(+)
 create mode 100644 Code/Mantid/Geometry/src/Quat.cpp

diff --git a/Code/Mantid/Geometry/src/Quat.cpp b/Code/Mantid/Geometry/src/Quat.cpp
new file mode 100644
index 00000000000..0fc2741620f
--- /dev/null
+++ b/Code/Mantid/Geometry/src/Quat.cpp
@@ -0,0 +1,339 @@
+#include "Quat.h" 
+#include "V3D.h"
+#include <cmath>
+#include <boost/test/floating_point_comparison.hpp>
+#include <stdexcept> 
+
+namespace Mantid
+{
+namespace Geometry
+{
+
+// Use boost float comparison 	
+boost::test_tools::close_at_tolerance<double> quat_tol(boost::test_tools::percent_tolerance(1e-6));
+
+
+Quat::Quat():w(1),a(0),b(0),c(0)
+/*! Null Constructor
+ * Initialize the quaternion with the identity q=1.0+0i+0j+0k;
+ */
+{
+}
+Quat::Quat(const double _w,const double _a, const double _b, const double _c):w(_w),a(_a),b(_b),c(_c)
+//! Constructor with values
+{
+}
+ 
+Quat::Quat(const Quat& _q)
+//! Copy constructor
+{
+	w=_q.w;
+	a=_q.a;
+	b=_q.b;
+	c=_q.c;
+}
+ 
+Quat::Quat(const double _deg,const V3D& _axis)
+/*! Constructor from an angle and axis.
+ * \param _deg :: angle of rotation
+ * \param _axis :: axis to rotate about
+ * 
+ * This construct a  quaternion to represent a rotation
+ * of an angle _deg around the _axis. The _axis does not need to be a unit vector
+ * */
+{
+	setAngleAxis(_deg,_axis);
+}
+Quat& Quat::operator=(const Quat& q)
+{
+	w=q.w;
+	a=q.a;
+	b=q.b;
+	c=q.c;
+	return *this;
+}
+void Quat::set(const double ww, const double aa, const double bb, const double cc)
+{
+	w=ww;
+	a=aa;
+	b=bb;
+	c=cc;
+	return;
+}
+void Quat::setAngleAxis(const double _deg, const V3D& _axis)
+/*! Constructor from an angle and axis.
+ * \param _deg :: angle of rotation
+ * \param _axis :: axis to rotate about
+ * 
+ * This construct a  quaternion to represent a rotation
+ * of an angle _deg around the _axis. The _axis does not need to be a unit vector
+ * */
+{
+	double deg2rad=M_PI/180.0;
+	w=cos(0.5*_deg*deg2rad);
+	double s=sin(0.5*_deg*deg2rad);
+	V3D temp(_axis);
+	temp.normalize();
+	a=s*temp[0];
+	b=s*temp[1];
+	c=s*temp[2];	
+	return;
+}
+void Quat::operator()(const double ww, const double aa, const double bb, const double cc)
+{
+	this->set(ww,aa,bb,cc);
+}
+void Quat::operator()(const double angle, const V3D& axis)
+{
+	this->setAngleAxis(angle,axis);
+} 
+Quat::~Quat()
+//! Destructor
+{}
+
+void Quat::init() 
+/*! Re-initialise a quaternion to identity.
+ */
+{
+	w=1.0;
+	a=b=c=0.0;
+	return;
+}
+
+Quat Quat::operator+(const Quat& _q) const
+/*! Quaternion addition operator
+ * \param _q :: the quaternion to add
+ * \return *this+_q
+ */
+{
+	return Quat(w+_q.w,a+_q.a,b+_q.b,c+_q.c);
+}
+ 
+Quat& Quat::operator+=(const Quat& _q)
+/*! Quaternion self-addition operator
+ * \param _q :: the quaternion to add
+ * \return *this+=_q
+ */
+{
+	w+=_q.w;a+=_q.a;b+=_q.b;c+=_q.c;
+	return *this;
+}
+ 
+Quat Quat::operator-(const Quat& _q) const
+/*! Quaternion subtraction operator
+ * \param _q :: the quaternion to add
+ * \return *this-_q
+ */
+
+{
+	return Quat(w-_q.w,a-_q.a,b-_q.b,c-_q.c);
+}
+ 
+Quat& Quat::operator-=(const Quat& _q)
+/*! Quaternion self-substraction operator
+ * \param _q :: the quaternion to add
+ * \return *this-=_q
+ */
+{
+	w-=_q.w;
+	a-=_q.a;
+	b-=_q.b;
+	c-=_q.c;
+	return *this;
+}
+ 
+Quat Quat::operator*(const Quat& _q) const
+/*! Quaternion multiplication operator
+ * \param _q :: the quaternion to multiply
+ * \return *this*_q
+ * 
+ *  Quaternion multiplication is non commutative
+ *  in the same way multiplication of rotation matrices 
+ *  isn't.
+ */
+{
+	double w1,a1,b1,c1;
+	w1=w*_q.w-a*_q.a-b*_q.b-c*_q.c;
+	a1=w*_q.a+_q.w*a+b*_q.c-_q.b*c;
+	b1=w*_q.b+_q.w*b-a*_q.c+c*_q.a;
+	c1=w*_q.c+_q.w*c+a*_q.b-_q.a*b;
+	return Quat(w1,a1,b1,c1);
+}
+ 
+Quat& Quat::operator*=(const Quat& _q) 
+/*! Quaternion self-multiplication operator
+ * \param _q :: the quaternion to multiply
+ * \return *this*=_q
+ */
+{
+	double w1,a1,b1,c1;
+	w1=w*_q.w-a*_q.a-b*_q.b-c*_q.c;
+	a1=w*_q.a+_q.w*a+b*_q.c-_q.b*c;
+	b1=w*_q.b+_q.w*b-a*_q.c+c*_q.a;
+	c1=w*_q.c+_q.w*c+a*_q.b-_q.a*b;
+	w=w1;a=a1;b=b1;c=c1;
+	return (*this);
+}
+ 
+bool Quat::operator==(const Quat& q) const 
+/*! Quaternion equal operator
+ * \param _q :: the quaternion to compare
+ * 
+ * Compare two quaternions at 1e-6%tolerance.
+ * Use boost close_at_tolerance method
+ */
+{
+	return (quat_tol(w,q.w) && quat_tol(a,q.a) && quat_tol(b,q.b) && quat_tol(c,q.c));
+} 
+ 
+bool Quat::operator!=(const Quat& _q) const
+{
+/*! Quaternion non-equal operator
+ * \param _q :: the quaternion to compare
+ * 
+ * Compare two quaternions at 1e-6%tolerance.
+ *  Use boost close_at_tolerance method
+ */
+	return (!operator==(_q));
+} 
+ 
+void Quat::normalize()
+/*! Quaternion normalization
+ * 
+ * Divide all elements by the quaternion norm
+ */
+{
+	double overnorm=1.0/len2();
+	w*=overnorm;
+	a*=overnorm;
+	b*=overnorm;
+	c*=overnorm;
+	return;
+}
+ 
+void Quat::conjugate()
+/*! Quaternion complex conjugate
+ * 
+ *  Reverse the sign of the 3 imaginary components of the 
+ *  quaternion
+ */
+{
+	a*=-1.0;
+	b*=-1.0;
+	c*=-1.0;
+	return;
+}
+ 
+double Quat::len() const
+/*! Quaternion length
+ *  
+ */
+{
+	return sqrt(len2());
+}
+
+double Quat::len2() const
+/*! Quaternion norm (length squared) 
+ *    
+ */
+{
+	return (w*w+a*a+b*b+c*c);
+}
+ 
+void Quat::inverse()  
+/*! Inverse a quaternion
+ *  
+ */
+{
+	conjugate();
+	normalize();
+	return;
+}
+void Quat::rotate(V3D& v) const
+/*! 	Rotate a vector. 
+ *  \param v :: the vector to be rotated
+ *  
+ *   The quaternion needs to be normalized beforehand to
+ *   represent a rotation. If q is thequaternion, the rotation
+ *   is represented by q.v.q-1 where q-1 is the inverse of 
+ *   v. 
+ */
+ {
+ 	Quat qinvert(*this);
+ 	qinvert.inverse();
+ 	Quat pos(0.0,v[0],v[1],v[2]);
+ 	pos*=qinvert;
+ 	pos=(*this)*pos;
+ 	v[0]=pos[1];
+ 	v[1]=pos[2];
+ 	v[2]=pos[3];
+ }
+void Quat::GLMatrix(double mat[16])  
+/*! 
+ */
+{
+	double aa      = a * a;
+	double ab      = a * b;
+	double ac      = a * c;
+	double aw      = a * w;
+	double bb      = b * b;
+	double bc      = b * c;
+	double bw      = b * w;
+	double cc      = c * c;
+	double cw      = c * w;
+	mat[0]  = 1.0 - 2.0 * ( bb + cc );
+	mat[4]  =     2.0 * ( ab - cw );
+	mat[8]  =     2.0 * ( ac + bw );
+	mat[1]  =     2.0 * ( ab + cw );
+	mat[5]  = 1.0 - 2.0 * ( aa + cc );
+	mat[9]  =     2.0 * ( bc - aw );
+	mat[2]  =     2.0 * ( ac - bw );
+	mat[6]  =     2.0 * ( bc + aw );
+	mat[10] = 1.0 - 2.0 * ( aa + bb );
+	mat[12]  = mat[13] = mat[14] = mat[3] = mat[7] = mat[11] = 0.0;
+	mat[15] = 1.0;
+	return;
+}
+  
+const double& Quat::operator[](const int Index) const
+{
+	switch (Index)
+	    {
+	    case 0: return w;
+	    case 1: return a;
+	    case 2: return b;
+	    case 3: return c;
+	    default:
+	      throw std::runtime_error("Quat::operator[] range error");
+	}
+}
+
+double& Quat::operator[](const int Index) 
+{
+	switch (Index)
+	    {
+	    case 0: return w;
+	    case 1: return a;
+	    case 2: return b;
+	    case 3: return c;
+	    default:
+	      throw std::runtime_error("Quat::operator[] range error");
+	}
+}
+
+void Quat::printSelf(std::ostream& os) const
+{
+	os << "[" << w << "," << a << "," << b << "," << c << "]";
+	return;
+
+}
+
+std::ostream& operator<<(std::ostream& os,const Quat& q)
+{
+	q.printSelf(os);
+	return os;
+}
+
+} // Namespace Geometry
+
+} // Namespce Mantid
-- 
GitLab