Go to the documentation of this file.00001 #include "rgrl_mask_oriented_box.h"
00002
00003
00004
00005 #include <vcl_cassert.h>
00006 #include <vcl_limits.h>
00007 #include <vnl/vnl_transpose.h>
00008
00009
00010
00011 rgrl_mask_oriented_box::
00012 rgrl_mask_oriented_box( unsigned dim )
00013 : rgrl_mask( dim ),
00014 omin_(dim),
00015 omax_(dim),
00016 axes_(dim, dim)
00017 {
00018 }
00019
00020 rgrl_mask_oriented_box::
00021 rgrl_mask_oriented_box( vnl_vector<double> const& x0,
00022 vnl_matrix<double> const& axes,
00023 vnl_vector<double> const& len )
00024 : rgrl_mask( x0.size() ),
00025 axes_( axes )
00026 {
00027 assert( x0.size() == len.size() );
00028 assert( x0.size() == axes.rows());
00029 assert( x0.size() == axes.cols());
00030
00031 omin_ = vnl_transpose( axes ) * x0;
00032 omax_ = omin_;
00033 omax_ += len;
00034
00035 update_bounding_box();
00036 }
00037
00038 rgrl_mask_oriented_box::
00039 rgrl_mask_oriented_box( vnl_vector<double> const& oriented_xmin,
00040 vnl_vector<double> const& oriented_xmax,
00041 vnl_matrix<double> const& axes )
00042 : rgrl_mask( oriented_xmin.size() ),
00043 omin_( oriented_xmin ),
00044 omax_( oriented_xmax ),
00045 axes_( axes )
00046 {
00047 assert( oriented_xmin.size() == oriented_xmax.size() );
00048 assert( oriented_xmin.size() == axes.rows() );
00049 assert( oriented_xmin.size() == axes.cols() );
00050
00051 update_bounding_box();
00052 }
00053
00054 bool
00055 rgrl_mask_oriented_box::
00056 inside( vnl_vector<double> const& pt ) const
00057 {
00058 assert( pt.size() == omin_.size() );
00059
00060 vnl_vector<double> mapped = vnl_transpose( axes_ ) * pt;
00061
00062
00063
00064 bool inside = true;
00065 for ( unsigned i=0; i<omin_.size()&&inside; ++i )
00066 inside = mapped[i] >= omin_[i] && mapped[i] <= omax_[i];
00067
00068 return inside;
00069 }
00070
00071 void
00072 rgrl_mask_oriented_box::
00073 set_len( vnl_vector<double> const& len )
00074 {
00075 assert( len.size() == omin_.size() );
00076 omax_ = omin_ + len;
00077
00078 update_bounding_box();
00079 }
00080
00081 void
00082 rgrl_mask_oriented_box::
00083 set_axes( vnl_matrix<double> const& axes )
00084 {
00085
00086 assert( axes.rows() == axes.cols() );
00087
00088 axes_ = axes;
00089
00090 update_bounding_box();
00091 }
00092
00093
00094 vnl_vector<double>
00095 rgrl_mask_oriented_box::
00096 origin() const
00097 {
00098 return axes_*omin_;
00099 }
00100
00101 void
00102 rgrl_mask_oriented_box::
00103 update_bounding_box()
00104 {
00105 assert( omin_.size() == omax_.size() );
00106 assert( omin_.size() == axes_.rows());
00107 assert( omin_.size() == axes_.cols());
00108
00109 const unsigned int dim = omin_.size();
00110
00111
00112
00113
00114 for ( unsigned i=0; i<dim; ++i )
00115 if ( omin_[i] > omax_[i] ) {
00116
00117
00118 double d = omax_[i];
00119 omax_[i] = omin_[i];
00120 omin_[i] = d;
00121
00122 for ( unsigned j=0; j<dim; ++j )
00123 axes_(j, i) = -axes_(j,i);
00124 }
00125
00126
00127 const unsigned num_corners = 2<<dim;
00128
00129 vnl_vector<double> xmin ( axes_*omin_ );
00130 vnl_vector<double> xmax ( xmin );
00131 vnl_vector<double> oriented_pt, pt;
00132 for ( unsigned i=1; i<num_corners; ++i ) {
00133
00134 oriented_pt = omin_;
00135
00136 for ( unsigned j=0; j<dim; ++j ) {
00137
00138
00139 if ( (i>>j)&0x1 )
00140 oriented_pt[j] = omax_[j];
00141 }
00142
00143 pt = axes_ * oriented_pt;
00144 for ( unsigned j=0; j<dim; ++j ) {
00145 if ( pt[j] < xmin[j] ) xmin[j] = pt[j];
00146 if ( pt[j] > xmax[j] ) xmax[j] = pt[j];
00147 }
00148 }
00149
00150 x0_ = xmin;
00151 x1_ = xmax;
00152 }
00153
00154
00155 double
00156 rgrl_mask_oriented_box::
00157 average_vertices_dist( const rgrl_mask_oriented_box& other ) const
00158 {
00159 if ( omin_.size() != other.omin_.size() )
00160 return vcl_numeric_limits<double>::infinity();
00161
00162 const unsigned int dim = omin_.size();
00163 double cum_dist = 0.0;
00164
00165
00166 const unsigned num_pts = 2<<dim;
00167 vnl_vector<double> pt, other_pt;
00168 for ( unsigned i=0; i<num_pts; ++i ) {
00169
00170 pt = omin_;
00171 other_pt = other.omin_;
00172
00173
00174 for ( unsigned j=0; j<dim; ++j ) {
00175
00176
00177 const bool use_max = ((i>>j)&0x1);
00178 if ( use_max ) {
00179 pt[j] = omax_[j];
00180 other_pt[j] = other.omax_[j];
00181 }
00182 }
00183
00184 cum_dist += (axes_*pt - other.axes()*other_pt).two_norm();
00185 }
00186 return cum_dist/num_pts;
00187 }
00188
00189 bool
00190 rgrl_mask_oriented_box::
00191 operator==( const rgrl_mask_oriented_box& other ) const
00192 {
00193
00194
00195
00196 vnl_matrix<double> prod = vnl_transpose( this->axes_ ) * other.axes_;
00197 vnl_matrix<double> eye( omin_.size(), omin_.size() );
00198 eye.set_identity();
00199 if ( (prod - eye).fro_norm() > 1e-4 ) {
00200 WarningMacro( "Incompatible axes. oriented boxes cannot be compared. " << vcl_endl );
00201 return false;
00202 }
00203
00204
00205
00206 return omin_ == other.omin_ &&
00207 omax_ == other.omax_;
00208 }
00209
00210 bool
00211 rgrl_mask_oriented_box::
00212 operator!=( const rgrl_mask_oriented_box& other ) const
00213 {
00214 return !( *this == other );
00215 }
00216
00217 vcl_ostream& operator<<(vcl_ostream& os, const rgrl_mask_oriented_box& box)
00218 {
00219 os<< box.oriented_x0().size() << " ";
00220 if ( box.oriented_x0().size() ) {
00221 os << box.oriented_x0()<<" "<<box.oriented_x1() << '\n'
00222 << box.axes() << vcl_endl;
00223 }
00224 return os;
00225 }
00226
00227 vcl_istream& operator>>(vcl_istream& is, rgrl_mask_oriented_box& box)
00228 {
00229 int m = -1;
00230 is >> m;
00231
00232 if ( m <= 0 ) return is;
00233
00234 vnl_vector<double> x0(m), x1(m);
00235 is >> x0 >> x1;
00236
00237 vnl_matrix<double> axes(m, m);
00238 is >> axes;
00239
00240 rgrl_mask_oriented_box temp_box( x0, x1, axes );
00241 box = temp_box;
00242 return is;
00243 }
00244