/****************************************************************************
Copyright (C) 2012-2012 Université de Sherbrooke, Québec, CANADA
All rights reserved.
Contact : richard.fournier@usherbrooke.ca
jean-francois.cote@nrcan-rncan.gc.ca
joris.ravaglia@gmail.com
Developers : Joris RAVAGLIA
This file is part of Computree version 2.0.
Computree 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.
Computree 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 Computree. If not, see .
*****************************************************************************/
#ifndef CT_SCANNER_H
#define CT_SCANNER_H
/** \file ct_scanner.h
\author J. Ravaglia - mail to : joris.ravaglia@gmail.com
\version 0.1
*/
#include "ct_itemdrawable/abstract/ct_abstractitemdrawablewithoutpointcloud.h" // Inherits from CT_abstractItemDrawableWithoutPointCloud
#include "ct_point.h" // Used to get rays from a scanner
#include // Used for M_PI constant
#include "ct_itemdrawable/ct_beam.h" // A scan creates some rays
#include "ct_itemdrawable/tools/drawmanager/ct_standardscannerdrawmanager.h"
#include "ct_itemdrawable/tools/scanner/ct_thetaphishootingpattern.h"
class CT_ThetaPhiShootingPattern;
/*! \def DEG2RAD
Linear constant to cast an angle in degrees to this angle in radians.
*/
#define DEG2RAD (M_PI/180.0)
/*! \def RAD2DEG
Linear constant to cast an angle in radians to this angle in degrees.
*/
#define RAD2DEG (180.0/M_PI)
/*! \def SCANNER_EPSILON
Used to avoid some instabilities : in some cases, we want values less than this constant (10e-5) become 0
*/
#define SCANNER_EPSILON 0.00001
/** \class CT_Scanner
\brief This class represents a terrestrial LiDAR scanner.
Angles are measured in radians and the theta/phi attributes are calculated on a spherical coordinates basis.
\ingroup PluginShared_Items
\todo Un scanner est-il un item drawable ? (Affichage de sa position) ?
*/
class PLUGINSHAREDSHARED_EXPORT CT_Scanner : public CT_AbstractItemDrawableWithoutPointCloud
{
Q_OBJECT
CT_TYPE_IMPL_MACRO(CT_Scanner, CT_AbstractItemDrawableWithoutPointCloud, Scan position)
public:
//********************************************//
// Constructors/Destructors //
//********************************************//
/*!
* \brief Default constructor
*
* Default constructor of the class
* Each attribute will be set to 0 or NULL
* Each vector will be empty
* \warning The _zVector attribute is set to (0,0,1) by default
*
*/
CT_Scanner( int scanID = 0, bool clockWise = true );
/*!
* \brief Constructor
*
* Constructor of the class
* Only take into account the CT_AbstractItemDrawableWithoutPointCloud members
* Each attribute will be set to 0 or NULL
* Each vector will be empty
* \warning The _zVector attribute is set to (0,0,1) by default
*
*/
CT_Scanner(const CT_OutAbstractSingularItemModel *model, const CT_AbstractResult *result, int scanId = 0, bool clockWise = true );
/*!
* \brief Constructor
*
* Constructor of the class
*
* \param scanID : ID of the scan
* \param position : position of the scan in world coordinate system
* \param zVector : vertica of the scan : (0,0,1) by default
* \param hFov : horizontal field of view
* \param vFov : vertical field of view
* \param hRes : horizontal resolution (angle between two consecutive horizontal rays)
* \param vRes : vertical resolution
* \param initTheta : (horizontal) angle between the first ray and the Ox axis
* \param initPhi : (vertical) angle between the first vertical ray and the Oz axis
* \param radians : type of angle (radians or degrees), degrees by default
*/
CT_Scanner(const CT_OutAbstractSingularItemModel *model, const CT_AbstractResult *result, int scanID, const Eigen::Vector3d &position, const Eigen::Vector3d &zVector, double hFov, double vFov, double hRes, double vRes, double initTheta, double initPhi, bool clockWise, bool radians = false );
CT_Scanner(const QString &modelName, const CT_AbstractResult *result, int scanId = 0, bool clockWise = true );
CT_Scanner(const QString &modelName, const CT_AbstractResult *result, int scanID, const Eigen::Vector3d& position, const Eigen::Vector3d& zVector, double hFov, double vFov, double hRes, double vRes, double initTheta, double initPhi, bool clockWise, bool radians = false );
/*!
* \brief Destructor
*
* Destructor of the class
*
*/
~CT_Scanner();
//********************************************//
// Getters //
//********************************************//
/*!
* \brief Getter of the class
*
* \return Returns the ID of the scanner
*/
inline int getScanID() const { return _scanID; }
/*!
* \brief Getter of the class
*
* \return Returns the position of the scanner
*/
inline Eigen::Vector3d getPosition() const { return getCenterCoordinate(); }
inline double getPositionX() const {return getCenterX();}
inline double getPositionY() const {return getCenterY();}
inline double getPositionZ() const {return getCenterZ();}
/*!
* \brief Getter of the class
*
* \return Returns the ID of the scanner
*/
inline Eigen::Vector3d getZVector() const { return m_shootingPattern->getZVector(); }
inline double getZVectorX() const {return getZVector()(0);}
inline double getZVectorY() const {return getZVector()(1);}
inline double getZVectorZ() const {return getZVector()(2);}
/*!
* \brief Getter of the class
*
* \return Returns the horizontal field of view of the scanner
*/
inline double getHFov() const { return m_shootingPattern->getHFov(); }
/*!
* \brief Getter of the class
*
* \return Returns the vertical field of view of the scanner
*/
inline double getVFov() const { return m_shootingPattern->getVFov(); }
/*!
* \brief Getter of the class
*
* \return Returns the horizontal resolution of the scanner
*/
inline double getHRes() const { return m_shootingPattern->getHRes(); }
/*!
* \brief Getter of the class
*
* \return Returns the vertical resolution of the scanner
*/
inline double getVRes() const { return m_shootingPattern->getVRes(); }
/*!
* \brief Getter of the class
*
* \return Returns the initial theta of the scanner
*/
inline double getInitTheta() const { return m_shootingPattern->getInitTheta(); }
/*!
* \brief Getter of the class
*
* \return Returns the initial phi of the scanner
*/
inline double getInitPhi() const { return m_shootingPattern->getInitPhi(); }
/*!
* \brief Getter of the class
*
* \return Returns the number of horizontal rays of the scanner
*/
inline int getNHRays() const { return m_shootingPattern->getNHRays(); }
/*!
* \brief Getter of the class
*
* \return Returns the number of vertical rays of the scanner
*/
inline double getNVRays() const { return m_shootingPattern->getNVRays(); }
/*!
* \brief Getter of the class
*
* \return Returns true if the scanner is clockwise, false else
*/
inline bool getClockWise() const { return m_shootingPattern->isClockWise(); }
/**
* @brief Returns the shooting pattern
*/
CT_ShootingPattern* getShootingPattern() const;
//********************************************//
// Setters //
//********************************************//
/*!
* \brief Setter of the class
*/
inline void setID ( int scanID ) { _scanID = scanID; }
/*!
* \brief Setter of the class
*/
inline void setPosition ( const Eigen::Vector3d& position ) { setCenterCoordinate(position); m_shootingPattern->setOrigin(position); }
/*!
* \brief Setter of the class
*/
inline void setZVector ( const Eigen::Vector3d& zVector ) { m_shootingPattern->setZVector(zVector); }
/*!
* \brief Setter of the class
*/
inline void setHFov ( double hFov ) { m_shootingPattern->setHFov(hFov); }
/*!
* \brief Setter of the class
*/
inline void setVFov ( double vFov ) { m_shootingPattern->setVFov(vFov); }
/*!
* \brief Setter of the class
*/
inline void setHRes ( double hRes ) { m_shootingPattern->setHRes(hRes); }
/*!
* \brief Setter of the class
*/
inline void setVRes ( double vRes ) { m_shootingPattern->setVRes(vRes); }
/*!
* \brief Setter of the class
*/
inline void setInitTheta ( double initTheta ) { m_shootingPattern->setInitTheta(initTheta); }
/*!
* \brief Setter of the class
*/
inline void setInitPhi ( double initPhi ) { m_shootingPattern->setInitPhi(initPhi); }
/*!
* \brief Setter of the class
*/
inline void setNHRays ( int nHRays ) { m_shootingPattern->setNHRays(nHRays); }
/*!
* \brief Setter of the class
*/
inline void setNVRays ( int nVRays ) { m_shootingPattern->setNVRays(nVRays); }
/*!
* \brief Setter of the class
*/
inline void setClockWise ( bool clockWise ) { m_shootingPattern->setClockWise(clockWise); }
//***********************************************************************************//
// Virtual/redefined methods from CT_AbstractItemDrawableWithoutPointCloud //
//***********************************************************************************//
/*!
* \brief Method inherited from CT_AbstractItemDrawableWithoutPointCloud that needs to be redefined (pure virtual)
* \return Returns a copy of the itemDrawable with a different id and a different result
*/
virtual CT_Scanner* copy(const CT_OutAbstractItemModel *model,
const CT_AbstractResult *result,
CT_ResultCopyModeList copyModeList);
//********************************************//
// Tools //
//********************************************//
public :
/*!
* \brief Provides access the (ith, jth) beam
*
* \param i : horizontal index of the beam
* \param j : vertical index of the beam
* \param moreStability : if equals true, then direction component close to 0 are set to 0. This avoids some numerical instabilities in some cases.
*
* \return Returns the (ith, jth) beam
*/
CT_Beam* beam ( int i, int j, bool moreStability = false ) const;
/*!
* \brief Provides access the (ith, jth) beam
*
* \param i : horizontal index of the beam
* \param j : vertical index of the beam
* \param moreStability : if equals true, then direction component close to 0 are set to 0. This avoids some numerical instabilities in some cases.
* \param beam : Returns the (ith, jth) beam
*/
void beam ( int i, int j, CT_Beam &beam, bool moreStability = false ) const;
private :
int _scanID; /*!< ID of the scan*/
CT_ThetaPhiShootingPattern* m_shootingPattern;
CT_DEFAULT_IA_BEGIN(CT_Scanner)
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataId(), &CT_Scanner::getScanID, QObject::tr("ScanID"), "sid")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataAngle(), &CT_Scanner::getHFov, QObject::tr("HFov"), "hfov")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataAngle(), &CT_Scanner::getVFov, QObject::tr("VFov"), "vfov")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataResolution(), &CT_Scanner::getHRes, QObject::tr("HRes"), "hres")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataResolution(), &CT_Scanner::getVRes, QObject::tr("VRes"), "vres")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataAngle(), &CT_Scanner::getInitTheta, QObject::tr("InitTheta"), "it")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataAngle(), &CT_Scanner::getInitPhi, QObject::tr("InitPhi"), "ip")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataNumber(), &CT_Scanner::getNHRays, QObject::tr("NHRays"), "nhr")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataNumber(), &CT_Scanner::getNVRays, QObject::tr("NVRays"), "nvr")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataValue(), &CT_Scanner::getClockWise, QObject::tr("ClockWise"), "cw")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataX(), &CT_Scanner::getPositionX, QObject::tr("PositionX"), "px")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataY(), &CT_Scanner::getPositionY, QObject::tr("PositionY"), "py")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataZ(), &CT_Scanner::getPositionZ, QObject::tr("PositionZ"), "pz")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataXDirection(), &CT_Scanner::getZVectorX, QObject::tr("ZVectorX"), "zvx")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataYDirection(), &CT_Scanner::getZVectorY, QObject::tr("ZVectorY"), "zvy")
CT_DEFAULT_IA_V3(CT_Scanner, CT_AbstractCategory::staticInitDataZDirection(), &CT_Scanner::getZVectorZ, QObject::tr("ZVectorZ"), "zvz")
CT_DEFAULT_IA_END(CT_Scanner)
const static CT_StandardScannerDrawManager CT_SCANNER_DRAW_MANAGER;
};
#endif // CT_SCANNER_H