1 // This is core/vgl/vgl_ray_3d.h
2 #ifndef vgl_ray_3d_h_
3 #define vgl_ray_3d_h_
4 //:
5 // \file
6 // \brief A 3-d ray defined by an origin and a direction vector
7 // \author  J.L. Mundy
8 //
9 // \verbatim
10 // Modifications
11 // Initial version Sept. 17,  2010
12 // \endverbatim
13 
14 #include <iosfwd>
15 #ifdef _MSC_VER
16 #  include <vcl_msvc_warnings.h>
17 #endif
18 #include "vgl_vector_3d.h"
19 #include "vgl_point_3d.h"
20 #include "vgl_line_segment_3d.h"
21 #include "vgl_line_3d_2_points.h"
22 
23 //: Represents a 3-d ray
24 //  The ray origin is p0 and the direction is t_.
25 
26 template <class Type>
27 class vgl_ray_3d
28 {
29   vgl_point_3d<Type> p0_; //!< The ray origin
30   vgl_vector_3d<Type> t_;  //!< ray direction vector
31  public:
32   //: Default constructor - does not initialise!
33   inline vgl_ray_3d() = default;
34 
35   //: Copy constructor
vgl_ray_3d(vgl_ray_3d<Type> const & l)36   inline vgl_ray_3d(vgl_ray_3d<Type> const& l)
37     : p0_(l.origin()), t_(l.direction()) {}
38 
39   //: Construct from orign and direction
vgl_ray_3d(vgl_point_3d<Type> const & p0,vgl_vector_3d<Type> const & direction)40   inline vgl_ray_3d(vgl_point_3d<Type> const& p0,
41                     vgl_vector_3d<Type> const& direction)
42     : p0_(p0), t_(direction) {t_ = t_/static_cast<Type>(t_.length());}
43 
44   //: Construct from two points
vgl_ray_3d(vgl_point_3d<Type> const & origin,vgl_point_3d<Type> const & p)45   inline vgl_ray_3d(vgl_point_3d<Type> const& origin,
46                     vgl_point_3d<Type> const& p)
47     : p0_(origin), t_(p-origin) {t_ = t_/static_cast<Type>(t_.length());}
48   //: Construct from a line segment, direction from 1 to 2
vgl_ray_3d(vgl_line_segment_3d<Type> const & ls)49   inline vgl_ray_3d(vgl_line_segment_3d<Type> const& ls)
50   {
51     p0_ = ls.point1(); t_ = ls.point2()-p0_;
52     t_ = t_/static_cast<Type>(t_.length());
53   }
54 
55   //: Construct from a line 2 points direction from 1 to 2
vgl_ray_3d(vgl_line_3d_2_points<Type> const & ls)56   inline vgl_ray_3d(vgl_line_3d_2_points<Type> const& ls)
57   {
58     p0_ = ls.point1(); t_ = ls.point2()-p0_;
59     t_ = t_/static_cast<Type>(t_.length());
60   }
61 
62   //: Destructor
63   inline ~vgl_ray_3d() = default;
64 
65   //: Accessors
origin()66   inline vgl_point_3d<Type> origin() const { return p0_; } // return a copy
67 
direction()68   inline vgl_vector_3d<Type> direction() const
69   { return t_/static_cast<Type>(t_.length()); } // return a copy
70 
71   //: The comparison operator
72   inline bool operator==(vgl_ray_3d<Type> const& r) const
73   { return (this==&r)||(direction()==r.direction() && origin()==r.origin());}
74 
75   inline bool operator!=(vgl_ray_3d<Type>const& other) const
76   { return !operator==(other); }
77 
78   //: Assignment
set(vgl_point_3d<Type> const & p0,vgl_vector_3d<Type> const & direction)79   inline void set(vgl_point_3d<Type> const& p0, vgl_vector_3d<Type> const& direction)
80   {
81     p0_ = p0; t_ = direction;
82     t_=t_/static_cast<Type>(t_.length());
83   }
84 
85   //: Check if point \a p is on the ray and lies in the positive ray direction
86   bool contains(const vgl_point_3d<Type>& p ) const;
87 
88 };
89 
90 //: Write to stream
91 // \relatesalso vgl_ray_3d
92 template <class Type>
93 std::ostream&  operator<<(std::ostream& s, const vgl_ray_3d<Type>& p);
94 
95 //: Read from stream
96 // \relatesalso vgl_ray_3d
97 template <class Type>
98 std::istream&  operator>>(std::istream& is,  vgl_ray_3d<Type>& p);
99 //: public functions
100 template <class Type>
101 //: angle between rays
angle(vgl_ray_3d<Type> const & r0,vgl_ray_3d<Type> const & r1)102 double angle(vgl_ray_3d<Type> const& r0, vgl_ray_3d<Type> const& r1)
103 {
104   return angle(r0.direction(), r1.direction());
105 }
106 #define VGL_RAY_3D_INSTANTIATE(T) extern "please include vgl/vgl_ray_3d.hxx first"
107 
108 #endif // vgl_ray_3d_h_
109