contrib/gel/mrc/vpgl/algo/vpgl_ray.cxx
Go to the documentation of this file.
00001 // This is gel/mrc/vpgl/algo/vpgl_ray.cxx
00002 #include "vpgl_ray.h"
00003 //
00004 #include <vnl/vnl_double_2.h>
00005 #include <vnl/vnl_double_3.h>
00006 #include <vnl/vnl_double_4.h>
00007 #include <vgl/vgl_point_3d.h>
00008 #include <vgl/vgl_vector_3d.h>
00009 #include <vgl/vgl_plane_3d.h>
00010 #include <vpgl/algo/vpgl_invmap_cost_function.h>
00011 #include "vpgl_backproject.h"
00012 
00013 bool vpgl_ray::ray(const vpgl_camera<double>* cam,
00014                    vnl_double_3 const& point_3d,
00015                    vnl_double_3& r)
00016 {
00017   //create an image point
00018   double u, v;
00019   cam->project(point_3d[0], point_3d[1], point_3d[2], u, v);
00020   vnl_double_2 image_point(u, v);
00021 
00022   //construct a shifted plane by 1 unit in - z direction
00023   vnl_double_4 plane(0, 0, 1.0, -point_3d[2]+ 1.0);
00024 
00025   //backproject onto the shifted plane
00026   vnl_double_3 shifted_point;
00027 
00028   if (!vpgl_backproject::bproj_plane(cam, image_point, plane, point_3d,
00029                                      shifted_point))
00030     return false;
00031   //The ray direction is just the difference
00032   r = shifted_point - point_3d;
00033   r.normalize();
00034   return true;
00035 }
00036 
00037 bool vpgl_ray::ray(const vpgl_camera<double>*  cam,
00038                    vgl_point_3d<double> const& point_3d,
00039                    vgl_vector_3d<double>& r)
00040 {
00041   vnl_double_3 p3d(point_3d.x(), point_3d.y(), point_3d.z());
00042   vnl_double_3 tr;
00043   bool success = vpgl_ray::ray(cam, p3d, tr);
00044   if (!success) return false;
00045   r.set(tr[0], tr[1], tr[2]);
00046   return true;
00047 }
00048 
00049 bool vpgl_ray::ray(vpgl_rational_camera<double> const& rcam,
00050                    vnl_double_3 const& point_3d,
00051                    vnl_double_3& ray)
00052 {
00053     const vpgl_camera<double>*  cam =
00054       static_cast<const vpgl_camera<double>* >(&rcam);
00055     return vpgl_ray::ray(cam, point_3d, ray);
00056 }
00057 
00058 bool vpgl_ray::ray(vpgl_rational_camera<double> const& rcam,
00059                    vgl_point_3d<double> const& point_3d,
00060                    vgl_vector_3d<double>& ray)
00061 {
00062     const vpgl_camera<double>*  cam =
00063       static_cast<const vpgl_camera<double>* >(&rcam);
00064 
00065     return vpgl_ray::ray(cam, point_3d, ray);
00066 }
00067 
00068 // compute a ray in local Cartesian coordinates for a local rational cam
00069 bool vpgl_ray::ray(vpgl_local_rational_camera<double> const& lrcam,
00070                    const double u, const double v,
00071                    vgl_point_3d<double>& origin,
00072                    vgl_vector_3d<double>& dir)
00073 {
00074   // find the horizontal plane at the top of the 3-d region
00075   // of valid RPC projection
00076   double z_off = lrcam.offset(vpgl_rational_camera<double>::Z_INDX);
00077   double z_scale = lrcam.scale(vpgl_rational_camera<double>::Z_INDX);
00078   double zmax = z_off + z_scale;
00079 
00080   // find the point of intersection of the back-projected ray with zmax
00081   vgl_plane_3d<double> top_plane(0.0, 0.0, 1.0, -zmax);
00082   vgl_point_2d<double> image_point(u, v);
00083   vgl_point_3d<double> initial_guess(0.0, 0.0, zmax);
00084   vpgl_local_rational_camera<double>* lrcam_ptr =
00085     const_cast<vpgl_local_rational_camera<double>*>(&lrcam);
00086   vpgl_camera<double>* cam = static_cast<vpgl_camera<double>*>(lrcam_ptr);
00087   if (!vpgl_backproject::bproj_plane(cam, image_point, top_plane,
00088                                      initial_guess, origin))
00089     return false;
00090 
00091   // find the point of intersection of the back-projected ray with the
00092   // plane at mid elevation.
00093   //
00094   vgl_plane_3d<double> mid_plane(0.0, 0.0, 1.0, -z_off);
00095   vgl_point_3d<double> mid_initial_guess(0.0, 0.0, z_off), mid_point;
00096   if (!vpgl_backproject::bproj_plane(cam, image_point, mid_plane,
00097                                      mid_initial_guess, mid_point))
00098     return false;
00099 
00100   dir = mid_point - origin;
00101   dir/=dir.length();//unit vector
00102 
00103   return true;
00104 }
00105 // compute a ray in local Cartesian coordinates for a local rational cam
00106 bool vpgl_ray::plane_ray(vpgl_local_rational_camera<double> const& lrcam,
00107                    const vgl_point_2d<double> image_point1,
00108                    const vgl_point_2d<double> image_point2,
00109                    vgl_plane_3d<double>& plane)
00110 {
00111   // find the horizontal plane at the top of the 3-d region
00112   // of valid RPC projection
00113   double z_off = lrcam.offset(vpgl_rational_camera<double>::Z_INDX);
00114   double z_scale = lrcam.scale(vpgl_rational_camera<double>::Z_INDX);
00115   double zmax = z_off + z_scale;
00116 
00117   // find the point of intersection of the back-projected ray with zmax
00118   vgl_plane_3d<double> top_plane(0.0, 0.0, 1.0, -zmax);
00119   //vgl_point_2d<double> image_point(u, v);
00120   vgl_point_3d<double> initial_guess(0.0, 0.0, zmax);
00121   vgl_point_3d<double> point1,point2;
00122   vpgl_local_rational_camera<double>* lrcam_ptr =
00123     const_cast<vpgl_local_rational_camera<double>*>(&lrcam);
00124   vpgl_camera<double>* cam = static_cast<vpgl_camera<double>*>(lrcam_ptr);
00125   if (!vpgl_backproject::bproj_plane(cam, image_point1, top_plane,
00126                                      initial_guess, point1))
00127     return false;
00128   if (!vpgl_backproject::bproj_plane(cam, image_point2, top_plane,
00129                                      initial_guess, point2))
00130     return false;
00131 
00132   // find the point of intersection of the back-projected ray with the
00133   // plane at mid elevation.
00134   //
00135   vgl_plane_3d<double> mid_plane(0.0, 0.0, 1.0, -z_off);
00136   vgl_point_3d<double> mid_initial_guess(0.0, 0.0, z_off), mid_point1;
00137   if (!vpgl_backproject::bproj_plane(cam, image_point1, mid_plane,
00138                                      mid_initial_guess, mid_point1))
00139     return false;
00140 
00141   plane=vgl_plane_3d<double>(point1,point2,mid_point1);
00142 
00143   return true;
00144 }