contrib/gel/vsol/vsol_line_3d.cxx
Go to the documentation of this file.
00001 // This is gel/vsol/vsol_line_3d.cxx
00002 #include "vsol_line_3d.h"
00003 //:
00004 // \file
00005 #include <vcl_cassert.h>
00006 #include <vbl/io/vbl_io_smart_ptr.h>
00007 #include <vsol/vsol_point_3d.h>
00008 #include <vgl/vgl_vector_3d.h>
00009 #include <vgl/vgl_homg_line_3d_2_points.h>
00010 #include <vgl/vgl_homg_point_3d.h>
00011 
00012 //***************************************************************************
00013 // Initialization
00014 //***************************************************************************
00015 
00016 //---------------------------------------------------------------------------
00017 //: Constructor from the direction and the middle point
00018 //---------------------------------------------------------------------------
00019 vsol_line_3d::vsol_line_3d(vgl_vector_3d<double> const& new_direction,
00020                            vsol_point_3d_sptr const& new_middle)
00021 : p0_(new vsol_point_3d(*(new_middle->plus_vector(-new_direction/2)))),
00022   p1_(new vsol_point_3d(*(new_middle->plus_vector(new_direction/2))))
00023 {
00024 }
00025 
00026 //---------------------------------------------------------------------------
00027 //: Clone `this': creation of a new object and initialization
00028 //  See Prototype pattern
00029 //---------------------------------------------------------------------------
00030 vsol_spatial_object_3d* vsol_line_3d::clone() const
00031 {
00032   return new vsol_line_3d(*this);
00033 }
00034 
00035 //***************************************************************************
00036 // Access
00037 //***************************************************************************
00038 
00039 //---------------------------------------------------------------------------
00040 //: Middle point of the straight line segment
00041 //---------------------------------------------------------------------------
00042 vsol_point_3d_sptr vsol_line_3d::middle() const
00043 {
00044   return p0_->middle(*p1_);
00045 }
00046 
00047 //---------------------------------------------------------------------------
00048 //: direction of the straight line segment.
00049 //---------------------------------------------------------------------------
00050 vgl_vector_3d<double> vsol_line_3d::direction() const
00051 {
00052   return p0_->to_vector(*p1_);
00053 }
00054 
00055 //***************************************************************************
00056 // Comparison
00057 //***************************************************************************
00058 
00059 //---------------------------------------------------------------------------
00060 //: Has `this' the same points than `other' ?
00061 //---------------------------------------------------------------------------
00062 bool vsol_line_3d::operator==(vsol_line_3d const& other) const
00063 {
00064   bool result;
00065 
00066   result=this==&other;
00067   if (!result)
00068     result=(((*p0_)==(*(other.p0_)))&&((*p1_)==(*(other.p1_))))
00069       ||(((*p0_)==(*(other.p1_)))&&((*p1_)==(*(other.p0_))));
00070   return result;
00071 }
00072 
00073 //: spatial object equality
00074 
00075 bool vsol_line_3d::operator==(vsol_spatial_object_3d const& obj) const
00076 {
00077   return
00078     obj.cast_to_curve() && obj.cast_to_curve()->cast_to_line() &&
00079     *this == *obj.cast_to_curve()->cast_to_line();
00080 }
00081 
00082 //***************************************************************************
00083 // Status report
00084 //***************************************************************************
00085 
00086 //---------------------------------------------------------------------------
00087 //: Compute the bounding box of `this'
00088 //---------------------------------------------------------------------------
00089 void vsol_line_3d::compute_bounding_box() const
00090 {
00091   set_bounding_box(   p0_->x(),p0_->y(),p0_->z());
00092   add_to_bounding_box(p1_->x(),p1_->y(),p1_->z());
00093 }
00094 
00095 //---------------------------------------------------------------------------
00096 //: Return the length of `this'
00097 //---------------------------------------------------------------------------
00098 double vsol_line_3d::length() const
00099 {
00100   return p0_->distance(p1_);
00101 }
00102 
00103 //***************************************************************************
00104 // Status setting
00105 //***************************************************************************
00106 
00107 //---------------------------------------------------------------------------
00108 //: Set the first point of the straight line segment
00109 //---------------------------------------------------------------------------
00110 void vsol_line_3d::set_p0(vsol_point_3d_sptr const& new_p0)
00111 {
00112   p0_=new_p0;
00113 }
00114 
00115 //---------------------------------------------------------------------------
00116 //: Set the last point of the straight line segment
00117 //---------------------------------------------------------------------------
00118 void vsol_line_3d::set_p1(vsol_point_3d_sptr const& new_p1)
00119 {
00120   p1_=new_p1;
00121 }
00122 
00123 //---------------------------------------------------------------------------
00124 //: Set the length of `this'. Doesn't change middle point and orientation.
00125 //    If p0 and p1 are equal then the direction is set to (1,0,0)
00126 // Require: new_length>=0
00127 //---------------------------------------------------------------------------
00128 void vsol_line_3d::set_length(const double new_length)
00129 {
00130   // require
00131   assert(new_length>=0);
00132 
00133   vsol_point_3d_sptr m=middle();
00134   vgl_vector_3d<double> d =
00135     (*p0_)==(*p1_) ? vgl_vector_3d<double>(1.0,0.0,0.0)
00136                    : normalized(direction());
00137   d *= new_length;
00138 
00139   p0_=new vsol_point_3d(*(m->plus_vector(-d/2)));
00140   p1_=new vsol_point_3d(*(m->plus_vector(d/2)));
00141 }
00142 
00143 //***************************************************************************
00144 // Basic operations
00145 //***************************************************************************
00146 
00147 //---------------------------------------------------------------------------
00148 //: Is `p' in `this' ?
00149 //---------------------------------------------------------------------------
00150 bool vsol_line_3d::in(vsol_point_3d_sptr const& p) const
00151 {
00152   // `p' belongs to the straight line
00153   double ax=p1_->x()-p0_->x();
00154   double ay=p1_->y()-p0_->y();
00155   double az=p1_->z()-p0_->z();
00156   double bx=p->x()-p0_->x();
00157   double by=p->y()-p0_->y();
00158   double bz=p->z()-p0_->z();
00159 
00160   bool result = ay*bz==az*by && az*bx==ax*bz && ax*by==ay*bx;
00161   if (result) // `p' belongs to the segment
00162   {
00163     double dot_product=bx*ax+by*ay+bz*az;
00164     result= dot_product>=0 && dot_product<ax*ax+ay*ay+az*az;
00165   }
00166   return result;
00167 }
00168 
00169 //---------------------------------------------------------------------------
00170 //: Return the tangent to `this' at `p'.  Has to be deleted manually
00171 // Require: in(p)
00172 //---------------------------------------------------------------------------
00173 vgl_homg_line_3d_2_points<double> *
00174 vsol_line_3d::tangent_at_point(vsol_point_3d_sptr const& p) const
00175 {
00176   assert(false); // TODO
00177   // require
00178   assert(in(p));
00179 
00180   vgl_homg_line_3d_2_points<double> *result;
00181   vgl_homg_point_3d<double> a(p0_->x(),p0_->y(),p0_->z());
00182   vgl_homg_point_3d<double> b(p1_->x(),p1_->y(),p1_->z());
00183 
00184   result=new vgl_homg_line_3d_2_points<double>(a,b);
00185 
00186   return result;
00187 }
00188 
00189 void vsol_line_3d::describe(vcl_ostream &strm, int blanking) const
00190 {
00191   if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00192   strm << '[' << *(p0()) << ' ' << *(p1()) << ']' << vcl_endl;
00193 }
00194 
00195 //----------------------------------------------------------------
00196 // ================   Binary I/O Methods ========================
00197 //----------------------------------------------------------------
00198 
00199 //: Binary save self to stream.
00200 void vsol_line_3d::b_write(vsl_b_ostream &os) const
00201 {
00202   vsl_b_write(os, version());
00203   vsol_spatial_object_3d::b_write(os);
00204   vsl_b_write(os, p0_);
00205   vsl_b_write(os, p1_);
00206 }
00207 
00208 //: Binary load self from stream. (not typically used)
00209 void vsol_line_3d::b_read(vsl_b_istream &is)
00210 {
00211   if (!is)
00212     return;
00213   short ver;
00214   vsl_b_read(is, ver);
00215   switch (ver)
00216   {
00217    case 1:
00218     vsol_spatial_object_3d::b_read(is);
00219     vsl_b_read(is, p0_);
00220     vsl_b_read(is, p1_);
00221     break;
00222    default:
00223     vcl_cerr << "vsol_line_3d: unknown I/O version " << ver << '\n';
00224   }
00225 }
00226 //: Return IO version number;
00227 short vsol_line_3d::version() const
00228 {
00229   return 1;
00230 }
00231 
00232 //: Print an ascii summary to the stream
00233 void vsol_line_3d::print_summary(vcl_ostream &os) const
00234 {
00235   os << *this;
00236 }
00237 
00238 //: Binary save vsol_line_3d to stream.
00239 void
00240 vsl_b_write(vsl_b_ostream &os, vsol_line_3d const* p)
00241 {
00242   if (p==0) {
00243     vsl_b_write(os, false); // Indicate null pointer stored
00244   }
00245   else{
00246     vsl_b_write(os,true); // Indicate non-null pointer stored
00247     p->b_write(os);
00248   }
00249 }
00250 
00251 //: Binary load vsol_line_3d from stream.
00252 void
00253 vsl_b_read(vsl_b_istream &is, vsol_line_3d* &p)
00254 {
00255   delete p;
00256   bool not_null_ptr;
00257   vsl_b_read(is, not_null_ptr);
00258   if (not_null_ptr) {
00259     p = new vsol_line_3d(new vsol_point_3d(0.0,0.0,0.0),new vsol_point_3d(0.0,0.0,0.0));
00260     p->b_read(is);
00261   }
00262   else
00263     p = 0;
00264 }