Boost.Geometry:如何创建简单的多边形数组并将它们保存为SVG图像?

4

我看到了一个很棒的库,叫做Boost Geometry。我看了一下,但是没有发现任何关于至少有点图形化的东西的教程。所以我想知道是否有人能够提供一个简单的教程,来创建一些随机的多边形(颜色、大小和形状都是随机的),并将它们保存为像SVG这样的矢量图像?


这可能会有所帮助:https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.Plot - Khaled Alshaya
2个回答

11

所以...问题已解决:在谷歌上可以找到这个老代码。它将无法编译最新的boost 1.47.0版本。所以你需要尝试修复它,并且在一些过时的文档这里,你会知道如何修复它... 长话短说,这里是让它工作的步骤:

下载boost/geometry/extensions/io/svg/中的3个代码文件,它们只是头文件,所以不用担心。

现在,您可以编译经过修复、升级到当前boost版本的代码了:

#include <iostream>
#include <fstream>
#include <boost/assign.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/io/svg/write_svg.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/algorithms/envelope.hpp>

#include <boost/geometry/io/svg/write_svg.hpp>


template <typename Geometry1, typename Geometry2>
void create_svg(std::string const& filename, Geometry1 const& a, Geometry2 const& b)
{
    typedef typename boost::geometry::point_type<Geometry1>::type point_type;
    std::ofstream svg(filename.c_str());

    boost::geometry::svg_mapper<point_type> mapper(svg, 400, 400);
    mapper.add(a);
    mapper.add(b);

    mapper.map(a, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
    mapper.map(b, "opacity:0.8;fill:none;stroke:rgb(255,128,0);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round");
}

int main()
{
    using namespace boost::assign;


    boost::geometry::model::ring<boost::geometry::model::d2::point_xy<double> > ring;
    ring +=
        boost::geometry::model::d2::point_xy<double>(4.0, -0.5), boost::geometry::model::d2::point_xy<double>(3.5, 1.0),
        boost::geometry::model::d2::point_xy<double>(2.0, 1.5), boost::geometry::model::d2::point_xy<double>(3.5, 2.0),
        boost::geometry::model::d2::point_xy<double>(4.0, 3.5), boost::geometry::model::d2::point_xy<double>(4.5, 2.0),
        boost::geometry::model::d2::point_xy<double>(6.0, 1.5), boost::geometry::model::d2::point_xy<double>(4.5, 1.0),
        boost::geometry::model::d2::point_xy<double>(4.0, -0.5);


     boost::geometry::model::box<boost::geometry::model::d2::point_xy<double> > box;
     boost::geometry::envelope(ring, box); 
    std::cout
        << "make_envelope:"
        << boost::geometry::dsv(box)
        << std::endl;

    create_svg("make_envelope.svg", ring, box);
}

这将绘制出以下图形:

在此输入图像描述

(不是图片,而是可以在 Google Chrome 中打开的矢量 SVG 文件=)) 因此,这就是如何使用 C++ 创建 SVG 文件=)


+1谢谢您发布这个!看起来boost::geometry仍然在转换中,因为1.48版本中该目录仍不存在。 - kfmfe04
@Rella 是否有相应的read()操作?也就是说,如果我在SVG中绘制了一个多边形,如何将其读入到boost::geometry::model::polygon中? - David Doria
现代版本的Boost需要进行一些修改才能正常工作。我会在这里编辑并提供修改后的内容。 - Catskul

0

对于 boost >= 1.54 版本,我们现在正式支持从库中使用 boost::geometry::io::svg

#include <string>
#include <fstream>

#include <boost/geometry.hpp>


namespace bg = boost::geometry;
namespace bgm = boost::geometry::model;

using Point2D = bgm::d2::point_xy<double>;
using Polygon2D = bgm::polygon<Point2D>;


template <typename Geometry>
void create_svg(std::string const& file_path, Geometry const& geometry, std::string const& style) {
    using PointType = typename bg::point_type<Geometry>::type;
    std::ofstream svg_file(file_path.c_str());
    bg::svg_mapper<PointType> mapper(svg_file, 400, 400);
    mapper.add(geometry);
    mapper.map(geometry, style);
}

Polygon2D create_polygon(Point2D const& p1, Point2D const& p2, Point2D const& p3, Point2D const& p4) {
    // NOTE: For closed poly first point equal to the last
    return {{p1, p2, p3, p4, p1}};
}

int main() {
    auto const& polygon = create_polygon({0., 0.}, {0., 4.}, {7., 4.}, {7., 0.});
    std::string style{"fill-rule:nonzero;fill-opacity:0.5;fill:yellow;stroke:black;stroke-width:2;"};
    create_svg("image.svg", polygon, style);
    return 0;
}

这给了我们

enter image description here

玩游戏的完整代码可以在这里找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接