Boost.Geometry GSoC 2019 Competency Test - Project 4

The following shows the usage of the proposed uniform point sampler. The required library code can be found here:

random/subsets.hpp
random/detail/uniform_point_distribution.hpp
random/dispatch/uniform_point_distribution.hpp
random/uniform_point_distribution.hpp

Output file: random_samples_interior.svg

main.cpp


#include <random>
#include <iostream>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/extensions/random/uniform_point_distribution.hpp>
#include <fstream>

namespace bg = boost::geometry;

template<typename Point, typename Geometry, typename Generator>
void sample_and_write(Geometry const& g, std::size_t in, Generator& gen, bg::svg_mapper<Point>& mapper)
{
    auto dist = bg::random::uniform_point_distribution(g);
    std::vector<typename bg::point_type<Geometry>::type> out;
    out.resize(in);
    std::generate(out.begin(), out.end(), std::bind(dist, std::ref(gen)));

    mapper.add(g);
    for(const auto& p : out) {
        mapper.add(p);
    }
    mapper.map(g, "opacity:0.4;fill:none;stroke:rgb(212,0,0);stroke-width:1");
    for(const auto& p : out) {
        mapper.map(p, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:1",1);
    }
}

int main() {
    typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
    typedef bg::model::multi_point<point_t> multi_point_t;
    typedef bg::model::polygon<point_t> polygon_t;
    typedef bg::model::linestring<point_t> linestring_t;
    typedef bg::model::multi_linestring<linestring_t> multi_linestring_t;
    typedef bg::model::box<point_t> box_t;
    polygon_t poly{{{2,1.3},{2.4,1.7},{2.8,1.8},{3.4,1.2},{3.7,1.6},{3.4,2},{4.1,3},{5.3,2.6},{5.4,1.2},{4.9,0.8},{2.9,0.7},{2,1.3}},
            {{4.0,2.0},{4.2,1.4},{4.8,1.9},{4.4,2.2},{4.0,2.0}}};
    multi_point_t mp;
    for(double y=0.0; y<0.6; y+=0.1) {
        for(double x=3.6; x<4.5; x+=0.1) {
            bg::append(mp, point_t(x, y));
        }
    }

    multi_linestring_t mls;
    for(double x = 3.5; x<4.5; x+=0.05) {
        linestring_t ls_open{{x, 3.25}, {x+0.05, 3.3}, {x, 3.35}};
        linestring_t ls_closed{{x, 3.1}, {x+0.02, 3.15}, {x, 3.2}, {x-0.02, 3.15}, {x, 3.1} };
        mls.push_back(ls_open);
        mls.push_back(ls_closed);
    }
    box_t b{{5.5, 1.0}, {6.5, 2.0}};

    std::ofstream svg("random_samples_interior.svg");
    bg::svg_mapper<point_t> mapper(svg, 800, 800);

    std::random_device rd;
    std::mt19937 gen(rd());
    sample_and_write(poly, 1000, gen, mapper);
    sample_and_write(b, 50, gen, mapper);
    sample_and_write(mls, 20, gen, mapper);
    auto dist = bg::random::uniform_point_distribution(mp);
    std::vector<point_t> out;
    out.resize(10);
    std::generate(out.begin(), out.end(), std::bind(dist, std::ref(gen)));
    for(const auto& p : out) {
        mapper.add(p);
    }
    for(const auto& p : out) {
        mapper.map(p, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:1",1);
    }
    mapper.add(mp);
    mapper.map(mp, "opacity:0.4;fill:none;stroke:rgb(212,0,0);stroke-width:1");

    return 0;
}