diff --git a/Code/Mantid/Geometry/inc/CompAssembly.h b/Code/Mantid/Geometry/inc/CompAssembly.h new file mode 100644 index 0000000000000000000000000000000000000000..dbfad69742e8a6c58d48b5b2c048c65db5c95a09 --- /dev/null +++ b/Code/Mantid/Geometry/inc/CompAssembly.h @@ -0,0 +1,75 @@ +#ifndef COMPONENT_ASSEMBLY_ +#define COMPONENT_ASSEMBLY_ +#include <string> +#include "Component.h" +#include <vector> +namespace Mantid +{ +namespace Geometry +{ + /** @class CompAssembly + @brief Class for Assembly of geometric components. + @version A + @author Laurent C Chapon, ISIS RAL + @date 01/11/2007 + + CompAssembly allows Component to be positioned + in a hierarchical structure in the form of a tree. + CompAssembly inherit from component. + @ignore + Copyright 2007 RAL + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: + <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + */ +class CompAssembly : public Component +{ + +public: + virtual std::string type() const {return "CompAssembly";} + //! Empty constructor + CompAssembly(); + //! Constructor with a name and parent reference + CompAssembly(const std::string&, Component* reference=0); + //! Copy constructor + CompAssembly(const CompAssembly&); + virtual ~CompAssembly(); + //! Make a clone of the present component + virtual Component* clone() const ; + //! Return the number of elements in the assembly + int nelements() const; + //! Add a component to the assembly + int add(Component*); + //! Add a copy (clone) of a component + int addCopy(Component*); + //! Add a copy (clone) of a component and rename it + int addCopy(Component*,const std::string&); + //! Get a pointer to the ith component in the assembly + Component* operator[](int i) const; + //! Print information about all children + void printChildren(std::ostream&) const; + void printTree(std::ostream&) const; +private: + std::vector<Component*> group; +}; + +std::ostream& operator<<(std::ostream&, const CompAssembly&); +} //Namespace Geometry +} //Namespace Mantid + +#endif diff --git a/Code/Mantid/Geometry/inc/Component.h b/Code/Mantid/Geometry/inc/Component.h new file mode 100644 index 0000000000000000000000000000000000000000..e15e2732ee73b706541d821daaed521350829abb --- /dev/null +++ b/Code/Mantid/Geometry/inc/Component.h @@ -0,0 +1,115 @@ +#ifndef COMPONENT_H_ +#define COMPONENT_H_ +#include <string> +#include "V3D.h" +#include "Quat.h" + +namespace Mantid +{ +namespace Geometry +{ + + // Forward declarations + // end forward declarations +/** @class Component + @brief base class for Geometric component + @version A + @author Laurent C Chapon, ISIS RAL + @date 01/11/2007 + + This is the base class for geometric components. + Geometric component can be placed in a hierarchical + structure and are defined with respect to a + parent component. The component position and orientation + are relatives, i.e. defined with respect to the parent + component. The orientation is stored as a quaternion. + Each component has a defined bounding box which at the moment + is cuboid. + @ignore + Copyright 2007 RAL + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: + <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + */ +class Component +{ +public: + virtual std::string type() const {return "LogicalComponent";} + //! Create Empty Component at Origin, with no orientation and null parent + Component(); + //! Create a named component with a parent component (optional) + Component(const std::string&, Component* reference=0); + //! Create a named component with positioning vector, and parent component (optional) + Component(const std::string&, const V3D&, Component* reference=0); + //! Create a named component with positioning vector, orientation and parent component + Component(const std::string&, const V3D&, const Quat&, Component* reference=0); + //Copy constructors + //! Copy constructor + Component(const Component&); + Component& operator=(const Component&); + //! Return a clone to the current object + virtual Component* clone() const; + virtual ~Component(); + //! Assign a parent component. Previous parent link is lost + void setParent(Component*); + //! Return a pointer to the current parent. + const Component* getParent() const; + //! Set the component name + void setName(const std::string&); + //! Get the component name + std::string getName() const; + //! Set the component position, x, y, z respective to parent (if present) otherwise absolute + void setPos(double, double, double); + void setPos(const V3D&); + //! Set the orientation quaternion relative to parent (if present) otherwise absolute + void setRot(const Quat&); + //! Copy the Rotation from another component + void copyRot(const Component&); + //! Translate the component (vector form). This is relative to parent if present. + void translate(const V3D&); + //! Translate the component (x,y,z form). This is relative to parent if present. + void translate(double, double, double); + //! Rotate the component. This is relative to parent. + void rotate(const Quat&); + //! Rotate the component by an angle in degrees with respect to an axis. + void rotate(double,const V3D&); + //! Get the position relative to the parent component (absolute if no parent) + V3D getRelativePos() const; + //! Get the position of the component. Tree structure is traverse through the parent chain + V3D getPos() const; + //! Get the relative Orientation + const Quat& getRelativeRot() const; + //! Get the distance to another component + double getDistance(const Component&) const; + void printSelf(std::ostream&) const; +private: + //! Name of the component + std::string name; + //! Position w + V3D pos; + //! Orientation + Quat rot; + Component* parent; // Parent component in the tree +}; + +std::ostream& operator<<(std::ostream&, const Component&); + +} //Namespace Geometry +} //Namespace Mantid + +#endif /*COMPONENT_H_*/ diff --git a/Code/Mantid/Geometry/inc/Quat.cpp b/Code/Mantid/Geometry/inc/Quat.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0fc2741620fba8c129983eb8a3ddf68084755f62 --- /dev/null +++ b/Code/Mantid/Geometry/inc/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 diff --git a/Code/Mantid/Geometry/inc/Quat.h b/Code/Mantid/Geometry/inc/Quat.h deleted file mode 100644 index 7f70a1af5aa3c871fb53c7699164ce0ac50ae4e1..0000000000000000000000000000000000000000 --- a/Code/Mantid/Geometry/inc/Quat.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef MANTID_QUAT_H_ -#define MANTID_QUAT_H_ - -#include <iostream> - -namespace Mantid -{ -namespace Geometry -{ -//Forward declarations -class V3D; -class M33; - -class Quat -{ - /** @class Quat Quat.h Geometry/Quat.h - @brief Class for quaternions - @version 1.0 - @author Laurent C Chapon, ISIS RAL - @date 10/10/2007 - - Templated class for quaternions. - Quaternions are the 3D generalization of complex numbers - Quaternions are used for roations in 3D spaces and - often implemented for computer graphics applications. - Quaternion can be written q=W+ai+bj+ck where - w is the scalar part, and a, b, c the 3 imaginary parts. - Quaternion multiplication is non-commutative. - i*j=-j*i=k - j*k=-k*j=i - k*i=-i*k=j - Rotation of an angle theta around a normalized axis (u,v,w) can be simply - written W=cos(theta/2), a=u*sin(theta/2), b=v*sin(theta/2), c=w*sin(theta/2) - This class support all arithmetic operations for quaternions - @ignore - Copyright � 2007 ???RAL??? - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your ption) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - - File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> - */ - public: - Quat(); - Quat(const double, const double, const double, const double); - Quat(const Quat&); - //! Set quaternion form an angle in degrees and an axis - Quat(const double, const V3D&); - //Quat(const M33&); - ~Quat(); - Quat& operator=(const Quat&); - void operator()(const double, const double, const double, const double); - void operator()(const double, const V3D&); - //! Set quaternion from a 3x3 matrix - //void operator()(const M33&); - void set(const double, const double, const double, const double); - void setAngleAxis(const double, const V3D&); - //void setRotMatrix(const M33&); - //! Norm of a quaternion - double len() const; - //! Norm squared - double len2() const; - //! Initialized to identity - void init(); - //! Nornmalize - void normalize(); - //! Take the complex conjugate - void conjugate(); - //! Inverse a quaternion (in the sense of rotayion inversion) - void inverse(); - //! Convert quaternion rotation to an OpenGL matrix [4x4] matrix - //! stored as an linear array of 16 double - //! The function glRotated must be called - void GLMatrix(double[16]); - //! Rotate a vector - void rotate(V3D&); - //! Overload operators - Quat operator+(const Quat&) const; - Quat& operator+=(const Quat&); - Quat operator-(const Quat&) const; - Quat& operator-=(const Quat&); - Quat operator*(const Quat&) const; - Quat& operator*=(const Quat&); - bool operator==(const Quat&) const; - bool operator!=(const Quat&) const; - const double& operator[](int) const; - double& operator[](int); - void printSelf(std::ostream&) const; - private: - double w, a, b, c; -}; - - //! Overload operator <<. This calls Quat::printself() - std::ostream& operator<<(std::ostream&, const Quat&); - -} // Namespace Mantid - -} // Namespace Geometry - -#endif /*MANTID_QUAT_H_*/ diff --git a/Code/Mantid/Geometry/inc/V3D.h b/Code/Mantid/Geometry/inc/V3D.h deleted file mode 100644 index f043f121e7920290350948cc9eb856029164a48a..0000000000000000000000000000000000000000 --- a/Code/Mantid/Geometry/inc/V3D.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef MANTID_V3D_H_ -#define MANTID_V3D_H_ - -namespace Mantid -{ -namespace Geometry -{ - class V3D - /** @class V3D - @brief Class for 3D vectors. - @version A - @author Laurent C Chapon, ISIS RAL - @date 09/10/2007 - - @ignore - Copyright 2007 RAL - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - - File change history is stored at: - <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> - */ - { - public: - - V3D(); - V3D(const V3D&); - V3D& operator=(const V3D&); - V3D(const double,const double,const double); - V3D(const double*); - ~V3D(); - - // Arithemetic operators overloaded - V3D operator+(const V3D&) const; - V3D& operator+=(const V3D&); - - V3D operator-(const V3D&) const; - V3D& operator-=(const V3D&); - // Inner product - V3D operator*(const V3D&) const; - V3D& operator*=(const V3D&); - // Inner division - V3D operator/(const V3D&) const; - V3D& operator/=(const V3D&); - // Scale - V3D operator*(const double) const; - V3D& operator*=(const double); - V3D operator/(const double) const; - V3D& operator/=(const double); - // Simple Comparison - bool operator==(const V3D&) const; - bool operator<(const V3D&) const; - // Access - // Setting x, y and z values - void operator()(const double, const double, const double); - // Get x - const double& X() const { return x; } - const double& Y() const { return y; } - const double& Z() const { return z; } - - const double& operator[](const int) const; - double& operator[](const int); - - // Make a normalized vector (return norm value) - double normalize(); - double norm() const; - double norm2() const; - // Scalar product - double scalar_prod(const V3D&) const; - // Cross product - V3D cross_prod(const V3D&) const; - // Distance between two points defined as vectors - double distance(const V3D&) const; - // Send to a stream - void printSelf(std::ostream&) const; - - private: - - double x; ///< X value [unitless] - double y; ///< Y value [unitless] - double z; ///< Z value [unitless] - }; - - // Overload operator << - std::ostream& operator<<(std::ostream&, const V3D&); - -} // Namespace Geometry -} // Namespace Mantid - -#endif /*MANTID_V3D_H_*/ diff --git a/Code/Mantid/Geometry/src/CompAssembly.cpp b/Code/Mantid/Geometry/src/CompAssembly.cpp new file mode 100644 index 0000000000000000000000000000000000000000..249d95e8f5b168ae26c9d35bcc8517a04dd03059 --- /dev/null +++ b/Code/Mantid/Geometry/src/CompAssembly.cpp @@ -0,0 +1,191 @@ +#include "CompAssembly.h" +#include <algorithm> +#include <stdexcept> +#include <ostream> +namespace Mantid +{ +namespace Geometry +{ + +/*! Empty constructor + */ +CompAssembly::CompAssembly():Component() +{ +} + +/*! Valued constructor + * @param n :: name of the assembly + * @param reference :: the parent Component + * + * If the reference is an object of class Component, + * normal parenting apply. If the reference object is + * an assembly itself, then in addition to parenting + * this is registered as a children of reference. + */ +CompAssembly::CompAssembly(const std::string& n, Component* reference) : Component(n,reference) +{ + if (reference) + { + CompAssembly* test=dynamic_cast<CompAssembly*>(reference); + if (test) + test->add(this); + } +} + +/*! Copy constructor + * @param ass :: assembly to copy + */ +CompAssembly::CompAssembly(const CompAssembly& ass):Component(ass) +{ + group=ass.group; +} + +/*! Destructor + */ +CompAssembly::~CompAssembly() +{ + group.empty(); +} + +/*! Clone method + * Make a copy of the component assembly + * @return new(*this) + */ +Component* CompAssembly::clone() const +{ + return new CompAssembly(*this); +} + +/*! Add method + * @param comp :: component to add + * @return number of components in the assembly + * + * This becomes the new parent of comp. + */ +int CompAssembly::add(Component* comp) +{ + if (comp) + { + comp->setParent(this); + group.push_back(comp); + } + return group.size(); +} + +/*! AddCopy method + * @param comp :: component to add + * @return number of components in the assembly + * + * Add a copy of a component in the assembly. + * Comp is cloned if valid, then added in the assembly + * This becomes the parent of the cloned component + */ +int CompAssembly::addCopy(Component* comp) +{ + if (comp) + { + Component* newcomp=comp->clone(); + newcomp->setParent(this); + group.push_back(newcomp); + } + return group.size(); +} + +/*! AddCopy method + * @param comp :: component to add + * @param m :: name of the copied component. + * @return number of components in the assembly + * + * Add a copy of a component in the assembly. + * Comp is cloned if valid, then added in the assembly + * This becomes the parent of the cloned component + */ +int CompAssembly::addCopy(Component* comp, const std::string& n) +{ + if (comp) + { + Component* newcomp=comp->clone(); + newcomp->setParent(this); + newcomp->setName(n); + group.push_back(newcomp); + } + return group.size(); +} + +/*! Return the number of components in the assembly + * @return group.size() + */ +int CompAssembly::nelements() const +{ + return group.size(); +} + +/*! Get a pointer to the ith component in the assembly + * @return group[i] + * + * Throws if i is not in range + */ +Component* CompAssembly::operator[](int i) const +{ + if (i<0 || i> static_cast<int>(group.size()-1)) + throw std::runtime_error("CompAssembly::operator[] range not valid"); + return group[i]; +} + +/*! Print information about elements in the assembly to a stream + * @param os :: output stream + * + * Loops through all components in the assembly + * and call printSelf(os). + */ +void CompAssembly::printChildren(std::ostream& os) const +{ + std::vector<Component*>::const_iterator it; + int i=0; + for (it=group.begin();it!=group.end();it++) + { + os << "Component " << i++ <<" : **********" <<std::endl; + (*it)->printSelf(os); + } +} + +void CompAssembly::printTree(std::ostream& os) const +{ + std::vector<Component*>::const_iterator it; + int i=0; + for (it=group.begin();it!=group.end();it++) + { + const CompAssembly* test=dynamic_cast<CompAssembly*>(*it); + os << "Element " << i++ << " in the assembly : "; + if (test) + { + os << test->getName() << std::endl; + os << "Children :******** " << std::endl; + test->printTree(os); + } + else + os << (*it)->getName() << std::endl; + } +} + +/*! Print information about elements in the assembly to a stream + * Overload the operator << + * @param os :: output stream + * @param ass :: component assembly + * + * Loops through all components in the assembly + * and call printSelf(os). + * Also output the number of children + */ +std::ostream& operator<<(std::ostream& os, const CompAssembly& ass) +{ + ass.printSelf(os); + os << "************************" << std::endl; + os << "Number of children :" << ass.nelements() << std::endl; + ass.printChildren(os); + return os; +} + +} // Namespace Geometry +} // Namespace Mantid + diff --git a/Code/Mantid/Geometry/src/Component.cpp b/Code/Mantid/Geometry/src/Component.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9f06fd0aaf0d2c3be0d2d2c6d1ff94705242c7eb --- /dev/null +++ b/Code/Mantid/Geometry/src/Component.cpp @@ -0,0 +1,214 @@ +#include "Component.h" +#include "Quat.h" + +namespace Mantid +{ +namespace Geometry +{ + +/*! Empty constructor + * Create a component with null parent + */ +Component::Component() +{ + name=""; + parent=0; +} + +/*! Constructor by value + * @param n :: Component name + * @param reference :: parent Component (optional) + */ +Component::Component(const std::string& n, Component* reference):name(n),parent(reference) +{ +} + +/*! Constructor by value + * @param n :: Component name + * @param v :: position + * absolute or relative if the reference if defined + * @param reference :: parent Component + */ +Component::Component(const std::string& n, const V3D& v, Component* reference):name(n),pos(v),parent(reference) +{ + if (reference) parent=reference; +} + +/*! Constructor + * @param n :: Component name + * @param v :: position + * @param q :: orientation quaternion + * @param reference :: parent Component (optional) + */ +Component::Component(const std::string& n, const V3D& v, const Quat& q, Component* reference):name(n),pos(v),rot(q),parent(reference) +{ + if (reference) parent=reference; +} +Component::~Component(){} + +/*! Copy constructor + * @param comp :: Component to copy + * + * All properties of comp are copied including the parent Component + */ +Component::Component(const Component& comp) +{ + name=comp.name; + parent=comp.parent; + pos=comp.pos; + rot=comp.rot; +} + +/*! Clone method + * Make a copy of the component + * @return new(*this) + */ +Component* Component::clone() const +{ + return new Component(*this); +} + +/*! Set the parent. Previous parenting is lost. + * @param comp :: the parent component + */ +void Component::setParent(Component* comp) +{ + parent=comp; +} + +/*! Get a pointer to the parent. + * @return this.parent + */ +const Component* Component::getParent() const +{ + return parent; +} + +/*! Set the name of the component + * @param s :: name string + */ +void Component::setName(const std::string& s) +{ + name=s; +} + +/*! Get the name of the component + * @return this.name + */ +std::string Component::getName() const +{ + return name; +} + +/*! Set the position of the component + * The position is with respect to the parent component + * @param x :: x position + * @param y :: y position + * @param z :: z position + */ +void Component::setPos(double x, double y, double z) +{ + pos(x,y,z); +} + +/*! Set the position of the component + * The position is with respect to the parent component + * @param v :: vector position + */ +void Component::setPos(const V3D& v) +{ + pos=v; +} + +/*! Set the orientation of the component + * The position is with respect to the parent component + * @param q :: rotation quaternion + */ +void Component::setRot(const Quat& q) +{ + rot=q; +} + +/*! Copy the orientationmatrix from another component + * @param comp :: component to copy rotation from + */ +void Component::copyRot(const Component& comp) +{ + rot=comp.rot; +} + +/*! Translate the component relative to the parent component + * @param x :: translation on the x-axis + * @param y :: translation on the y-axis + * @param z :: translation on the z-axis + */ +void Component::translate(double x, double y, double z) +{ + pos[0]+=x; + pos[1]+=y; + pos[2]+=z; + return; +} + +/*! Translate the component relative to the parent component + * @param v :: translation vector + */ +void Component::translate(const V3D& v) +{ + pos+=v; + return; +} +void Component::rotate(const Quat& r) +{ + rot=r*rot; +} +void Component::rotate(double, const V3D& axis) +{ + +} +V3D Component::getRelativePos() const +{ + return pos; +} +V3D Component::getPos() const +{ + + if (!parent) + return pos; + else + { + V3D temp(pos); + rot.rotate(temp); + temp+=parent->getPos(); + return temp; + } +} +const Quat& Component::getRelativeRot() const +{ + return rot; +} +double Component::getDistance(const Component& comp) const +{ + return pos.distance(comp.pos); +} +void Component::printSelf(std::ostream& os) const +{ + os << "Name : " << name << std::endl; + os << "Type: " << this->type() << std::endl; + if (parent) + os << "Parent: " << parent->name << std::endl; + else + os << "Parent: None" << std::endl; + + os << "Position : " << getPos() << std::endl; + os << "Orientation :" << rot << std::endl; +} +std::ostream& operator<<(std::ostream& os, const Component& comp) +{ + comp.printSelf(os); + return os; +} + + +} //Namespace Geometry +} //Namespace Mantid diff --git a/Code/Mantid/Geometry/src/V3D.cpp b/Code/Mantid/Geometry/src/V3D.cpp deleted file mode 100644 index 6e6b1f1416566643b2f68d5ebaf916f3dd091faa..0000000000000000000000000000000000000000 --- a/Code/Mantid/Geometry/src/V3D.cpp +++ /dev/null @@ -1,361 +0,0 @@ -#include <ostream> -#include <stdexcept> -#include <cmath> -#include <vector> - - -// THIS IS VERY ERROR PRONE :: USE "V3D.h" and -I flag. -#include "../inc/V3D.h" - -namespace Mantid -{ -namespace Geometry -{ - -const double precision(1e-7); - -V3D::V3D():x(0),y(0),z(0) - /// Constructor [Null] -{} - -V3D::V3D(const double xx, const double yy, const double zz) : - x(xx),y(yy),z(zz) - /// Value constructor -{} - -V3D::V3D(const V3D& v):x(v.x),y(v.y),z(v.z) - /// Copy constructor -{} - -V3D& -V3D::operator=(const V3D& A) - /*! - Assignment operator - \param v :: V3D to copy - \return *this - */ -{ - if (this!=&A) - { - x=A.x; - y=A.y; - z=A.z; - } - return *this; -} - -V3D::V3D(const double* vPtr) - /*! - Constructor from a pointer. - requires that the point is assigned after this has - been allocated since vPtr[x] may throw. - */ -{ - if (vPtr) - { - x=vPtr[0]; - y=vPtr[1]; - z=vPtr[2]; - } -} - -V3D::~V3D() - /// Destructor -{} - -V3D -V3D::operator+(const V3D& v) const - /* - Addtion operator - \param v :: Vector to add - \return *this+v; - */ -{ - V3D out(*this); - out+=v; - return out; -} - -V3D -V3D::operator-(const V3D& v) const - /* - Subtraction operator - \param v :: Vector to sub. - \return *this-v; - */ -{ - V3D out(*this); - out-=v; - return out; -} - -V3D -V3D::operator*(const V3D& v) const - /* - Inner product - \param v :: Vector to sub. - \return *this * v; - */ -{ - V3D out(*this); - out*=v; - return out; -} - -V3D -V3D::operator/(const V3D& v) const - /* - Inner division - \param v :: Vector to divide - \return *this * v; - */ -{ - V3D out(*this); - out/=v; - return out; -} - -V3D& -V3D::operator+=(const V3D& v) - /* - Self-Addition operator - \param v :: Vector to add. - \return *this+=v; - */ -{ - x+=v.x; - y+=v.y; - z+=v.z; - return *this; -} - -V3D& -V3D::operator-=(const V3D& v) - /* - Self-Subtraction operator - \param v :: Vector to sub. - \return *this-v; - */ -{ - x-=v.x; - y-=v.y; - z-=v.z; - return *this; -} - -V3D& -V3D::operator*=(const V3D& v) - /* - Self-Inner product - \param v :: Vector to multiply - \return *this*=v; - */ -{ - x*=v.x; - y*=v.y; - z*=v.z; - return *this; -} - -V3D& -V3D::operator/=(const V3D& v) - /* - Self-Inner division - \param v :: Vector to divide - \return *this*=v; - */ -{ - x/=v.x; - y/=v.y; - z/=v.z; - return *this; -} - -V3D -V3D::operator*(const double D) const - /*! - Scalar product - \param D :: value to scale - \return this * D - */ -{ - V3D out(*this); - out*=D; - return out; -} - -V3D -V3D::operator/(const double D) const - /*! - Scalar divsion - \param D :: value to scale - \return this / D - */ -{ - V3D out(*this); - out/=D; - return out; -} - -V3D& -V3D::operator*=(const double D) - /*! - Scalar product - \param D :: value to scale - \return this *= D - */ -{ - x*=D; - y*=D; - z*=D; - return *this; -} - -V3D& -V3D::operator/=(const double D) - /*! - Scalar division - \param D :: value to scale - \return this /= D - \todo ADD PRECISION - */ -{ - if (D!=0.0) - { - x/=D; - y/=D; - z/=D; - } - return *this; -} - -bool -V3D::operator==(const V3D& v) const - /*! - Equals operator with tolerance factor - \param v :: V3D for comparison - */ -{ - return (fabs(x-v.x)>precision || - fabs(y-v.y)>precision || - fabs(z-v.z)>precision) ? - false : true; -} - -bool -V3D::operator<(const V3D& V) const - /*! - \tood ADD PRCESSION - */ -{ - if (x!=V.x) - return x<V.x; - if (y!=V.y) - return y<V.y; - return z<V.z; -} - -void -V3D::operator()(const double xx, const double yy, const double zz) -{ - x=xx; - y=yy; - z=zz; - return; -} - -const double& -V3D::operator[](const int Index) const -{ - switch (Index) - { - case 0: return x; - case 1: return y; - case 2: return z; - default: - throw std::runtime_error("V3D::operator[] range error"); - } -} - -double& -V3D::operator[](const int Index) -{ - switch (Index) - { - case 0: return x; - case 1: return y; - case 2: return z; - default: - throw std::runtime_error("V3D::operator[] range error"); - } -} - -double -V3D::norm() const - /*! - Vector length - \return vec.length() - */ -{ - return sqrt(x*x+y*y+z*z); -} - -double -V3D::norm2() const -{ - return (x*x+y*y+z*z); -} - -double -V3D::normalize() - /*! - Normalises the vector and - then returns the scalar value of the vector - \return Norm - */ -{ - const double ND(norm()); - this->operator/=(ND); - return ND; -} - -double -V3D::scalar_prod(const V3D& V) const -{ - return (x*V.x+y*V.y+z*V.z); -} - -V3D -V3D::cross_prod(const V3D& v) const -{ - V3D out; - out.x=y*v.z-z*v.y; - out.y=z*v.x-x*v.z; - out.z=x*v.y-y*v.x; - return out; -} - -double -V3D::distance(const V3D& v) const -{ - V3D dif(*this); - dif-=v; - return dif.norm(); -} - -void -V3D::printSelf(std::ostream& os) const -{ - os << "[" << x << "," << y << "," << z << "]"; - return; -} - -std::ostream& -operator<<(std::ostream& os, const V3D& v) -{ - v.printSelf(os); - return os; -} - -} // Namespace Geometry -} // Namespace Mantid