1 // This is core/vpgl/algo/vpgl_ray.h
2 #ifndef vpgl_ray_h_
3 #define vpgl_ray_h_
4 //:
5 // \file
6 // \brief Methods for computing the camera ray direction at a given 3-d point and other operations on camera rays
7 // \author J. L. Mundy
8 // \date Dec 22, 2007
9 
10 #include <vpgl/vpgl_rational_camera.h>
11 #include <vgl/algo/vgl_rotation_3d.h>
12 #include <vpgl/vpgl_local_rational_camera.h>
13 #include <vpgl/vpgl_perspective_camera.h>
14 #include <vpgl/vpgl_proj_camera.h>
15 #include <vpgl/vpgl_affine_camera.h>
16 #include <vpgl/vpgl_generic_camera.h>
17 #include <vnl/vnl_double_3.h>
18 #include <vgl/vgl_point_3d.h>
19 #include <vgl/vgl_vector_3d.h>
20 #include <vgl/vgl_ray_3d.h>
21 
22 class vpgl_ray
23 {
24  public:
25   //: Generic camera interfaces (pointer for abstract class)
26   // Solves using back-project so will work for any camera
27   // The ray direction assumes the camera is in the positive half-space
28   // of the x-y plane. This assumption is necessary since some cameras
29   // don't have a natural center of projection (e.g. rational cameras).
30 
31        // === vnl interface ===
32 
33   //: compute the ray at a given 3-d point
34   static  bool ray(const vpgl_camera<double>* cam,
35                    vnl_double_3 const& point_3d,
36                    vnl_double_3& ray);
37 
38        // === vgl interface ===
39 
40   //: compute the ray at a given 3-d point
41   static bool ray(const vpgl_camera<double>*  cam,
42                   vgl_point_3d<double> const& point_3d,
43                   vgl_vector_3d<double>& ray);
44 
45   //: vgl interface, origin_z defines an x-y plane wherein lies the ray origin
46   static bool ray(const vpgl_camera<double>*  cam,
47                   vgl_point_3d<double> const& point_3d,
48                   double origin_z,
49                   vgl_ray_3d<double>& ray);
50 
51   //: vgl interface, origin_z defines an x-y plane wherein lies the ray origin
52   //  and dz defines a plane to compute a second intersection point for the ray direction
53   // the inital guess is for the x and y values where the ray intersects the z planes
54   static bool ray(const vpgl_camera<double>*  cam,
55                   vgl_point_2d<double> image_pt,
56                   vgl_point_2d<double> const& inital_guess,
57                   double origin_z, double dz,
58                   vgl_ray_3d<double>& ray);
59 
60   // +++ concrete rational camera interfaces +++
61 
62        // === vnl interface ===
63 
64   //: compute the ray at a given 3-d point
65   static bool ray(vpgl_rational_camera<double> const& rcam,
66                   vnl_double_3 const& point_3d,
67                   vnl_double_3& ray);
68 
69        // === vgl interface ===
70 
71   //: compute the ray at a given 3-d point
72   static bool ray(vpgl_rational_camera<double> const& rcam,
73                   vgl_point_3d<double> const& point_3d,
74                   vgl_vector_3d<double>& ray);
75 
76   //: compute the ray at a given 3-d point
77   static bool ray(vpgl_rational_camera<double> const& rcam,
78                   vgl_point_3d<double> const& point_3d,
79                   vgl_ray_3d<double>& ray);
80 
81   //: compute a ray in local Cartesian coordinates at a given (u, v)
82   static bool ray(vpgl_local_rational_camera<double> const& lrcam,
83                   const double u, const double v,
84                   vgl_point_3d<double>& origin, vgl_vector_3d<double>& dir);
85 
86   //: compute a ray in local Cartesian coordinates at a given (u, v)
87   static bool ray(vpgl_local_rational_camera<double> const& lrcam,
88                   const double u, const double v,
89                   vgl_ray_3d<double>& ray);
90 
91   //: compute a ray in local Cartesian coordinates for a local rational cam
92   static bool plane_ray(vpgl_local_rational_camera<double> const& lrcam,
93                         const vgl_point_2d<double> image_point1,
94                         const vgl_point_2d<double> image_point2,
95                         vgl_plane_3d<double>& plane);
96   // ====== projective camera =====
97   static bool ray(vpgl_proj_camera<double> const& cam,
98                   vgl_point_3d<double> const& world_pt,
99                   vgl_ray_3d<double>& ray);
100 
101   static bool principal_ray(vpgl_proj_camera<double> const& cam,
102                             vgl_ray_3d<double>& pray);
103 
104  // ====== affine camera =====
105   static bool ray(vpgl_affine_camera<double> const& cam,
106                   vgl_point_3d<double> const& world_pt,
107                   vgl_ray_3d<double>& ray);
108 
109 
110 
111   // ====== perspective camera =====
112   static bool ray(vpgl_perspective_camera<double> const& cam,
113                   vgl_point_3d<double> const& world_pt,
114                   vgl_ray_3d<double>& ray);
115 
principal_ray(vpgl_perspective_camera<double> const & cam,vgl_ray_3d<double> & pray)116   static bool principal_ray(vpgl_perspective_camera<double> const& cam,
117                             vgl_ray_3d<double>& pray) {
118     vpgl_proj_camera<double> const* procam =
119       static_cast<vpgl_proj_camera<double> const* >(&cam);
120     return  vpgl_ray::principal_ray(*procam, pray);
121   }
122 
123   // ====== generic camera =====
124   static bool ray(vpgl_generic_camera<double> const& cam,
125                   vgl_point_3d<double> const& world_pt,
126                   vgl_ray_3d<double>& ray);
127 
128 
129   // ====== operations on rotation matrices with respect to camera rays ======
130 
131     //: angle(radians) between principal ray of one rotation and the principal ray of a second rotation
132   // Rotations \p r0 and \p r1 are expressed as vgl_rotation<T>
133   static double angle_between_rays(vgl_rotation_3d<double> const& r0, vgl_rotation_3d<double> const& r1);
134 
135   //: the rotation about the principal ray required to go from \p r0 to \p r1
136   static double rot_about_ray(vgl_rotation_3d<double> const& r0, vgl_rotation_3d<double> const& r1);
137 
138   //: the rotation required to point the principal ray in a given direction, starting with the identity camera (principal ray in z direction)
139   static vgl_rotation_3d<double> rot_to_point_ray(vgl_vector_3d<double> const& ray_dir);
140   //: define the principal ray in spherical coordinates (in degrees, azimuth [0 360], elevation [0, 180], x axis = (0, 90), y axis = (90, 90, z axis = (0, 0)).
141   static vgl_rotation_3d<double> rot_to_point_ray(double azimuth, double elevation);
142  private:
143   //: constructor/destructor private - static methods only
144   vpgl_ray() = delete;
145   ~vpgl_ray() = delete;
146 };
147 
148 #endif // vpgl_ray_h_
149