contrib/oxl/mvl/AffineMetric.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/AffineMetric.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 
00008 #include "AffineMetric.h"
00009 
00010 #include <vcl_iostream.h>
00011 #include <vcl_cassert.h>
00012 
00013 #include <vnl/vnl_inverse.h>
00014 
00015 #include <vgl/vgl_point_2d.h>
00016 #include <vgl/vgl_homg_point_2d.h>
00017 #include <mvl/HomgPoint2D.h>
00018 
00019 #include <vgl/algo/vgl_homg_operators_2d.h> // for matrix * point
00020 
00021 //: Construct and AffineMetric from the matrix A.
00022 // The last row of A should be (0,0,lambda).
00023 AffineMetric::AffineMetric()
00024 {
00025   A_.set_identity();
00026   A_inverse_.set_identity();
00027 }
00028 
00029 
00030 //: Construct and AffineMetric from the 3x3 matrix A.
00031 // The last row of A should be (0,0,lambda).
00032 AffineMetric::AffineMetric(vnl_matrix_fixed<double,3,3> const& A):
00033   A_(A),
00034   A_inverse_(vnl_inverse(A))
00035 {
00036   assert(A(2,0) == 0);
00037   assert(A(2,1) == 0);
00038 }
00039 
00040 void AffineMetric::set(vnl_matrix_fixed<double,3,3> const& A)
00041 {
00042   A_ = A;
00043   A_inverse_ = vnl_inverse(A);
00044   assert(A(2,0) == 0);
00045   assert(A(2,1) == 0);
00046 }
00047 
00048 //: set [a11  0 a13; 0 a22 a23; 0 0 a33]
00049 void AffineMetric::set(double a11, double a13,
00050                        double a22, double a23,
00051                        double a33)
00052 {
00053   A_(0,0) = a11;
00054   A_(0,1) =   0;
00055   A_(0,2) = a13;
00056   A_(1,0) =   0;
00057   A_(1,1) = a22;
00058   A_(1,2) = a23;
00059   A_(2,0) =   0;
00060   A_(2,1) =   0;
00061   A_(2,2) = a33;
00062 
00063   A_inverse_ = vnl_inverse(A_);
00064 }
00065 
00066 // == Implementation of AffineMetric ==
00067 
00068 //: Convert homogeneous point in conditioned coordinates to one in image coordinates
00069 vgl_homg_point_2d<double> AffineMetric::homg_to_imagehomg(vgl_homg_point_2d<double> const& p) const
00070 {
00071   return A_ * p;
00072 }
00073 
00074 //: Transform p
00075 HomgPoint2D AffineMetric::homg_to_imagehomg(const HomgPoint2D& p) const
00076 {
00077    return HomgPoint2D(A_ * p.get_vector());
00078 }
00079 
00080 //: Inverse-transform p
00081 vgl_homg_point_2d<double> AffineMetric::imagehomg_to_homg(vgl_homg_point_2d<double> const& p) const
00082 {
00083   return A_inverse_ * p;
00084 }
00085 
00086 //: Inverse-transform p
00087 HomgPoint2D AffineMetric::imagehomg_to_homg(const HomgPoint2D& p) const
00088 {
00089   return HomgPoint2D(A_inverse_ * p.get_vector());
00090 }
00091 
00092 vgl_homg_point_2d<double> AffineMetric::image_to_homg(vgl_point_2d<double> const& p) const
00093 {
00094   const vnl_double_3x3& a = A_inverse_;
00095   double h1 = a[0][0] * p.x() + a[0][1] * p.y() + a[0][2];
00096   double h2 = a[1][0] * p.x() + a[1][1] * p.y() + a[1][2];
00097   double h3 = a[2][0] * p.x() + a[2][1] * p.y() + a[2][2];
00098 
00099   return vgl_homg_point_2d<double>(h1, h2, h3);
00100 }
00101 
00102 HomgPoint2D AffineMetric::image_to_homg(double x, double y) const
00103 {
00104   const vnl_double_3x3& a = A_inverse_;
00105   double h1 = a[0][0] * x + a[0][1] * y + a[0][2];
00106   double h2 = a[1][0] * x + a[1][1] * y + a[1][2];
00107   double h3 = a[2][0] * x + a[2][1] * y + a[2][2];
00108 
00109   return HomgPoint2D(h1, h2, h3);
00110 }
00111 
00112 HomgPoint2D AffineMetric::image_to_homg(const vnl_double_2& p) const
00113 {
00114   return image_to_homg(p[0], p[1]);
00115 }
00116 
00117 //: Convert conditioned point p to image coordinates
00118 vgl_point_2d<double> AffineMetric::homg_to_image(vgl_homg_point_2d<double> const& p) const
00119 {
00120   return A_ * p;
00121 }
00122 
00123 //: Convert conditioned point p to image coordinates
00124 vnl_double_2 AffineMetric::homg_to_image(const HomgPoint2D& p) const
00125 {
00126   vnl_double_3 x = A_ * p.get_vector();
00127   double s = 1/x[2];
00128 
00129   return vnl_double_2(x[0] * s, x[1] * s);
00130 }
00131 
00132 //: print to vcl_ostream
00133 vcl_ostream& AffineMetric::print(vcl_ostream& s) const
00134 {
00135   return s << "AffineMetric ["
00136            << A_.get_row(0) << ';'
00137            << A_.get_row(1) << ';'
00138            << A_.get_row(2) << ']';
00139 }