Go to the documentation of this file.00001
00002 #include "vsol_line_2d.h"
00003
00004
00005 #include <vcl_cassert.h>
00006 #include <vcl_cmath.h>
00007 #include <vcl_iostream.h>
00008 #include <vnl/vnl_math.h>
00009 #include <vbl/io/vbl_io_smart_ptr.h>
00010 #include <vsol/vsol_point_2d.h>
00011 #include <vgl/vgl_homg_point_2d.h>
00012 #include <vgl/vgl_vector_2d.h>
00013 #include <vgl/vgl_homg_line_2d.h>
00014 #include <vgl/vgl_line_segment_2d.h>
00015 #include <vgl/vgl_point_2d.h>
00016
00017
00018
00019
00020
00021
00022
00023
00024 vsol_line_2d::vsol_line_2d()
00025 : vsol_curve_2d(),
00026 p0_(new vsol_point_2d),
00027 p1_(new vsol_point_2d)
00028 {
00029 }
00030
00031
00032
00033
00034 vsol_line_2d::vsol_line_2d(vgl_vector_2d<double> const& new_direction,
00035 const vsol_point_2d_sptr &new_middle)
00036 : vsol_curve_2d(),
00037 p0_(new vsol_point_2d(*(new_middle->plus_vector(-(new_direction)/2)))),
00038 p1_(new vsol_point_2d(*(new_middle->plus_vector((new_direction)/2))))
00039 {
00040 }
00041
00042
00043
00044
00045 vsol_line_2d::vsol_line_2d(vgl_vector_2d<double> const& new_direction,
00046 const vgl_point_2d<double> &new_middle)
00047 : vsol_curve_2d(),
00048 p0_(new vsol_point_2d(*(vsol_point_2d(new_middle).plus_vector(-(new_direction)/2)))),
00049 p1_(new vsol_point_2d(*(vsol_point_2d(new_middle).plus_vector((new_direction)/2))))
00050 {
00051 }
00052
00053
00054
00055
00056 vsol_line_2d::vsol_line_2d(vgl_point_2d<double> const& p0,
00057 vgl_point_2d<double> const& p1)
00058 : vsol_curve_2d(),
00059 p0_(new vsol_point_2d(p0)),
00060 p1_(new vsol_point_2d(p1))
00061 {
00062 }
00063
00064
00065
00066
00067 vsol_line_2d::vsol_line_2d(vgl_line_segment_2d<double> const& l)
00068 : vsol_curve_2d(),
00069 p0_(new vsol_point_2d(l.point1())),
00070 p1_(new vsol_point_2d(l.point2()))
00071 {
00072 }
00073
00074
00075
00076
00077
00078 vsol_spatial_object_2d* vsol_line_2d::clone() const
00079 {
00080 return new vsol_line_2d(*this);
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090 vsol_point_2d_sptr vsol_line_2d::middle() const
00091 {
00092 return p0_->middle(*p1_);
00093 }
00094
00095
00096
00097
00098 vgl_vector_2d<double> vsol_line_2d::direction() const
00099 {
00100 return p0_->to_vector(*p1_);
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 bool vsol_line_2d::operator==(vsol_line_2d const& other) const
00111 {
00112 if (this==&other)
00113 return true;
00114 return vsol_curve_2d::endpoints_equal(other);
00115 }
00116
00117
00118
00119 bool vsol_line_2d::operator==(vsol_spatial_object_2d const& obj) const
00120 {
00121 return
00122 obj.cast_to_curve() && obj.cast_to_curve()->cast_to_line() &&
00123 *this == *obj.cast_to_curve()->cast_to_line();
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133 void vsol_line_2d::compute_bounding_box() const
00134 {
00135 set_bounding_box( p0_->x(), p0_->y());
00136 add_to_bounding_box(p1_->x(), p1_->y());
00137 }
00138
00139
00140
00141
00142 double vsol_line_2d::length() const
00143 {
00144 return p0_->distance(p1_);
00145 }
00146
00147
00148
00149
00150
00151 double vsol_line_2d::tangent_angle() const
00152 {
00153 static const double deg_per_rad = vnl_math::deg_per_rad;
00154 double dy = p1_->y()-p0_->y();
00155 double dx = p1_->x()-p0_->x();
00156
00157 double ang;
00158
00159 if (dx == 0) ang = dy<0 ? 270.0 : 90.0;
00160 else if (dy == 0) ang = dx<0 ? 180.0 : 0.0;
00161 else if (dy == dx) ang = dy<0 ? 225.0 : 45.0;
00162 else if (dy+dx==0) ang = dy<0 ? 315.0 :135.0;
00163
00164 else ang = deg_per_rad * vcl_atan2(dy,dx);
00165 if (ang<0) ang+= 360.0;
00166 return ang;
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176 void vsol_line_2d::set_p0(vsol_point_2d_sptr const& new_p0)
00177 {
00178 p0_=new_p0;
00179 }
00180
00181
00182
00183
00184 void vsol_line_2d::set_p1(vsol_point_2d_sptr const& new_p1)
00185 {
00186 p1_=new_p1;
00187 }
00188
00189
00190
00191
00192
00193
00194 void vsol_line_2d::set_length(const double new_length)
00195 {
00196
00197 assert(new_length>=0);
00198
00199 vsol_point_2d_sptr m=middle();
00200 vgl_vector_2d<double> d =
00201 (*p0_)==(*p1_) ? vgl_vector_2d<double>(1.0,0.0)
00202 : normalized(direction());
00203 d *= new_length;
00204
00205 p0_=new vsol_point_2d(*(m->plus_vector(-d/2)));
00206 p1_=new vsol_point_2d(*(m->plus_vector(d/2)));
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216 bool vsol_line_2d::in(vsol_point_2d_sptr const& p) const
00217 {
00218
00219 bool result=(p0_->y()-p1_->y())*p->x()+(p1_->x()-p0_->x())*p->y()
00220 +p0_->x()*p1_->y() -p0_->y()*p1_->x() ==0;
00221
00222 if (result)
00223 {
00224 double dot_product=(p->x()-p0_->x())*(p1_->x()-p0_->x())
00225 +(p->y()-p0_->y())*(p1_->y()-p0_->y());
00226 result=(dot_product>=0)&&
00227 (dot_product<(vnl_math_sqr(p1_->x()-p0_->x())
00228 +vnl_math_sqr(p1_->y()-p0_->y())));
00229 }
00230 return result;
00231 }
00232
00233
00234
00235
00236
00237 vgl_homg_line_2d<double> *
00238 vsol_line_2d::tangent_at_point(vsol_point_2d_sptr const& p) const
00239 {
00240
00241 assert(in(p));
00242
00243 return new vgl_homg_line_2d<double>(p0_->y()-p1_->y(),p1_->x()-p0_->x(),
00244 p0_->x()*p1_->y()-p0_->y()*p1_->x());
00245 }
00246
00247
00248
00249
00250 vgl_homg_line_2d<double> vsol_line_2d::vgl_hline_2d() const
00251 {
00252 vgl_homg_point_2d<double> vp0(p0_->x(), p0_->y());
00253 vgl_homg_point_2d<double> vp1(p1_->x(), p1_->y());
00254 vgl_homg_line_2d<double> l(vp0, vp1);
00255 return l;
00256 }
00257
00258
00259
00260
00261 vgl_line_segment_2d<double> vsol_line_2d::vgl_seg_2d() const
00262 {
00263 vgl_homg_point_2d<double> vp0(p0_->x(), p0_->y());
00264 vgl_homg_point_2d<double> vp1(p1_->x(), p1_->y());
00265 vgl_line_segment_2d<double> l(vp0, vp1);
00266 return l;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275 void vsol_line_2d::b_write(vsl_b_ostream &os) const
00276 {
00277 vsl_b_write(os, version());
00278 vsol_spatial_object_2d::b_write(os);
00279 vsl_b_write(os, p0_);
00280 vsl_b_write(os, p1_);
00281 }
00282
00283
00284 void vsol_line_2d::b_read(vsl_b_istream &is)
00285 {
00286 if (!is)
00287 return;
00288 short ver;
00289 vsl_b_read(is, ver);
00290 switch (ver)
00291 {
00292 case 1:
00293 vsol_spatial_object_2d::b_read(is);
00294 vsl_b_read(is, p0_);
00295 vsl_b_read(is, p1_);
00296 break;
00297 default:
00298 vcl_cerr << "vsol_line_2d: unknown I/O version " << ver << '\n';
00299 }
00300 }
00301
00302 short vsol_line_2d::version() const
00303 {
00304 return 1;
00305 }
00306
00307
00308 void vsol_line_2d::print_summary(vcl_ostream &os) const
00309 {
00310 os << *this;
00311 }
00312
00313
00314 void
00315 vsl_b_write(vsl_b_ostream &os, const vsol_line_2d* p)
00316 {
00317 if (p==0) {
00318 vsl_b_write(os, false);
00319 }
00320 else{
00321 vsl_b_write(os,true);
00322 p->b_write(os);
00323 }
00324 }
00325
00326
00327
00328 void
00329 vsl_b_read(vsl_b_istream &is, vsol_line_2d* &p)
00330 {
00331 delete p;
00332 bool not_null_ptr;
00333 vsl_b_read(is, not_null_ptr);
00334 if (not_null_ptr) {
00335 p = new vsol_line_2d();
00336 p->b_read(is);
00337 }
00338 else
00339 p = 0;
00340 }
00341
00342 void vsol_line_2d::describe(vcl_ostream &strm, int blanking) const
00343 {
00344 if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00345 strm << '[' << *(p0()) << ' ' << *(p1()) << ']' << vcl_endl;
00346 }