Reputation: 583
Is there any built-in instrument in boost::geometry
to cut geomtries like on the picture below? My idea is to find an intersection geometries, and substract them from both sources. But it feels like not the best solution, when there's more than 2 intersecting rectangles that shares same area.
So, translating the input data to a isomorphic test case in code:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/io/io.hpp>
#include <iostream>
#include <fstream>
namespace bg = boost::geometry;
namespace bgm = bg::model;
using point = bgm::d2::point_xy<int>;
using poly = bgm::polygon<point>;
using mpoly = bgm::multi_polygon<poly>;
int main()
{
poly a, b, c;
bg::read_wkt("POLYGON((0 0 0 6 6 6 6 0 0 0))", a);
bg::read_wkt("POLYGON((4 -1 4 4 5 4 5 -1 4 -1))", b);
bg::read_wkt("POLYGON((3 -3 3 3 9 3 9 -3 3 -3))", c);
std::cout << bg::wkt(a) << "\n";
std::cout << bg::wkt(b) << "\n";
std::cout << bg::wkt(c) << "\n";
{
std::ofstream svg("output.svg");
boost::geometry::svg_mapper<point> mapper(svg, 400, 400);
mapper.add(a);
mapper.add(b);
mapper.add(c);
mapper.map(a, "fill-opacity:0.2;fill:rgb(0,0,153);stroke:rgb(0,0,200);stroke-width:2");
mapper.map(b, "fill-opacity:0.2;fill:rgb(153,0,0);stroke:rgb(200,0,0);stroke-width:2");
mapper.map(c, "fill-opacity:0.2;fill:rgb(0,153,0);stroke:rgb(0,200,0);stroke-width:2");
}
}
Which reflects the following SVG:
Upvotes: 1
Views: 857
Reputation:
Consider the following code:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry.hpp>
#include <boost/foreach.hpp>
#include <boost/foreach.hpp>
namespace bg = boost::geometry;
namespace bgm = bg::model;
typedef bgm::d2::point_xy<int> point;
typedef bgm::polygon<point> poly;
typedef bgm::multi_polygon<poly> mpoly;
int main()
{
poly a, b, c;
bg::read_wkt("POLYGON((0 0 0 6 6 6 6 0 0 0))", a);
bg::read_wkt("POLYGON((4 -1 4 4 5 4 5 -1 4 -1))", b);
bg::read_wkt("POLYGON((3 -3 3 3 9 3 9 -3 3 -3))", c);
std::vector<poly> polies;
polies.push_back(a);
polies.push_back(b);
polies.push_back(c);
std::vector<poly> res;
for (size_t i = 0; i < polies.size(); ++i)
{
for (size_t j = i; j < polies.size(); ++j)
{
boost::geometry::model::multi_polygon<poly> output;
boost::geometry::union_(polies[i], polies[j], output);
for (auto it = output.begin(); it != output.end(); ++it)
{
res.push_back(*it);
}
}
}
for (size_t i = 0; i < polies.size(); ++i)
{
for (size_t j = i; j < polies.size(); ++j)
{
boost::geometry::model::multi_polygon<poly> multi;
boost::geometry::sym_difference(polies[i], polies[j], multi);
for (auto it = multi.begin(); it != multi.end(); ++it)
{
res.push_back(*it);
}
}
}
{
std::ofstream svg("output2.svg");
boost::geometry::svg_mapper<point> mapper(svg, 400, 400);
size_t i = 0;
BOOST_FOREACH(poly& p, res)
{
std::stringstream ss;
ss << ++i * 10;
std::stringstream ss2;
ss2 << 255 - i * 10;
mapper.add(p);
mapper.map(p, "fill-opacity:0.2;fill:rgb("+ ss.str() + "," + ss2.str() +",153);stroke:rgb(0,0,200);stroke-width:2");
}
}
return 0;
}
Which produces the following output:
For this, you have to run over all combinations and compute the unions and sym_differences of the initial polygons.
Sorry, the coloring is not as nice as yours.
Does this help?
Upvotes: 1