/**************************************************************************** Copyright (C) 2012-2012 Universite de Sherbrooke, Quebec, CANADA All rights reserved. Contact : richard.fournier@usherbrooke.ca jean-francois.cote@nrcan-rncan.gc.ca joris.ravaglia@gmail.com Developers : Joris RAVAGLIA Adapted by Alexandre Piboule for Computree 2.0 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_beam.h" #include const CT_StandardBeamDrawManager CT_Beam::BEAM_DRAW_MANAGER; CT_TYPE_IMPL_INIT_MACRO(CT_Beam) CT_Beam::CT_Beam() : SuperClass(), m_shot(CT_Shot(true)) { setCenterX(0); setCenterY(0); setCenterZ(0); setBaseDrawManager(&BEAM_DRAW_MANAGER); } CT_Beam::CT_Beam(const Eigen::Vector3d& origin, const Eigen::Vector3d& direction) : SuperClass(), m_shot(origin, direction.normalized()) { Q_ASSERT( !(direction(0) == 0 && direction(1) == 0 && direction(2) == 0) ); if (direction(0) == 0 && direction(1) == 0 && direction(2) == 0) {qDebug() << "CT_Beam::CT_Beam" << ", " << "direction(0) == 0 && direction(1) == 0 && direction(2) == 0";} setCenterCoordinate(origin); setBaseDrawManager(&BEAM_DRAW_MANAGER); } bool CT_Beam::intersect(const Eigen::Vector3d& bot, const Eigen::Vector3d& top, Eigen::Vector3d &nearP, Eigen::Vector3d &farP) const { double t0 = 0; double t1 = std::numeric_limits::max(); if (!updateIntervals(bot(0), top(0), m_shot.origin()(0), m_shot.direction()(0), t0, t1)) {return false;} if (!updateIntervals(bot(1), top(1), m_shot.origin()(1), m_shot.direction()(1), t0, t1)) {return false;} if (!updateIntervals(bot(2), top(2), m_shot.origin()(2), m_shot.direction()(2), t0, t1)) {return false;} nearP = m_shot.origin() + m_shot.direction()*t0; farP = m_shot.origin() + m_shot.direction()*t1; return true; } bool CT_Beam::intersect(const Eigen::Vector3d& bot, const Eigen::Vector3d& top) const { double t0 = 0; double t1 = std::numeric_limits::max(); if (!updateIntervals(bot(0), top(0), m_shot.origin()(0), m_shot.direction()(0), t0, t1)) {return false;} if (!updateIntervals(bot(1), top(1), m_shot.origin()(1), m_shot.direction()(1), t0, t1)) {return false;} if (!updateIntervals(bot(2), top(2), m_shot.origin()(2), m_shot.direction()(2), t0, t1)) {return false;} return true; } bool CT_Beam::updateIntervals(const double &bot, const double &top, const double &origin, const double &direction, double &t0, double &t1) const { // Update interval for bounding box slab double invRayDir = 1.f / direction; double tNear = (bot - origin) * invRayDir; double tFar = (top - origin) * invRayDir; // Update parametric interval from slab intersection $t$s if (tNear > tFar) std::swap(tNear, tFar); t0 = tNear > t0 ? tNear : t0; t1 = tFar < t1 ? tFar : t1; if (t0 > t1 && t0 - t1 > EPSILON_INTERSECTION_RAY ) // t0 being always > t1, (t0-t1) is always positive { return false; } return true; }