#ifndef MSP_GEOMETRY_RAY_H_
#define MSP_GEOMETRY_RAY_H_
+#include <stdexcept>
#include <msp/linal/vector.h>
namespace Msp {
namespace Geometry {
+/**
+A directed line segment. Can be used to point at things.
+*/
template<typename T, unsigned D>
class Ray
{
private:
LinAl::Vector<T, D> start;
LinAl::Vector<T, D> direction;
+ T limit;
public:
Ray();
Ray(const LinAl::Vector<T, D> &, const LinAl::Vector<T, D> &);
+ Ray(const LinAl::Vector<T, D> &, const LinAl::Vector<T, D> &, T);
const LinAl::Vector<T, D> &get_start() const { return start; }
const LinAl::Vector<T, D> &get_direction() const { return direction; }
+ T get_limit() const { return limit; }
+ bool check_limits(T) const;
};
template<typename T, unsigned D>
-Ray<T, D>::Ray()
+inline Ray<T, D>::Ray():
+ limit(0)
{
- direction[0] = 1;
+ direction[0] = T(1);
}
template<typename T, unsigned D>
-Ray<T, D>::Ray(const LinAl::Vector<T, D> &s, const LinAl::Vector<T, D> &d):
+inline Ray<T, D>::Ray(const LinAl::Vector<T, D> &s, const LinAl::Vector<T, D> &d):
start(s),
- direction(normalize(d))
+ direction(normalize(d)),
+ limit(0)
{ }
+template<typename T, unsigned D>
+inline Ray<T, D>::Ray(const LinAl::Vector<T, D> &s, const LinAl::Vector<T, D> &d, T l):
+ start(s),
+ direction(normalize(d)),
+ limit(l)
+{
+ if(l<T(0))
+ throw std::invalid_argument("Ray::Ray");
+}
+
+template<typename T, unsigned D>
+inline bool Ray<T, D>::check_limits(T x) const
+{
+ return x>=T(0) && (!limit || x<=limit);
+}
+
} // namespace Geometry
} // namespace Msp