contrib/gel/vsol/vsol_triangle_3d.cxx
Go to the documentation of this file.
00001 // This is gel/vsol/vsol_triangle_3d.cxx
00002 #include "vsol_triangle_3d.h"
00003 //:
00004 // \file
00005 #include <vcl_cassert.h>
00006 #include <vcl_iostream.h>
00007 #include <vsol/vsol_point_3d.h>
00008 #include <vgl/vgl_vector_3d.h>
00009 #include <vnl/vnl_math.h>
00010 
00011 //***************************************************************************
00012 // Initialization
00013 //***************************************************************************
00014 
00015 //---------------------------------------------------------------------------
00016 //: Constructor from its 3 vertices
00017 //---------------------------------------------------------------------------
00018 vsol_triangle_3d::vsol_triangle_3d(vsol_point_3d_sptr const& new_p0,
00019                                    vsol_point_3d_sptr const& new_p1,
00020                                    vsol_point_3d_sptr const& new_p2)
00021 {
00022   storage_=new vcl_vector<vsol_point_3d_sptr>(3);
00023   (*storage_)[0]=new_p0;
00024   (*storage_)[1]=new_p1;
00025   (*storage_)[2]=new_p2;
00026 }
00027 
00028 //---------------------------------------------------------------------------
00029 // Copy constructor
00030 //---------------------------------------------------------------------------
00031 vsol_triangle_3d::vsol_triangle_3d(vsol_triangle_3d const& other)
00032   : vsol_polygon_3d(other)
00033 {
00034 }
00035 
00036 //---------------------------------------------------------------------------
00037 // Destructor
00038 //---------------------------------------------------------------------------
00039 vsol_triangle_3d::~vsol_triangle_3d()
00040 {
00041 }
00042 
00043 //---------------------------------------------------------------------------
00044 //: Clone `this': creation of a new object and initialization
00045 // See Prototype pattern
00046 //---------------------------------------------------------------------------
00047 vsol_spatial_object_3d* vsol_triangle_3d::clone(void) const
00048 {
00049   return new vsol_triangle_3d(*this);
00050 }
00051 
00052 //***************************************************************************
00053 // Access
00054 //***************************************************************************
00055 
00056 //---------------------------------------------------------------------------
00057 //: Return the first vertex
00058 //---------------------------------------------------------------------------
00059 vsol_point_3d_sptr vsol_triangle_3d::p0(void) const
00060 {
00061   return (*storage_)[0];
00062 }
00063 
00064 //---------------------------------------------------------------------------
00065 //: Return the second vertex
00066 //---------------------------------------------------------------------------
00067 vsol_point_3d_sptr vsol_triangle_3d::p1(void) const
00068 {
00069   return (*storage_)[1];
00070 }
00071 
00072 //---------------------------------------------------------------------------
00073 //: Return the last vertex
00074 //---------------------------------------------------------------------------
00075 vsol_point_3d_sptr vsol_triangle_3d::p2(void) const
00076 {
00077   return (*storage_)[2];
00078 }
00079 
00080 //***************************************************************************
00081 // Comparison
00082 //***************************************************************************
00083 
00084 //---------------------------------------------------------------------------
00085 //: Has `this' the same points than `other' in the same order ?
00086 //---------------------------------------------------------------------------
00087 bool vsol_triangle_3d::operator==(vsol_triangle_3d const& other) const
00088 {
00089   return vsol_polygon_3d::operator==(other);
00090 }
00091 
00092 bool vsol_triangle_3d::operator==(vsol_polygon_3d const& other) const
00093 {
00094   return vsol_polygon_3d::operator==(other);
00095 }
00096 
00097 //: spatial object equality
00098 
00099 bool vsol_triangle_3d::operator==(vsol_spatial_object_3d const& obj) const
00100 {
00101   return
00102     obj.cast_to_region() && obj.cast_to_region()->cast_to_polygon() &&
00103     *this == *obj.cast_to_region()->cast_to_polygon();
00104 }
00105 
00106 //***************************************************************************
00107 // Status report
00108 //***************************************************************************
00109 
00110 //---------------------------------------------------------------------------
00111 //: Return the area of `this'
00112 //---------------------------------------------------------------------------
00113 double vsol_triangle_3d::area(void) const
00114 {
00115   double dx02=(*storage_)[0]->x()-(*storage_)[2]->x();
00116   double dy02=(*storage_)[0]->y()-(*storage_)[2]->y();
00117   double dz02=(*storage_)[0]->z()-(*storage_)[2]->z();
00118   double dx12=(*storage_)[1]->x()-(*storage_)[2]->x();
00119   double dy12=(*storage_)[1]->y()-(*storage_)[2]->y();
00120   double dz12=(*storage_)[1]->z()-(*storage_)[2]->z();
00121   return vcl_sqrt( vnl_math_sqr(dy02*dz12-dy12*dz02)
00122                  + vnl_math_sqr(dz02*dx12-dz12*dx02)
00123                  + vnl_math_sqr(dx02*dy12-dx12*dy02))/2;
00124 }
00125 //***************************************************************************
00126 // Element change
00127 //***************************************************************************
00128 
00129 //---------------------------------------------------------------------------
00130 //: Set the first vertex
00131 //---------------------------------------------------------------------------
00132 void vsol_triangle_3d::set_p0(vsol_point_3d_sptr const& new_p0)
00133 {
00134   (*storage_)[0]=new_p0;
00135 }
00136 
00137 //---------------------------------------------------------------------------
00138 //: Set the second vertex
00139 //---------------------------------------------------------------------------
00140 void vsol_triangle_3d::set_p1(vsol_point_3d_sptr const& new_p1)
00141 {
00142   (*storage_)[1]=new_p1;
00143 }
00144 
00145 //---------------------------------------------------------------------------
00146 //: Set the last vertex
00147 //---------------------------------------------------------------------------
00148 void vsol_triangle_3d::set_p2(vsol_point_3d_sptr const& new_p2)
00149 {
00150   (*storage_)[2]=new_p2;
00151 }
00152 
00153 //***************************************************************************
00154 // Basic operations
00155 //***************************************************************************
00156 
00157 //---------------------------------------------------------------------------
00158 //: Is `p' in `this' ?
00159 // \todo not yet implemented
00160 //---------------------------------------------------------------------------
00161 bool vsol_triangle_3d::in(vsol_point_3d_sptr const& ) const
00162 {
00163   vcl_cerr << "Warning: vsol_triangle_3d::in() has not been implemented yet\n";
00164   return true;
00165 }
00166 
00167 //---------------------------------------------------------------------------
00168 //: Return the unit normal vector at point `p'.
00169 // This is the normal to the place in which the triangle lies.
00170 // If the vertices are collinear, the normal is the null vector.
00171 // Require: in(p)
00172 //---------------------------------------------------------------------------
00173 vgl_vector_3d<double>
00174 vsol_triangle_3d::normal_at_point(vsol_point_3d_sptr const& p) const
00175 {
00176   // require
00177   assert(in(p));
00178 
00179   // Since a rectangle is planar, the answer is independent of p:
00180   vgl_vector_3d<double> v1((*storage_)[1]->x()-(*storage_)[0]->x(),
00181                            (*storage_)[1]->y()-(*storage_)[0]->y(),
00182                            (*storage_)[1]->z()-(*storage_)[0]->z());
00183   vgl_vector_3d<double> v2((*storage_)[2]->x()-(*storage_)[0]->x(),
00184                            (*storage_)[2]->y()-(*storage_)[0]->y(),
00185                            (*storage_)[2]->z()-(*storage_)[0]->z());
00186 
00187   return normalized(cross_product(v1,v2));
00188 }
00189 
00190 inline void vsol_triangle_3d::describe(vcl_ostream &strm, int blanking) const
00191 {
00192   if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00193   strm << "<vsol_triangle_3d with corners";
00194   for (unsigned int i=0; i<size(); ++i)
00195     strm << ' ' << *(vertex(i));
00196   strm << '>' << vcl_endl;
00197 }
00198 
00199 //----------------------------------------------------------------
00200 // ================   Binary I/O Methods ========================
00201 //----------------------------------------------------------------
00202 
00203 //: Binary save self to stream.
00204 void vsol_triangle_3d::b_write(vsl_b_ostream &os) const
00205 {
00206   vsl_b_write(os, version());
00207   vsol_polygon_3d::b_write(os);
00208 }
00209 
00210 //: Binary load self from stream (not typically used)
00211 void vsol_triangle_3d::b_read(vsl_b_istream &is)
00212 {
00213   if (!is)
00214     return;
00215   short ver;
00216   vsl_b_read(is, ver);
00217   switch (ver)
00218   {
00219    case 1:
00220     vsol_polygon_3d::b_read(is);
00221     if (storage_->size()!=3) {
00222       vcl_cerr << "I/O ERROR: vsol_triangle_3d::b_read(vsl_b_istream&)\n"
00223                << "           Incorrect number of vertices: "<< storage_->size() << '\n';
00224       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00225       return;
00226     }
00227     break;
00228 
00229    default:
00230     vcl_cerr << "I/O ERROR: vsol_triangle_3d::b_read(vsl_b_istream&)\n"
00231              << "           Unknown version number "<< ver << '\n';
00232     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00233     return;
00234   }
00235 }
00236 //: Return IO version number;
00237 short vsol_triangle_3d::version() const
00238 {
00239   return 1;
00240 }
00241 
00242 //: Print an ascii summary to the stream
00243 void vsol_triangle_3d::print_summary(vcl_ostream &os) const
00244 {
00245   os << *this;
00246 }
00247 
00248 //external functions
00249 
00250 //: Binary save vsol_triangle_3d_sptr to stream.
00251 void
00252 vsl_b_write(vsl_b_ostream &os, vsol_triangle_3d const* t)
00253 {
00254   if (!t){
00255     vsl_b_write(os, false); // Indicate null triangle stored
00256   }
00257   else{
00258     vsl_b_write(os,true); // Indicate non-null triangle stored
00259     t->b_write(os);
00260   }
00261 }
00262 
00263 //: Binary load vsol_triangle_3d* from stream.
00264 void
00265 vsl_b_read(vsl_b_istream &is, vsol_triangle_3d* &t)
00266 {
00267   delete t;
00268   bool not_null_ptr;
00269   vsl_b_read(is, not_null_ptr);
00270   if (not_null_ptr) {
00271     t = new vsol_triangle_3d(new vsol_point_3d(0.0,0.0,0.0),new vsol_point_3d(0.0,0.0,0.0),new vsol_point_3d(0.0,0.0,0.0));
00272     t->b_read(is);
00273   }
00274   else
00275     t = 0;
00276 }