user1496491
user1496491

Reputation: 583

Cutting geometries into pieces using boost

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.

cut result

enter image description here

So, translating the input data to a isomorphic test case in code:

Live On Coliru

#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:

enter image description here

Upvotes: 1

Views: 857

Answers (1)

user4290866
user4290866

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: enter image description here 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

Related Questions