00001
00059
00060 #include <ros/console.h>
00061
00062 #include <cob_3d_mapping_common/polygon.h>
00063
00064 #include <pcl/common/common.h>
00065
00066 #ifdef PCL_VERSION_COMPARE
00067 #include <pcl/common/transforms.h>
00068 #else
00069 #include <pcl/common/transform.h>
00070 #include <pcl/registration/transforms.h>
00071 #endif
00072 #include <pcl/common/centroid.h>
00073 #include <pcl/common/eigen.h>
00074
00075
00076 #include <boost/shared_ptr.hpp>
00077
00078
00079 #define MOD(a,b) ( ((a%b)+b)%b )
00080
00081 namespace cob_3d_mapping
00082 {
00083
00084
00085
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00124
00125
00126
00127
00128
00129
00130
00131
00132
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 Polygon::Polygon(unsigned int id,
00179 Eigen::Vector3f normal,
00180 Eigen::Vector3f centroid,
00181 std::vector<std::vector<Eigen::Vector3f> >& contours_3d,
00182 std::vector<bool> holes,
00183 std::vector<float> color)
00184 : normal_(Eigen::Vector3f::Zero()),
00185 d_(0.0),
00186 merge_weight_(1.0)
00187 {
00188 id_ = id;
00189 d_ = centroid.dot(normal);
00190 if (d_ > 0) {
00191 normal_ = -normal;
00192 d_ = -d_;
00193 }
00194 else { normal_ = normal; }
00195 holes_ = holes;
00196 color_ = color;
00197 computePose(contours_3d);
00198 setContours3D(contours_3d);
00199 }
00200
00201 Polygon::Polygon(unsigned int id,
00202 Eigen::Vector3f normal,
00203 Eigen::Vector3f centroid,
00204 std::vector<pcl::PointCloud<pcl::PointXYZ> >& contours_3d,
00205 std::vector<bool> holes,
00206 std::vector<float> color)
00207 : normal_(Eigen::Vector3f::Zero()),
00208 d_(0.0),
00209 merge_weight_(1.0)
00210 {
00211 id_ = id;
00212 d_ = centroid.dot(normal);
00213 if (d_ > 0) {
00214 normal_ = -normal;
00215 d_ = -d_;
00216 }
00217 else { normal_ = normal; }
00218
00219 holes_ = holes;
00220 color_ = color;
00221 std::vector<std::vector<Eigen::Vector3f> > contours_eigen;
00222 for(unsigned int i = 0; i < contours_3d.size(); i++)
00223 {
00224 std::vector<Eigen::Vector3f> c_eigen;
00225 for(unsigned int j = 0; j < contours_3d[i].size(); j++)
00226 {
00227 Eigen::Vector3f pt = contours_3d[i].points[j].getVector3fMap();
00228 c_eigen.push_back(pt);
00229 }
00230 contours_eigen.push_back(c_eigen);
00231 }
00232 computePose(contours_eigen);
00233 setContours3D(contours_eigen);
00234 }
00235
00236 void
00237 Polygon::setContours3D(std::vector<std::vector<Eigen::Vector3f> >& contours_3d)
00238 {
00239 contours_.clear();
00240 for(unsigned int i = 0; i < contours_3d.size(); i++)
00241 {
00242 std::vector<Eigen::Vector2f> c;
00243 for(unsigned int j = 0; j < contours_3d[i].size(); j++)
00244 {
00245 Eigen::Vector2f pt_2d = (pose_.inverse()*contours_3d[i][j]).head(2);
00246 c.push_back(pt_2d);
00247 }
00248 contours_.push_back(c);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 }
00258
00259 std::vector<std::vector<Eigen::Vector3f> >
00260 Polygon::getContours3D()
00261 {
00262 std::vector<std::vector<Eigen::Vector3f> > contours_3d;
00263 for(unsigned int i = 0; i < contours_.size(); i++)
00264 {
00265 std::vector<Eigen::Vector3f> c;
00266 for(unsigned int j = 0; j < contours_[i].size(); j++)
00267 {
00268 Eigen::Vector3f pt_2d(contours_[i][j](0), contours_[i][j](1), 0);
00269 Eigen::Vector3f pt_3d = pose_*pt_2d;
00270 c.push_back(pt_3d);
00271 }
00272 contours_3d.push_back(c);
00273 }
00274 return contours_3d;
00275 }
00276
00277 void
00278 Polygon::updateAttributes(const Eigen::Vector3f &new_normal, const Eigen::Vector3f& new_origin)
00279 {
00280
00281 d_ = new_origin.dot(new_normal);
00282 if (d_ > 0) {
00283 normal_ = -new_normal;
00284 d_ = -d_;
00285 }
00286 else { normal_ = new_normal; }
00287
00288
00289
00290 Eigen::Affine3f t;
00291 pcl::getTransformationFromTwoUnitVectorsAndOrigin(normal_.unitOrthogonal(), normal_, new_origin, t);
00292 pose_ = t.inverse();
00293
00294
00295 }
00296
00297 void Polygon::transform(const Eigen::Affine3f& trafo)
00298 {
00299
00300
00301 pose_ = trafo*pose_;
00302 normal_ = trafo.rotation()*normal_;
00303 d_ = pose_.translation().dot(normal_);
00304 if (d_ > 0)
00305 {
00306 normal_ *= -1;
00307 d_ = -d_;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317 }
00318
00319
00320 void
00321 Polygon::smoothContours()
00322 {
00323
00324
00325
00326
00327 std::vector<std::vector<Eigen::Vector2f> > contours_sm = contours_;
00328 float weight_data = 0.5, weight_smooth = 0.01, tolerance = 1.0f;
00329 float change = tolerance;
00330
00331 for(unsigned int j = 0; j < contours_.size(); ++j)
00332 {
00333 int num_iteration = 0;
00334 int l = contours_[j].size();
00335
00336
00337
00338 while(change >= tolerance && num_iteration <= 5)
00339 {
00340 change = 0.0f;
00341 for(int k=0; k<l; ++k)
00342 {
00343
00344
00345 float before = contours_sm[j][k](0);
00346 contours_sm[j][k](0) += weight_data * (contours_[j][k](0) - contours_sm[j][k](0));
00347 contours_sm[j][k](0) += weight_smooth * (contours_sm[j][ MOD(k-1,l) ](0) + contours_sm[j][ (k+1)%l ](0) - (2.0f * contours_sm[j][k](0)));
00348 contours_sm[j][k](0) += 0.5f * weight_smooth * (2.0f * contours_sm[j][ MOD(k-1,l) ](0) - contours_sm[j][ MOD(k-2,l) ](0) - contours_sm[j][k](0));
00349 contours_sm[j][k](0) += 0.5f * weight_smooth * (2.0f * contours_sm[j][ (k+1)%l ](0) - contours_sm[j][ (k+2)%l ](0) - contours_sm[j][k](0));
00350 change += fabs(before - contours_sm[j][k](0));
00351
00352
00353 before = contours_sm[j][k](1);
00354 contours_sm[j][k](1) += weight_data * (contours_[j][k](1) - contours_sm[j][k](1));
00355 contours_sm[j][k](1) += weight_smooth * (contours_sm[j][ MOD(k-1,l) ](1) + contours_sm[j][ (k+1)%l ](1) - (2.0f * contours_sm[j][k](1)));
00356 contours_sm[j][k](1) += 0.5f * weight_smooth * (2.0f * contours_sm[j][ MOD(k-1,l) ](1) - contours_sm[j][ MOD(k-2,l) ](1) - contours_sm[j][k](1));
00357 contours_sm[j][k](1) += 0.5f * weight_smooth * (2.0f * contours_sm[j][ (k+1)%l ](1) - contours_sm[j][ (k+2)%l ](1) - contours_sm[j][k](1));
00358 change += fabs(before - contours_sm[j][k](1));
00359 }
00360 ++num_iteration;
00361 }
00362 ROS_DEBUG_STREAM( "Needed " << num_iteration << " iterations for polygon of size " << l );
00363 }
00364 contours_ = contours_sm;
00365 }
00366
00367
00368
00369
00370
00371 void
00372 Polygon::getMergeCandidates(const std::vector<Polygon::Ptr>& poly_vec, std::vector<int>& intersections) const
00373 {
00374 for(size_t i=0; i< poly_vec.size(); ++i)
00375 {
00376
00377 if(this->hasSimilarParametersWith(poly_vec[i]) && this->isIntersectedWith(poly_vec[i])) intersections.push_back(i);
00378 }
00379 }
00380
00381 bool
00382 Polygon::isIntersectedWith(const Polygon::Ptr& poly) const
00383 {
00384 gpc_polygon *gpc_res = new gpc_polygon();
00385 this->getIntersection(poly, gpc_res);
00386 bool res = (gpc_res->num_contours != 0);
00387 gpc_free_polygon(gpc_res);
00388 return (res);
00389 }
00390
00391
00392 void
00393 Polygon::getIntersection(const Polygon::Ptr& poly, gpc_polygon* gpc_intersection) const
00394 {
00395
00396
00397
00398
00399
00400 std::vector<std::vector<Eigen::Vector2f> > contours_p;
00401 projectContour(*poly, contours_p);
00402
00403
00404
00405
00406
00407 gpc_polygon *gpc_poly = new gpc_polygon(), *gpc_here = new gpc_polygon();
00408 this->getGpcStructure(gpc_here, contours_);
00409 poly->getGpcStructure(gpc_poly, contours_p);
00410 gpc_polygon_clip(GPC_INT, gpc_here, gpc_poly, gpc_intersection);
00411 gpc_free_polygon(gpc_poly);
00412 gpc_free_polygon(gpc_here);
00413 }
00414
00415 bool
00416 Polygon::getContourOverlap(const Polygon::Ptr& poly, float& rel_overlap, int& abs_overlap) const
00417 {
00418 std::vector<std::vector<Eigen::Vector2f> > contours_p;
00419 projectContour(*poly, contours_p);
00420 gpc_polygon *gpc_a = new gpc_polygon(), *gpc_b = new gpc_polygon();
00421 gpc_polygon *gpc_res_int = new gpc_polygon(), *gpc_res_union = new gpc_polygon();
00422 this->getGpcStructure(gpc_a, contours_);
00423 poly->getGpcStructure(gpc_b, contours_p);
00424 gpc_polygon_clip(GPC_INT, gpc_a, gpc_b, gpc_res_int);
00425 gpc_polygon_clip(GPC_UNION, gpc_a, gpc_b, gpc_res_union);
00426
00427 int i_int = -1, i_union = -1;
00428 for(int i=0;i<gpc_res_int->num_contours;++i) { if(!gpc_res_int->hole[i]) { i_int = i; break; } }
00429 for(int i=0;i<gpc_res_union->num_contours;++i) { if(!gpc_res_union->hole[i]) { i_union = i; break; } }
00430 if(i_int == -1 || i_union == -1) return false;
00431 int overlap = 0;
00432 float d_th = pow( 0.01, 2 );
00433 for(int i=0;i<gpc_res_int->contour[i_int].num_vertices; ++i)
00434 {
00435 gpc_vertex* pv_int = &gpc_res_int->contour[i_int].vertex[i];
00436 for(int j=0;j<gpc_res_union->contour[i_union].num_vertices; ++j)
00437 {
00438 if( pow(gpc_res_union->contour[i_union].vertex[j].x - pv_int->x, 2) +
00439 pow(gpc_res_union->contour[i_union].vertex[j].y - pv_int->y, 2) < d_th )
00440 {
00441 ++overlap;
00442 break;
00443 }
00444 }
00445 }
00446 rel_overlap = (float)overlap/(float)gpc_res_int->contour[i_int].num_vertices;
00447 abs_overlap = overlap;
00448 ROS_DEBUG_STREAM("Overlap: " << overlap << "/"<<gpc_res_int->contour[i_int].num_vertices << " -> "
00449 << (float)overlap/(float)gpc_res_int->contour[i_int].num_vertices );
00450 gpc_free_polygon(gpc_a);
00451 gpc_free_polygon(gpc_b);
00452 gpc_free_polygon(gpc_res_int);
00453 gpc_free_polygon(gpc_res_union);
00454 return true;
00455 }
00456
00457
00458 float
00459 Polygon::computeSimilarity(const Polygon::Ptr& poly) const
00460 {
00461 float normal = (fabs(poly->normal_.dot(this->normal_)) - this->merge_settings_.angle_thresh) /
00462 (1-this->merge_settings_.angle_thresh);
00463 float d = fabs(fabs((this->pose_.translation()-poly->pose_.translation()).head(3).dot(this->normal_))-this->merge_settings_.d_thresh) /
00464 this->merge_settings_.d_thresh;
00465 float overlap = 0.0;
00466 int abs_overlap;
00467 this->getContourOverlap(poly, overlap, abs_overlap);
00468 return ( 3.0f / (1.0f / normal + 1.0f / d + 1.0f / overlap) );
00469 }
00470
00471 void
00472 Polygon::merge(std::vector<Polygon::Ptr>& poly_vec)
00473 {
00474 assignID(poly_vec);
00475
00476 Polygon::Ptr p_average = Polygon::Ptr(new Polygon);
00477 computeAverage(poly_vec, p_average);
00478 mergeUnion(poly_vec, p_average);
00479 assignWeight();
00480
00481 }
00482
00483 void
00484 Polygon::mergeDifference(Polygon::Ptr& p_merge)
00485 {
00486 std::vector<std::vector<Eigen::Vector2f> > contours_p;
00487 p_merge->projectContour(*this, contours_p);
00488 gpc_polygon *gpc_C = new gpc_polygon;
00489 this->getGpcStructure(gpc_C, contours_p);
00490
00491
00492 gpc_polygon *gpc_B = new gpc_polygon;
00493 p_merge->getGpcStructure(gpc_B, p_merge->contours_);
00494
00495 gpc_polygon_clip(GPC_DIFF, gpc_C, gpc_B, gpc_B);
00496
00497 gpc_free_polygon(gpc_C);
00498
00499
00500 p_merge->applyGpcStructure(gpc_B);
00501 gpc_free_polygon(gpc_B);
00502
00503 }
00504
00505 void
00506 Polygon::mergeUnion(std::vector<Polygon::Ptr>& poly_vec, Polygon::Ptr& p_average)
00507 {
00508
00509
00510 d_color_.reset();
00511
00512 std::vector<std::vector<Eigen::Vector2f> > contours;
00513 p_average->projectContour(*this, contours);
00514
00515
00516
00517
00518
00519
00520
00521 gpc_polygon *gpc_C = new gpc_polygon, *smoothed = new gpc_polygon;
00522 this->getGpcStructure(gpc_C, contours);
00523
00524 double min_weight = this->merge_weight_;
00525 for(size_t i=0;i<poly_vec.size();++i)
00526 {
00527 if(poly_vec[i]->merge_weight_ < min_weight)
00528 min_weight = poly_vec[i]->merge_weight_;
00529 }
00530 double normalizer = 1/min_weight;
00531
00532 for(size_t i=0;i<poly_vec.size();++i)
00533 {
00534 std::vector<std::vector<Eigen::Vector2f> > contours_p;
00535 p_average->projectContour(*poly_vec[i], contours_p);
00536
00537
00538
00539
00540
00541
00542
00543 gpc_polygon *gpc_B = new gpc_polygon;
00544 poly_vec[i]->getGpcStructure(gpc_B, contours_p);
00545 gpc_polygon_clip(GPC_UNION, gpc_B, gpc_C, gpc_C);
00546 gpc_free_polygon(gpc_B);
00547 d_color_.addColor(poly_vec[i]->color_[0]*255,poly_vec[i]->color_[1]*255,poly_vec[i]->color_[2]*255, round(normalizer*poly_vec[i]->merge_weight_));
00548
00549 }
00550 d_color_.addColor(this->color_[0]*255,this->color_[1]*255,this->color_[2]*255,round(normalizer*this->merge_weight_));
00551
00552
00553
00554
00555
00556
00557 setParamsFrom(p_average);
00558
00559
00560
00561
00562 this->applyGpcStructure(gpc_C);
00563 gpc_free_polygon(gpc_C);
00564
00565
00566
00567
00568
00569
00570
00571
00572 uint8_t r,g,b;
00573 d_color_.getColor(r,g,b);
00574
00575 float temp_inv = 1.0f/255.0f;
00576
00577 this->color_[0] = r * temp_inv;
00578 this->color_[1] = g * temp_inv;
00579 this->color_[2] = b * temp_inv;
00580
00581 }
00582
00583 void
00584 Polygon::projectContour(const Polygon& p, std::vector<std::vector<Eigen::Vector2f> >& contours) const
00585 {
00586
00587
00588 for(unsigned int i = 0; i < p.contours_.size(); i++)
00589 {
00590 std::vector<Eigen::Vector2f> c;
00591 for(unsigned int j = 0; j < p.contours_[i].size(); j++)
00592 {
00593
00594 Eigen::Vector2f pt_p = (pose_.inverse() * p.pose_ * Eigen::Vector3f(p.contours_[i][j](0), p.contours_[i][j](1), 0)).head(2);
00595 c.push_back(pt_p);
00596
00597 }
00598 contours.push_back(c);
00599 }
00600 }
00601
00602 void
00603 Polygon::assignWeight()
00604 {
00605 if (std::strcmp(merge_settings_.weighting_method.c_str(), "COUNTER") == 0)
00606 {
00607 merge_weight_ = merged_;
00608 }
00609 else if (std::strcmp(merge_settings_.weighting_method.c_str(), "AREA") == 0)
00610 {
00611 double area = computeArea3d();
00612 merge_weight_ = (merged_ * area);
00613 }
00614 }
00615
00616 void
00617 Polygon::assignID(const std::vector<Polygon::Ptr>& poly_vec)
00618 {
00619 unsigned int tmp_id = poly_vec[0]->id_;
00620 for(size_t i = 0; i < poly_vec.size(); ++i)
00621 {
00622 if(poly_vec[i]->id_ < tmp_id) tmp_id = poly_vec[i]->id_;
00623 }
00624 this->id_ = tmp_id;
00625 }
00626
00627 void
00628 Polygon::computeAverage(const std::vector<Polygon::Ptr>& poly_vec, Polygon::Ptr & p_average)
00629 {
00630
00631
00632 Eigen::Vector3f average_normal = normal_*merge_weight_;
00633 Eigen::Vector3f average_centroid = pose_.translation()*merge_weight_;
00634 double average_d = d_*merge_weight_;
00635 double sum_w = merge_weight_;
00636 unsigned int sum_merged = merged_;
00637
00638
00639
00640
00641 for(int i=0 ; i< (int) poly_vec.size();i++)
00642 {
00643 Polygon& p_map1 =*(poly_vec[i]);
00644
00645 if(normal_.dot(p_map1.normal_) < 0)
00646 {
00647 average_normal += p_map1.merge_weight_* -p_map1.normal_;
00648 }
00649 else
00650 {
00651 average_normal += p_map1.merge_weight_* p_map1.normal_;
00652 }
00653 average_centroid += p_map1.merge_weight_* p_map1.pose_.translation();
00654
00655
00656 average_d += p_map1.merge_weight_ * p_map1.d_;
00657 sum_w += p_map1.merge_weight_;
00658 sum_merged += p_map1.merged_;
00659 }
00660
00661 average_normal = average_normal/sum_w;
00662 average_centroid = average_centroid/sum_w;
00663 average_d = average_d/sum_w;
00664 average_normal.normalize();
00665
00666 if (sum_merged < merged_limit_)
00667 {
00668 p_average->merged_ = sum_merged;
00669 }
00670 else
00671 {
00672 p_average->merged_ = merged_limit_;
00673 }
00674
00675
00676 p_average->updateAttributes(average_normal, average_centroid);
00677
00678 }
00679
00680 void
00681 Polygon::setParamsFrom(Polygon::Ptr& p)
00682 {
00683 this->pose_ = p->pose_;
00684 this->d_ = p->d_;
00685 this->normal_ = p->normal_;
00686 if(this->merged_ < 9) { this->merged_ = p->merged_; }
00687 else { this->merged_ = 9; }
00688 }
00689
00690 void
00691 Polygon::getGpcStructure(gpc_polygon* gpc_p, const std::vector<std::vector<Eigen::Vector2f> >& contours) const
00692 {
00693
00694
00695
00696
00697 gpc_p->num_contours = contours.size();
00698 gpc_p->hole = (int*)malloc(contours.size()*sizeof(int));
00699 gpc_p->contour = (gpc_vertex_list*)malloc(contours.size()*sizeof(gpc_vertex_list));
00700 for(size_t j = 0; j<contours.size(); ++j)
00701 {
00702 gpc_p->hole[j] = holes_[j];
00703 gpc_p->contour[j].num_vertices = contours[j].size();
00704 gpc_p->contour[j].vertex = (gpc_vertex*)malloc(gpc_p->contour[j].num_vertices*sizeof(gpc_vertex));
00705
00706 for(size_t k = 0; k < contours[j].size(); ++k)
00707 {
00708
00709 gpc_p->contour[j].vertex[k].x = contours[j][k](0);
00710 gpc_p->contour[j].vertex[k].y = contours[j][k](1);
00711 }
00712 }
00713 }
00714
00715
00716 void
00717 Polygon::applyGpcStructure(const gpc_polygon* gpc_p)
00718 {
00719
00720 this->contours_.clear();
00721 this->holes_.clear();
00722 for(int j = 0; j < gpc_p->num_contours; ++j)
00723 {
00724 this->contours_.push_back(std::vector<Eigen::Vector2f>());
00725 this->holes_.push_back(gpc_p->hole[j]);
00726 float last_x = 0.0, last_y = 0.0;
00727 for (int k = 0; k < gpc_p->contour[j].num_vertices; ++k)
00728 {
00729
00730 if (fabs(gpc_p->contour[j].vertex[k].x - last_x) < 0.01 && fabs(gpc_p->contour[j].vertex[k].y - last_y) < 0.01)
00731 continue;
00732 last_x = gpc_p->contour[j].vertex[k].x;
00733 last_y = gpc_p->contour[j].vertex[k].y;
00734 this->contours_.back().push_back(Eigen::Vector2f(last_x,last_y));
00735 }
00736
00737 if (this->contours_.back().size() <= 2)
00738 {
00739 this->contours_.pop_back();
00740 this->holes_.pop_back();
00741 }
00742 }
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 void
00760 Polygon::computePose(std::vector<std::vector<Eigen::Vector3f> >& contours_3d)
00761 {
00762 Eigen::Vector3f origin = d_*normal_;
00763
00764
00765
00766 Eigen::Affine3f t;
00767 pcl::getTransformationFromTwoUnitVectorsAndOrigin(normal_.unitOrthogonal(), normal_, origin, t);
00768 pose_ = t.inverse();
00769 }
00770
00771 Eigen::Vector3f
00772 Polygon::computeCentroid()
00773 {
00774 std::vector<std::vector<Eigen::Vector3f> > contours_3d = getContours3D();
00775 return computeCentroid(contours_3d);
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 }
00803
00804 Eigen::Vector3f
00805 Polygon::computeCentroid(std::vector<std::vector<Eigen::Vector3f> >& contours_3d)
00806 {
00807
00808 unsigned int idx = 0;
00809 for (unsigned int i = 0; i < contours_3d.size (); i++)
00810 {
00811 int max_pts = 0;
00812 if(!holes_[i])
00813 {
00814 if((int)contours_3d[i].size()>(int)max_pts)
00815 {
00816 max_pts = contours_3d[i].size();
00817 idx = i;
00818 }
00819 }
00820 }
00821 pcl::PointCloud<pcl::PointXYZ> poly_cloud;
00822 for (unsigned int j = 0; j < contours_3d[idx].size () ; j++)
00823 {
00824 pcl::PointXYZ p;
00825 p.getVector3fMap() = contours_3d[idx][j];
00826 poly_cloud.push_back(p);
00827 }
00828 Eigen::Vector4f centroid;
00829 pcl::compute3DCentroid(poly_cloud, centroid);
00830 return centroid.head(3);
00831 }
00832
00833
00834 double
00835 Polygon::computeArea3d() const
00836 {
00837 double area = 0;
00838
00839 list<TPPLPoly> tri_list;
00840 triangulate(tri_list);
00841 for (std::list<TPPLPoly>::iterator it = tri_list.begin (); it != tri_list.end (); it++)
00842 {
00843 TPPLPoint pt1 = it->GetPoint(0);
00844 TPPLPoint pt2 = it->GetPoint(1);
00845 TPPLPoint pt3 = it->GetPoint(2);
00846 area += 0.5*fabs((pt2.x - pt1.x)*(pt3.y - pt1.y) - (pt3.x -pt1.x)*(pt2.y - pt1.y));
00847 }
00848 return area;
00849 }
00850
00851 void
00852 Polygon::triangulate(list<TPPLPoly>& tri_list) const
00853 {
00854 TPPLPartition pp;
00855 list<TPPLPoly> polys;
00856 TPPLPoly poly;
00857 TPPLPoint pt;
00858
00859 for(size_t j=0;j<contours_.size();j++)
00860 {
00861 poly.Init(contours_[j].size());
00862 poly.SetHole(holes_[j]);
00863 for(size_t i=0; i<contours_[j].size(); ++i)
00864 {
00865 pt.x = contours_[j][i](0);
00866 pt.y = contours_[j][i](1);
00867 poly[i] = pt;
00868 }
00869 if (holes_[j])
00870 poly.SetOrientation(TPPL_CW);
00871 else
00872 poly.SetOrientation(TPPL_CCW);
00873 polys.push_back(poly);
00874 }
00875
00876 pp.Triangulate_EC (&polys, &tri_list);
00877 }
00878
00879
00880
00881 void Polygon::debugOutput(std::string name)
00882 {
00883 std::string path = "/home/goa-tz/debug/dbg/";
00884 path.append(name.c_str());
00885 std::ofstream os(path.c_str());
00886
00887 for (int i = 0; i < (int) this->contours_.size(); ++i)
00888 {
00889 for (int j = 0; j < (int) this->contours_[i].size(); ++j)
00890 {
00891 os << contours_[i][j] << std::endl;
00892 }
00893 }
00894
00895 os.close();
00896 }
00897
00898 }
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012