/**************************************************************************** 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 . *****************************************************************************/ #include "ct_scanner.h" #ifdef _MSC_VER #define _USE_MATH_DEFINES #include #endif CT_DEFAULT_IA_INIT(CT_Scanner) // Initializing the draw manager const CT_StandardScannerDrawManager CT_Scanner::CT_SCANNER_DRAW_MANAGER; CT_Scanner::CT_Scanner(int scanID, bool clockWise) : CT_AbstractItemDrawableWithoutPointCloud() { _scanID = scanID; setCenterX(0); setCenterY(0); setCenterZ(0); m_shootingPattern = new CT_ThetaPhiShootingPattern(Eigen::Vector3d(0,0,0), 0, 0, 0, 0, 0, 0, Eigen::Vector3d(0,0,1), clockWise); setBaseDrawManager(&CT_SCANNER_DRAW_MANAGER); } CT_Scanner::CT_Scanner(const CT_OutAbstractSingularItemModel *model, const CT_AbstractResult *result, int scanId, bool clockWise) : CT_AbstractItemDrawableWithoutPointCloud (model, result ) { _scanID = scanId; setCenterX(0); setCenterY(0); setCenterZ(0); m_shootingPattern = new CT_ThetaPhiShootingPattern(Eigen::Vector3d(0,0,0), 0, 0, 0, 0, 0, 0, Eigen::Vector3d(0,0,1), clockWise); setBaseDrawManager(&CT_SCANNER_DRAW_MANAGER); } CT_Scanner::CT_Scanner(const CT_OutAbstractSingularItemModel *model, const CT_AbstractResult *result, int scanID, const Eigen::Vector3d &origin, const Eigen::Vector3d &zVector, double hFov, double vFov, double hRes, double vRes, double initTheta, double initPhi, bool clockWise, bool radians) : CT_AbstractItemDrawableWithoutPointCloud (model, result ) { _scanID = scanID; setCenterX(origin.x()); setCenterY(origin.y()); setCenterZ(origin.z()); m_shootingPattern = new CT_ThetaPhiShootingPattern(Eigen::Vector3d(0,0,0), hFov, vFov, hRes, vRes, initTheta, initPhi, zVector, clockWise, radians); setBaseDrawManager(&CT_SCANNER_DRAW_MANAGER); } CT_Scanner::CT_Scanner(const QString &modelName, const CT_AbstractResult *result, int scanId, bool clockWise) : CT_AbstractItemDrawableWithoutPointCloud (modelName, result ) { _scanID = scanId; setCenterX(0); setCenterY(0); setCenterZ(0); m_shootingPattern = new CT_ThetaPhiShootingPattern(Eigen::Vector3d(0,0,0), 0, 0, 0, 0, 0, 0, Eigen::Vector3d(0,0,1), clockWise); setBaseDrawManager(&CT_SCANNER_DRAW_MANAGER); } CT_Scanner::CT_Scanner(const QString &modelName, const CT_AbstractResult *result, int scanID, const Eigen::Vector3d &origin, const Eigen::Vector3d &zVector, double hFov, double vFov, double hRes, double vRes, double initTheta, double initPhi, bool clockWise, bool radians) : CT_AbstractItemDrawableWithoutPointCloud (modelName, result ) { _scanID = scanID; setCenterX(origin(0)); setCenterY(origin(1)); setCenterZ(origin(2)); m_shootingPattern = new CT_ThetaPhiShootingPattern(Eigen::Vector3d(0,0,0), hFov, vFov, hRes, vRes, initTheta, initPhi, zVector, clockWise, radians); setBaseDrawManager(&CT_SCANNER_DRAW_MANAGER); } CT_Scanner::~CT_Scanner() { delete m_shootingPattern; } CT_ShootingPattern* CT_Scanner::getShootingPattern() const { return m_shootingPattern; } CT_Beam *CT_Scanner::beam(int i, int j, bool moreStability) const { assert ( i >= 0 && j >= 0 ); assert ( i <= getNHRays() && j <= getNVRays() ); double theta = getInitTheta() + (i * getHRes()); double phi = getInitPhi() + (j * getVRes()); // If clockwise, then real theta equals opposite to initial if ( getClockWise() ) { theta *= -1; } // The direction is calculated using spherical coordinates, the origin is the scaning position double sinPhi = sin( phi ); double cosPhi = cos ( phi ); double sinTheta = sin ( theta ); double cosTheta = cos ( theta ); Eigen::Vector3d direction; if ( moreStability ) { // We avoid too small numbers that leads to numerical instability fabs(sinPhi*cosTheta) > SCANNER_EPSILON ? direction(0) = sinPhi*cosTheta : direction(0) = 0; fabs(sinPhi*sinTheta) > SCANNER_EPSILON ? direction(1) = sinPhi*sinTheta : direction(1) = 0; fabs(cosPhi) > SCANNER_EPSILON ? direction(2) = cosPhi : direction(2) = 0; } else { direction(0) = sinPhi*cosTheta; direction(1) = sinPhi*sinTheta; direction(2) = cosPhi; } return new CT_Beam(NULL, NULL, getCenterCoordinate(), direction); } void CT_Scanner::beam(int i, int j, CT_Beam &beam, bool moreStability) const { assert ( i >= 0 && j >= 0 ); assert ( i <= getNHRays() && j <= getNVRays() ); double theta = getInitTheta() + (i * getHRes()); double phi = getInitPhi() + (j * getVRes()); // If clockwise, then real theta equals opposite to initial if ( getClockWise() ) { theta *= -1; } // The direction is calculated using spherical coordinates, the origin is the scaning position double sinPhi = sin( phi ); double cosPhi = cos ( phi ); double sinTheta = sin ( theta ); double cosTheta = cos ( theta ); Eigen::Vector3d direction; if ( moreStability ) { // We avoid too small numbers that leads to numerical instability fabs(sinPhi*cosTheta) > SCANNER_EPSILON ? direction(0) = sinPhi*cosTheta : direction(0) = 0; fabs(sinPhi*sinTheta) > SCANNER_EPSILON ? direction(1) = sinPhi*sinTheta : direction(1) = 0; fabs(cosPhi) > SCANNER_EPSILON ? direction(2) = cosPhi : direction(2) = 0; } else { direction(0) = sinPhi*cosTheta; direction(1) = sinPhi*sinTheta; direction(2) = cosPhi; } beam.setOrigin(getCenterCoordinate()); beam.setDirection(direction); } CT_Scanner* CT_Scanner::copy(const CT_OutAbstractItemModel *model, const CT_AbstractResult *result, CT_ResultCopyModeList copyModeList) { CT_Scanner *sc = new CT_Scanner((const CT_OutAbstractSingularItemModel *)model, result, getScanID(), getPosition(), getZVector(), getHFov(), getVFov(), getHRes(), getVRes(), getInitTheta(), getInitPhi(), getClockWise()); sc->setId(id()); sc->setAlternativeDrawManager(getAlternativeDrawManager()); return sc; }