我试图计算2个多边形之间的差异(事实上,为简单起见,直线形状)。例如,shape1具有点列表{0 0,100,0,100 100,0 100},并且shape2具有点列表{25 25,75 25,75 75,25 75}。 所以按照概念,我期待" shape1 - shape2"将为我提供4个矩形盒子,可以制作戒指或圆环形状。我不知道如何实现这一目标,但我发现"提升"图书馆在线并尝试过这样:
#include <iostream>
#include <list>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/foreach.hpp>
int main()
{
typedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > polygon;
polygon green, blue;
boost::geometry::read_wkt( "POLYGON((0 0 100 0 100 100 0 100))", green);
boost::geometry::read_wkt( "POLYGON((25 25 75 22 75 75 25 75))", blue);
std::list<polygon> output;
boost::geometry::difference(green, blue, output);
int i = 0;
std::cout << "green - blue:" << std::endl;
BOOST_FOREACH(polygon const& p, output)
{
std::cout << i++ << ": " << boost::geometry::area(p) << std::endl;
}
output.clear();
boost::geometry::difference(blue, green, output);
i = 0;
std::cout << "blue - green:" << std::endl;
BOOST_FOREACH(polygon const& p, output)
{
std::cout << i++ << ": " << boost::geometry::area(p) << std::endl;
}
return 0;
}
然而,没有打印出来...我的计划是找出一种方法将输出结果转换为矩形框{0 0 100 0 100 25 0 25} {0 75 100 75 100 100 0 100} {0 25 25 25 25 75 0 75}和{75 25 100 25 100 75 75 75},但我感到沮丧的是,上述代码根本没有打印出来。 谁能给我一些指导? 我附上了一张图片,展示了我想做的事情。事实上,我已经拥有了代表这个甜甜圈的所有点坐标,所以也许我可以跳过&#34;差异()函数&#34; ?如果是这种情况,困难的部分将是将甜甜圈转换成矩形段。 (我们假设这里的所有多边形都是直线形状。) 感谢。
答案 0 :(得分:0)
您的起始多边形没有所需的方向。您可以使用is_valid
自行查找。方便的是,您可以使用correct
来解决输入数据中最常见的问题:
std::string reason;
if (!bg::is_valid(geometry, reason))
{
std::cout << "Correcting " << bg::wkt(geometry) << " to ";
bg::correct(geometry);
std::cout << bg::wkt(geometry) << "\n";
if (!bg::is_valid(geometry, reason))
std::cout << "UNCORRECTIBLE: " << reason << "\n";
}
当你这样做时,你会发现:
Correcting POLYGON((0 0,100 0,100 100,0 100,0 0)) to POLYGON((0 0,0 100,100 100,100 0,0 0))
Correcting POLYGON((25 25,75 22,75 75,25 75,25 25)) to POLYGON((25 25,25 75,75 75,75 22,25 25))
现在,当你得到差异时,你将得到预期的结果:
auto do_diff = [](std::string caption, auto const& a, auto const& b) {
multi output;
bg::difference(a, b, output);
std::cout << caption << bg::wkt(output) << std::endl;
};
do_diff("green - blue:", green, blue);
do_diff("blue - green:", blue, green);
<强> Live On Coliru 强>
#include <iostream>
#include <fstream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/foreach.hpp>
namespace bg = boost::geometry;
int main() {
typedef bg::model::d2::point_xy<double> point;
typedef bg::model::polygon<point> polygon;
typedef bg::model::multi_polygon<polygon> multi;
polygon green, blue;
bg::read_wkt("POLYGON((0 0 100 0 100 100 0 100))", green);
bg::read_wkt("POLYGON((25 25 75 22 75 75 25 75))", blue);
auto test = [](polygon& geometry) {
std::string reason;
if (!bg::is_valid(geometry, reason))
{
std::cout << "Correcting " << bg::wkt(geometry) << " to ";
bg::correct(geometry);
std::cout << bg::wkt(geometry) << "\n";
if (!bg::is_valid(geometry, reason))
std::cout << "UNCORRECTIBLE: " << reason << "\n";
}
};
test(green);
test(blue);
auto do_diff = [](std::string caption, polygon const& a, polygon const& b) {
multi output;
bg::difference(a, b, output);
std::cout << caption << bg::wkt(output) << std::endl;
};
do_diff("green - blue:", green, blue);
do_diff("blue - green:", blue, green);
{
std::ofstream svg("output.svg");
boost::geometry::svg_mapper<point> mapper(svg, 400, 400);
mapper.add(blue);
mapper.add(green);
mapper.map(blue, "fill-opacity:0.5;fill:rgb(0,0,153);stroke:rgb(0,0,200);stroke-width:2");
mapper.map(green, "fill-opacity:0.5;fill:rgb(0,153,0);stroke:rgb(0,200,0);stroke-width:2");
}
}
打印
Correcting POLYGON((0 0,100 0,100 100,0 100,0 0)) to POLYGON((0 0,0 100,100 100,100 0,0 0))
Correcting POLYGON((25 25,75 22,75 75,25 75,25 25)) to POLYGON((25 25,25 75,75 75,75 22,25 25))
green - blue:MULTIPOLYGON(((0 0,0 100,100 100,100 0,0 0),(25 25,75 22,75 75,25 75,25 25)))
blue - green:MULTIPOLYGON()
并写svg:
答案 1 :(得分:0)
other answer将结束你的沮丧/困惑,这个答案会让你更有成效:)
而且,是的,你可以跳过差异函数:
bg::read_wkt("POLYGON((0 0 0 100 100 100 100 0 0 0) (25 25 75 22 75 75 25 75 25 25))", donut);
指定内环(反方向!)。
结果:
由该程序生成:
<强> Live On Coliru 强>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <iostream>
#include <fstream>
namespace bg = boost::geometry;
int main() {
typedef bg::model::d2::point_xy<double> point;
typedef bg::model::polygon<point> polygon;
polygon donut;
bg::read_wkt("POLYGON((0 0 0 100 100 100 100 0 0 0) (25 25 75 22 75 75 25 75 25 25))", donut);
std::ofstream svg("output.svg");
boost::geometry::svg_mapper<point> mapper(svg, 400, 400);
mapper.add(donut);
mapper.map(donut, "fill-opacity:0.5;fill:rgb(0,0,153);stroke:rgb(0,0,200);stroke-width:2");
}