Go to the documentation of this file.00001
00002 #include "vsol_polygon_2d.h"
00003
00004
00005 #include <vsl/vsl_vector_io.h>
00006 #include <vcl_iostream.h>
00007 #include <vcl_cassert.h>
00008 #include <vcl_cmath.h>
00009 #include <vsol/vsol_point_2d.h>
00010 #include <vgl/vgl_vector_2d.h>
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 vsol_polygon_2d::vsol_polygon_2d(const vcl_vector<vsol_point_2d_sptr> &new_vertices)
00021 : vsol_region_2d()
00022 {
00023
00024 assert(new_vertices.size()>=3);
00025
00026 storage_=new vcl_vector<vsol_point_2d_sptr>(new_vertices);
00027 }
00028
00029
00030
00031
00032 vsol_polygon_2d::vsol_polygon_2d(const vsol_polygon_2d &other)
00033 : vsol_region_2d(other)
00034 {
00035
00036 storage_=new vcl_vector<vsol_point_2d_sptr>(*other.storage_);
00037 for (unsigned int i=0;i<storage_->size();++i)
00038 (*storage_)[i]=new vsol_point_2d(*((*other.storage_)[i]));
00039 }
00040
00041
00042
00043
00044 vsol_polygon_2d::~vsol_polygon_2d()
00045 {
00046 for (unsigned i = 0; i < storage_->size(); i++)
00047 (*storage_)[i] = 0;
00048 delete storage_;
00049 }
00050
00051
00052
00053
00054
00055 vsol_spatial_object_2d* vsol_polygon_2d::clone(void) const
00056 {
00057 return new vsol_polygon_2d(*this);
00058 }
00059
00060
00061
00062
00063
00064 vsol_polygon_2d* vsol_polygon_2d::cast_to_polygon(void)
00065 {
00066 if (!cast_to_triangle()||!cast_to_rectangle())
00067 return this;
00068 else
00069 return 0;
00070 }
00071
00072 const vsol_polygon_2d* vsol_polygon_2d::cast_to_polygon(void) const
00073 {
00074 if (!cast_to_triangle()||!cast_to_rectangle())
00075 return this;
00076 else
00077 return 0;
00078 }
00079
00080 vsol_triangle_2d* vsol_polygon_2d::cast_to_triangle(void){return 0;}
00081 const vsol_triangle_2d* vsol_polygon_2d::cast_to_triangle(void) const
00082 {
00083 return 0;
00084 }
00085
00086 vsol_rectangle_2d* vsol_polygon_2d::cast_to_rectangle(void){return 0;}
00087 const vsol_rectangle_2d* vsol_polygon_2d::cast_to_rectangle(void) const
00088 {
00089 return 0;
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 vsol_point_2d_sptr vsol_polygon_2d::vertex(const int i) const
00101 {
00102
00103 assert(valid_index(i));
00104
00105 return (*storage_)[i];
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115 bool vsol_polygon_2d::operator==(const vsol_polygon_2d &other) const
00116 {
00117 bool result = (this==&other);
00118
00119 if (!result)
00120 {
00121 result = (storage_->size()==other.storage_->size());
00122 if (result)
00123 {
00124 vsol_point_2d_sptr p=(*storage_)[0];
00125
00126 unsigned int i=0;
00127 for (result=false;i<storage_->size()&&!result;++i)
00128 result = (*p==*(*other.storage_)[i]);
00129 if (result)
00130 {
00131 for (unsigned int j=1;j<size()&&result;++i,++j)
00132 {
00133 if (i>=storage_->size()) i=0;
00134 result = ((*storage_)[i]==(*storage_)[j]);
00135 }
00136 }
00137 }
00138 }
00139 return result;
00140 }
00141
00142
00143
00144 bool vsol_polygon_2d::operator==(const vsol_spatial_object_2d& obj) const
00145 {
00146 return
00147 obj.cast_to_region() && obj.cast_to_region()->cast_to_polygon() &&
00148 *this == *obj.cast_to_region()->cast_to_polygon();
00149 }
00150
00151
00152
00153
00154
00155 void vsol_polygon_2d::compute_bounding_box(void) const
00156 {
00157 set_bounding_box((*storage_)[0]->x(), (*storage_)[0]->y());
00158 for (unsigned int i=1;i<storage_->size();++i)
00159 add_to_bounding_box((*storage_)[i]->x(), (*storage_)[i]->y());
00160 }
00161
00162
00163
00164
00165 double vsol_polygon_2d::area(void) const
00166 {
00167 double area = 0.0;
00168 unsigned int last = storage_->size()-1;
00169
00170 for (unsigned int i=0; i<last; ++i)
00171 area += ((*storage_)[i]->x() * (*storage_)[i+1]->y())
00172 - ((*storage_)[i+1]->x() * (*storage_)[i]->y());
00173
00174 area += ((*storage_)[last]->x() * (*storage_)[0]->y())
00175 - ((*storage_)[0]->x() * (*storage_)[last]->y());
00176
00177 return vcl_abs(area / 2.0);
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 vsol_point_2d_sptr vsol_polygon_2d::centroid(void) const
00204 {
00205 unsigned int nverts = storage_->size();
00206 assert(nverts>0);
00207 double sx = 0, sy = 0;
00208 double area = 0;
00209
00210 vsol_point_2d_sptr pi = (*storage_)[nverts-1];
00211 vsol_point_2d_sptr pi1 = (*storage_)[0];
00212 double xi = pi->x(), yi = pi->y();
00213 double xi1 = pi1->x(), yi1 = pi1->y();
00214
00215
00216 double xsum = xi, ysum = yi;
00217
00218 double temp = xi*yi1 - xi1*yi;
00219 area += temp;
00220 sx += temp*(xi1 + xi);
00221 sy += temp*(yi1 + yi);
00222 for (unsigned int i=0; i<nverts-1; ++i)
00223 {
00224 pi = (*storage_)[i];
00225 pi1 = (*storage_)[i+1];
00226 xi = pi->x(), yi = pi->y();
00227 xi1 = pi1->x(), yi1 = pi1->y();
00228 temp = xi*yi1 - xi1*yi;
00229 area += temp;
00230 sx += temp*(xi1 + xi);
00231 sy += temp*(yi1 + yi);
00232 xsum += xi; ysum += yi;
00233 }
00234 area /= 2.0;
00235 if(vcl_fabs(area)!=0.0)
00236 {
00237 double xc = sx/(6.0*area), yc = sy/(6.0*area);
00238 return new vsol_point_2d(xc, yc);
00239 }
00240 return new vsol_point_2d(xsum/nverts, ysum/nverts);
00241 }
00242
00243
00244
00245
00246
00247
00248
00249 bool vsol_polygon_2d::is_convex(void) const
00250 {
00251 if (storage_->size()==3) return true;
00252
00253
00254
00255
00256
00257
00258
00259
00260 double n = 0.0;
00261 for (unsigned int i=0; i<storage_->size(); ++i)
00262 {
00263 int j = (i>1) ? i-2 : i-2+storage_->size();
00264 int k = (i>0) ? i-1 : i-1+storage_->size();
00265 vsol_point_2d_sptr p0=(*storage_)[k];
00266 vsol_point_2d_sptr p1=(*storage_)[j];
00267 vsol_point_2d_sptr p2=(*storage_)[i];
00268 vgl_vector_2d<double> v1=p0->to_vector(*p1);
00269 vgl_vector_2d<double> v2=p1->to_vector(*p2);
00270 n = cross_product(v1,v2);
00271 if (n != 0.0)
00272 break;
00273 }
00274 if (n == 0.0)
00275 return true;
00276
00277 for (unsigned int i=0; i<storage_->size(); ++i)
00278 {
00279 int j = (i>1) ? i-2 : i-2+storage_->size();
00280 int k = (i>0) ? i-1 : i-1+storage_->size();
00281 vsol_point_2d_sptr p0=(*storage_)[k];
00282 vsol_point_2d_sptr p1=(*storage_)[j];
00283 vsol_point_2d_sptr p2=(*storage_)[i];
00284 vgl_vector_2d<double> v1=p0->to_vector(*p1);
00285 vgl_vector_2d<double> v2=p1->to_vector(*p2);
00286 double n2 = cross_product(v1,v2);
00287 if (n2*n < 0)
00288 return false;
00289 }
00290 return true;
00291 }
00292
00293
00294
00295
00296
00297
00298 void vsol_polygon_2d::b_write(vsl_b_ostream &os) const
00299 {
00300 vsl_b_write(os, version());
00301 vsol_spatial_object_2d::b_write(os);
00302 if (!storage_)
00303 vsl_b_write(os, false);
00304 else
00305 {
00306 vsl_b_write(os, true);
00307 vsl_b_write(os, *storage_);
00308 }
00309 }
00310
00311
00312 void vsol_polygon_2d::b_read(vsl_b_istream &is)
00313 {
00314 short ver;
00315 vsl_b_read(is, ver);
00316 switch (ver)
00317 {
00318 case 1:
00319 vsol_spatial_object_2d::b_read(is);
00320
00321 delete storage_;
00322 storage_ = new vcl_vector<vsol_point_2d_sptr>();
00323 bool null_ptr;
00324 vsl_b_read(is, null_ptr);
00325 if (!null_ptr)
00326 return;
00327 vsl_b_read(is, *storage_);
00328 break;
00329 default:
00330 vcl_cerr << "vsol_polygon_2d: unknown I/O version " << ver << '\n';
00331 }
00332 }
00333
00334
00335 short vsol_polygon_2d::version() const
00336 {
00337 return 1;
00338 }
00339
00340
00341 void vsol_polygon_2d::print_summary(vcl_ostream &os) const
00342 {
00343 os << *this;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353 vsol_polygon_2d::vsol_polygon_2d(void)
00354 {
00355 storage_=new vcl_vector<vsol_point_2d_sptr>();
00356 }
00357
00358 bool vsol_polygon_2d::valid_vertices(const vcl_vector<vsol_point_2d_sptr> ) const
00359 {
00360 return true;
00361 }
00362
00363
00364
00365 void
00366 vsl_b_write(vsl_b_ostream &os, const vsol_polygon_2d* p)
00367 {
00368 if (p==0) {
00369 vsl_b_write(os, false);
00370 }
00371 else{
00372 vsl_b_write(os,true);
00373 p->b_write(os);
00374 }
00375 }
00376
00377
00378
00379 void
00380 vsl_b_read(vsl_b_istream &is, vsol_polygon_2d* &p)
00381 {
00382 delete p;
00383 bool not_null_ptr;
00384 vsl_b_read(is, not_null_ptr);
00385 if (not_null_ptr) {
00386 p = new vsol_polygon_2d();
00387 p->b_read(is);
00388 }
00389 else
00390 p = 0;
00391 }
00392
00393
00394 inline void vsol_polygon_2d::describe(vcl_ostream &strm, int blanking) const
00395 {
00396 if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00397 if (size() == 0)
00398 strm << "[null]";
00399 else {
00400 strm << "[Nverts=" << size()
00401 << " Area=" << area();
00402 for (unsigned int i=0; i<size(); ++i)
00403 strm << " p" << i << ':' << *(vertex(i));
00404 strm << ']';
00405 }
00406 strm << vcl_endl;
00407 }