我遵循CGAL文档的这个示例,以简化许多多边形,这些多边形最初存储在一个名为polys
的向量中。之后,我将简化的多边形收集到一个名为simple_polys
的向量中。然而,在简化过程中,多边形的顺序被混淆了。这意味着simple_polys[i]
不一定是polys[i]
的简化版本。我将感谢任何关于如何调整我的代码的想法(见下文),以便保持或恢复多边形的顺序。
注意到:简化每个多边形的明显解决方案对我来说不是一个选项,因为我需要保留多边形的公共边(如果有的话),即允许简化公共边,但它们必须保持公共边。
下面是我的代码的当前版本:
#include <vector>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
#include <CGAL/Polyline_simplification_2/simplify.h>
#include <CGAL/Polyline_simplification_2/Squared_distance_cost.h>
#include <CGAL/IO/WKT.h>
// CGAL typedefs
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
// CGAL classes needed for polyline simplification
namespace PS = CGAL::Polyline_simplification_2;
typedef PS::Vertex_base_2<Kernel> Vb;
typedef CGAL::Constrained_triangulation_face_base_2<Kernel> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> TDS;
typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, TDS, CGAL::Exact_predicates_tag> CDT;
typedef CGAL::Constrained_triangulation_plus_2<CDT> CT;
typedef PS::Stop_above_cost_threshold Stop;
typedef PS::Squared_distance_cost Cost;
int main()
{
// Read the polygons from WTK file
std::ifstream is("polys.wkt");
std::vector<Polygon_2> polys;
do {
Polygon_2 p;
CGAL::IO::read_polygon_WKT(is, p);
if(!p.is_empty())
polys.push_back(p);
} while(is.good() && !is.eof());
// Insert the polygons into a Constrained_triangulation_plus_2
CT ct;
for ( auto poly : polys ) ct.insert_constraint(poly);
// Simplify the polygons
PS::simplify(ct, Cost(), Stop(2.0));
// Convert the result back into normal polygons
std::vector<Polygon_2> simple_polys;
for( CT::Constraint_iterator cit = ct.constraints_begin(); cit != ct.constraints_end(); ++cit)
{
Polygon_2 poly;
for ( CT::Points_in_constraint_iterator vit = ct.points_in_constraint_begin(*cit);
vit != ct.points_in_constraint_end(*cit); ++vit) poly.push_back(*vit);
simple_polys.push_back(poly);
}
}
下面是一个WKT输入文件的示例,可以用来运行上面的代码(命名为polys.wkt
):
POLYGON((46.465 -37.3521,35.5358 -20.6702,48.8869 -11.958,51.9866 -16.8288,50.0332 -18.1056,54.9318 -25.6487,55.8444 -25.0541,55.5429 -22.8841,73.1793 -11.5299,77.2208 -17.435))
POLYGON((150.934 48.3496,137.482 47.0145,136.581 54.533,134.581 54.3679,134.206 58.2453,136.107 58.4855,135.177 66.2472,148.772 67.1611))
POLYGON((113.969 -24.4624,103.013 -25.5321,102.007 -15.8837,101.437 -15.8568,101.143 -12.0671,101.652 -12.0653,100.581 -1.99834,107.794 -1.3459,107.853 -2.01614,111.495 -1.66637,111.568 -1.96882,111.947 -1.88637))
POLYGON((35.8102 -21.0888,27.2558 -8.05192,38.1005 -0.96724,44.4211 -10.2175,45.1996 -9.66818,45.021 -9.3973,45.5261 -7.35956,50.2289 -4.30611,50.4096 -3.43368,64.9678 6.02664,66.7379 -0.809735))
POLYGON((-1.28342 -115.889,22.725 -111.81,25.6615 -128.839,16.2488 -130.272,16.4807 -131.888,12.9582 -132.401,12.7173 -130.807,12.4127 -130.833,16.6721 -156.064,0.111882 -158.497,-1.28339 -150.737))
POLYGON((133.248 -68.93,100.825 -72.0011,99.8362 -61.4584,107.418 -60.8479,107.399 -60.397,110.68 -60.2175,110.691 -60.6869,120.743 -59.7579,120.696 -59.3589,124.041 -59.0963,124.058 -59.5348,132.275 -58.7058))
POLYGON((118.371 29.3127,111.786 28.6569,110.332 42.1233,117.682 42.8478,117.895 41.5415,118.397 41.5653,118.858 38.6083,118.3 38.521,118.704 35.4032,117.714 35.3187))
POLYGON((146.407 -67.6797,132.75 -68.9772,131.777 -58.752,135.766 -58.415,135.713 -57.87,138.974 -57.6063,139.028 -58.0592,145.445 -57.5652))
POLYGON((38.7765 -180.005,42.57 -177.511,39.8274 -173.17,45.4545 -169.387,34.4094 -152.557,47.1264 -144.271,47.0159 -144.108,51.1497 -141.344,53.8363 -145.461,55.5009 -144.64,58.878 -149.842,57.4133 -151.006,61.0026 -156.489,62.2453 -155.685,67.94 -140.543,85.4228 -166.825,64.2719 -180.516,60.9827 -175.481,56.3313 -178.594,57.1839 -179.899,44.1068 -188.413))
POLYGON((117.162 35.7683,136.609 37.8265,137.825 36.8336,138.697 36.9208,137.923 42.338,137.507 42.2789,137.23 44.2193,137.646 44.2784,137.59 44.664,137.165 44.6034,136.887 46.5429,137.314 46.6042,137.188 47.4854,150.877 48.8464,152.721 32.789,117.873 29.2627))
POLYGON((115.832 -45.2902,104.975 -46.2859,104.142 -37.6361,103.622 -37.7286,103.332 -34.3286,103.777 -34.0371,102.964 -25.0344,113.924 -23.9644))
POLYGON((66.5341 -28.0144,70.402 -33.9903,70.291 -34.3719,60.4063 -40.7947,59.9046 -40.7393,56.0238 -34.773,56.1665 -34.3699,56.3403 -34.274,66.1632 -27.8986))
POLYGON((105.673 -127.635,90.8711 -104.911,92.492 -102.406,115.3 -100.248,116.48 -111.052,112.586 -111.576,112.605 -111.81,111.09 -112.735,110.572 -112.55,110.365 -112.893,115.687 -121.196))
POLYGON((152.194 5.74036,111.195 -2.55811,111.11 -2.20564,107.405 -2.56147,106.262 7.74335,143.459 15.1823,142.642 22.9693,142.005 22.9033,141.67 26.0846,142.307 26.1507,141.68 32.1367,152.665 33.2868,154.612 15.5801,151.26 15.2101,151.847 9.88508,151.738 9.87268))
POLYGON((22.9004 58.0935,-1.28339 56.2459,-1.28339 62.8131,-0.817275 62.867,-0.1184 63.6614,5.80649 64.1534,6.12005 64.7858,8.92235 65.0356,9.85597 64.4913,21.9914 65.718))
发布于 2022-08-05 10:20:25
我自己想出来了。我在这里发布解决方案,以防将来对其他人有用。解决方案是在向量polys
中的多边形索引与Constrained_triangulation_plus_2
对象中约束的in之间建立联系。下面是经过修改的代码,其中包括问题的解决方案。
#include <vector>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
#include <CGAL/Polyline_simplification_2/simplify.h>
#include <CGAL/Polyline_simplification_2/Squared_distance_cost.h>
#include <CGAL/IO/WKT.h>
// CGAL typedefs
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
// CGAL classes needed for polyline simplification
namespace PS = CGAL::Polyline_simplification_2;
typedef PS::Vertex_base_2<Kernel> Vb;
typedef CGAL::Constrained_triangulation_face_base_2<Kernel> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> TDS;
typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, TDS, CGAL::Exact_predicates_tag> CDT;
typedef CGAL::Constrained_triangulation_plus_2<CDT> CT;
typedef PS::Stop_above_cost_threshold Stop;
typedef PS::Squared_distance_cost Cost;
int main()
{
// Read the polygons from WTK file
std::ifstream is("polys.wkt");
std::vector<Polygon_2> polys;
do {
Polygon_2 p;
CGAL::IO::read_polygon_WKT(is, p);
if(!p.is_empty())
polys.push_back(p);
} while(is.good() && !is.eof());
// Insert the polygons into a Constrained_triangulation_plus_2 and keep
// track of the constraint IDs
CT ct;
std::vector<CT::Constraint_id> constraint_IDs;
for ( auto poly : polys )
{
CT::Constraint_id ID = ct.insert_constraint(poly);
constraint_IDs.push_back(ID);
}
// Simplify the polygons
PS::simplify(ct, Cost(), Stop(2.0));
// Convert the result back into normal polygons
std::vector<Polygon_2> simple_polys(polys.size());
for( CT::Constraint_iterator cit = ct.constraints_begin(); cit != ct.constraints_end(); ++cit)
{
// Find the index of the constraint ID in the constraint_IDs vector. This is the index
// of the original polygon the current simplified polygon corresponds to
auto it = std::find(constraint_IDs.begin(), constraint_IDs.end(), *cit);
size_t idx = it - constraint_IDs.begin();
// Obtain the simplified polygon
Polygon_2 poly;
for ( CT::Points_in_constraint_iterator vit = ct.points_in_constraint_begin(*cit);
vit != ct.points_in_constraint_end(*cit); ++vit) poly.push_back(*vit);
// Write the simplified polygon to the correct location
simple_polys[idx] = poly;
}
}
https://stackoverflow.com/questions/73247437
复制相似问题