-
Ayomide Bamidele authoredAyomide Bamidele authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Track.h 8.03 KiB
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2007 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source
// & Institut Laue - Langevin
// SPDX - License - Identifier: GPL - 3.0 +
#ifndef MANTID_GEOMETRY_TRACK_H_
#define MANTID_GEOMETRY_TRACK_H_
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidGeometry/DllConfig.h"
#include "MantidGeometry/IComponent.h"
#include "MantidGeometry/Objects/IObject.h"
#include "MantidGeometry/Surfaces/Line.h"
#include "MantidKernel/Tolerance.h"
#include <iosfwd>
#include <list>
namespace Mantid {
//----------------------------------------------------------------------
// Forward Declaration
//----------------------------------------------------------------------
namespace Kernel {
class Logger;
}
namespace Geometry {
/**
\struct Link
\author S. Ansell
\author M. Gigg, Tessella plc
\brief For a leg of a track
*/
struct MANTID_GEOMETRY_DLL Link {
/**
* Constuctor
* @param entry :: Kernel::V3D point to start
* @param exit :: Kernel::V3D point to end track
* @param totalDistance :: Total distance from start of track
* @param obj :: A reference to the object that was intersected
* @param compID :: An optional component identifier for the physical object
* hit. (Default=NULL)
*/
inline Link(const Kernel::V3D &entry, const Kernel::V3D &exit,
const double totalDistance, const IObject &obj,
const ComponentID compID = nullptr)
: entryPoint(entry), exitPoint(exit), distFromStart(totalDistance),
distInsideObject(entryPoint.distance(exitPoint)), object(&obj),
componentID(compID) {}
/// Less than operator
inline bool operator<(const Link &other) const {
return distFromStart < other.distFromStart;
}
/// Less than operator
inline bool operator<(const double &other) const {
return distFromStart < other;
}
/** @name Attributes. */
//@{
Kernel::V3D entryPoint; ///< Entry point
Kernel::V3D exitPoint; ///< Exit point
double distFromStart; ///< Total distance from track beginning
double distInsideObject; ///< Total distance covered inside object
const IObject *object; ///< The object that was intersected
ComponentID componentID; ///< ComponentID of the intersected component
//@}
};
// calculations should prefer throwing a std::domain_error rather than using
// INVALID
enum class TrackDirection { LEAVING = -1, INVALID = 0, ENTERING = 1 };
inline bool operator<(const TrackDirection left, const TrackDirection right) {
return static_cast<int>(left) < static_cast<int>(right);
}
MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &os,
TrackDirection direction);
/**
* Stores a point of intersection along a track. The component intersected
* is linked using its ComponentID.
*
* Ordering for IntersectionPoint is special since we need that when dist is
* close that the +/- flag is taken into account.
*/
struct IntersectionPoint {
/**
* Constuctor
* @param direction :: Indicates the direction of travel of the track with
* respect to the object: +1 is entering, -1 is leaving.
* @param end :: The end point for this partial segment
* @param distFromStartOfTrack :: Total distance from start of track
* @param compID :: An optional unique ID marking the component intersected.
* (Default=NULL)
* @param obj :: A reference to the object that was intersected
*/
inline IntersectionPoint(const TrackDirection direction,
const Kernel::V3D &end,
const double distFromStartOfTrack,
const IObject &obj,
const ComponentID compID = nullptr)
: direction(direction), endPoint(end),
distFromStart(distFromStartOfTrack), object(&obj), componentID(compID) {
}
/**
* A IntersectionPoint is less-than another if either
* (a) the difference in distances is greater than the tolerance and this
*distance is less than the other or
* (b) the distance is less than the other and this point is defined as an
*exit point
*
* @param other :: IntersectionPoint object to compare
* @return True if the object is considered less than, otherwise false.
*/
inline bool operator<(const IntersectionPoint &other) const {
const double diff = fabs(distFromStart - other.distFromStart);
return (diff > Kernel::Tolerance) ? distFromStart < other.distFromStart
: direction < other.direction;
}
/** @name Attributes. */
//@{
TrackDirection direction; ///< Directional flag
Kernel::V3D endPoint; ///< Point
double distFromStart; ///< Total distance from track begin
const IObject *object; ///< The object that was intersected
ComponentID componentID; ///< Unique component ID
//@}
};
/**
* Defines a track as a start point and a direction. Intersections are
* stored as ordered lists of links from the start point to the exit point.
*
* @author S. Ansell
*/
class MANTID_GEOMETRY_DLL Track {
public:
using LType = std::list<Link>;
using PType = std::list<IntersectionPoint>;
public:
/// Default constructor
Track();
/// Constructor
Track(const Kernel::V3D &startPt, const Kernel::V3D &unitVector);
/// Adds a point of intersection to the track
void addPoint(const TrackDirection direction, const Kernel::V3D &endPoint,
const IObject &obj, const ComponentID compID = nullptr);
/// Adds a link to the track
int addLink(const Kernel::V3D &firstPoint, const Kernel::V3D &secondPoint,
const double distanceAlongTrack, const IObject &obj,
const ComponentID compID = nullptr);
/// Remove touching Links that have identical components
void removeCojoins();
/// Construct links between added points
void buildLink();
/// Set a starting point and direction
void reset(const Kernel::V3D &startPoint, const Kernel::V3D &direction);
/// Clear the current set of intersection results
void clearIntersectionResults();
/// Returns the starting point
const Kernel::V3D &startPoint() const { return m_line.getOrigin(); }
/// Returns the direction as a unit vector
const Kernel::V3D &direction() const { return m_line.getDirect(); }
/// Returns an interator to the start of the set of links
LType::iterator begin() { return m_links.begin(); }
/// Returns an interator to one-past-the-end of the set of links
LType::iterator end() { return m_links.end(); }
/// Returns an interator to the start of the set of links (const version)
LType::const_iterator begin() const { return m_links.begin(); }
/// Returns an interator to one-past-the-end of the set of links (const
/// version)
LType::const_iterator end() const { return m_links.end(); }
/// Returns an interator to the start of the set of links (const version)
LType::const_iterator cbegin() const { return m_links.cbegin(); }
/// Returns an interator to one-past-the-end of the set of links (const
/// version)
LType::const_iterator cend() const { return m_links.cend(); }
/// Returns a reference to the first link
LType::reference front() { return m_links.front(); }
/// Returns a reference to the last link
LType::reference back() { return m_links.back(); }
/// Returns a reference to the first link (const version)
LType::const_reference front() const { return m_links.front(); }
/// Returns a reference to the last link (const version)
LType::const_reference back() const { return m_links.back(); }
/// Returns the number of links
int count() const { return static_cast<int>(m_links.size()); }
/// Is the link complete?
int nonComplete() const;
private:
Line m_line; ///< Line object containing origin and direction
LType m_links; ///< Track units
PType m_surfPoints; ///< Intersection points
};
} // NAMESPACE Geometry
} // NAMESPACE Mantid
#endif /*MANTID_GEOMETRY_TRACK_H_*/