diff options
Diffstat (limited to 'src/boost/libs/geometry/example/06_b_transformation_example.cpp')
-rw-r--r-- | src/boost/libs/geometry/example/06_b_transformation_example.cpp | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/boost/libs/geometry/example/06_b_transformation_example.cpp b/src/boost/libs/geometry/example/06_b_transformation_example.cpp new file mode 100644 index 000000000..ad7f75b33 --- /dev/null +++ b/src/boost/libs/geometry/example/06_b_transformation_example.cpp @@ -0,0 +1,167 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Example: Affine Transformation (translate, scale, rotate) +// +// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#include <ctime> // for std::time +#include <algorithm> +#include <fstream> +#include <iostream> +#include <limits> +#include <sstream> + +#include <boost/geometry/geometry.hpp> +#include <boost/geometry/geometries/point_xy.hpp> +#include <boost/geometry/geometries/polygon.hpp> +#include <boost/geometry/algorithms/centroid.hpp> +#include <boost/geometry/strategies/transform.hpp> +#include <boost/geometry/strategies/transform/matrix_transformers.hpp> +#include <boost/geometry/io/wkt/read.hpp> + +#if defined(HAVE_SVG) +# include <boost/geometry/io/svg/write.hpp> +#endif + +#include <boost/random.hpp> +#include <boost/range.hpp> +#include <boost/shared_ptr.hpp> + +using namespace boost::geometry; + +struct random_style +{ + random_style() + : rng(static_cast<int>(std::time(0))), dist(0, 255), colour(rng, dist) + {} + + std::string fill(double opacity = 1) + { + std::ostringstream oss; + oss << "fill:rgba(" << colour() << "," << colour() << "," << colour() << "," << opacity << ");"; + return oss.str(); + } + + std::string stroke(int width, double opacity = 1) + { + std::ostringstream oss; + oss << "stroke:rgba(" << colour() << "," << colour() << "," << colour() << "," << opacity << ");"; + oss << "stroke-width:" << width << ";"; + return oss.str(); + } + + template <typename T> + std::string text(T x, T y, std::string const& text) + { + std::ostringstream oss; + oss << "<text x=\"" << static_cast<int>(x) - 90 << "\" y=\"" << static_cast<int>(y) << "\" font-family=\"Verdana\">" << text << "</text>"; + return oss.str(); + } + + boost::mt19937 rng; + boost::uniform_int<> dist; + boost::variate_generator<boost::mt19937&, boost::uniform_int<> > colour; +}; + +template <typename OutputStream> +struct svg_output +{ + svg_output(OutputStream& os, double opacity = 1) : os(os), opacity(opacity) + { + os << "<?xml version=\"1.0\" standalone=\"no\"?>\n" + << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n" + << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n" + << "<svg width=\"100%\" height=\"100%\" version=\"1.1\"\n" + << "xmlns=\"http://www.w3.org/2000/svg\">" << std::endl; + } + + ~svg_output() + { + os << "</svg>" << std::endl; + } + + template <typename G> + void put(G const& g, std::string const& label) + { + std::string style_str(style.fill(opacity) + style.stroke(5, opacity)); +#if defined(HAVE_SVG) + os << boost::geometry::svg(g, style_str) << std::endl; +#endif + if (!label.empty()) + { + typename point_type<G>::type c; + centroid(g, c); + os << style.text(static_cast<int>(get<0>(c)), static_cast<int>(get<1>(c)), label); + } + } + +private: + + OutputStream& os; + double opacity; + random_style style; +}; + + +int main() +{ + using namespace boost::geometry::strategy::transform; + + typedef boost::geometry::model::d2::point_xy<double> point_2d; + + try + { + std::string file("06_b_transformation_example.svg"); + std::ofstream ofs(file.c_str()); + svg_output<std::ofstream> svg(ofs, 0.5); + + // G1 - create subject for affine transformations + model::polygon<point_2d> g1; + read_wkt("POLYGON((50 250, 400 250, 150 50, 50 250))", g1); + std::clog << "source box:\t" << boost::geometry::dsv(g1) << std::endl; + svg.put(g1, "g1"); + + // G1 - Translate -> G2 + translate_transformer<double, 2, 2> translate(0, 250); + model::polygon<point_2d> g2; + transform(g1, g2, translate); + std::clog << "translated:\t" << boost::geometry::dsv(g2) << std::endl; + svg.put(g2, "g2=g1.translate(0,250)"); + + // G2 - Scale -> G3 + scale_transformer<double, 2, 2> scale(0.5, 0.5); + model::polygon<point_2d> g3; + transform(g2, g3, scale); + std::clog << "scaled:\t" << boost::geometry::dsv(g3) << std::endl; + svg.put(g3, "g3=g2.scale(0.5,0.5)"); + + // G3 - Combine rotate and translate -> G4 + rotate_transformer<degree, double, 2, 2> rotate(45); + + // Compose matrix for the two transformation + // Create transformer attached to the transformation matrix + matrix_transformer<double, 2, 2> combined(rotate.matrix() * translate.matrix()); + + // Apply transformation to subject geometry point-by-point + model::polygon<point_2d> g4; + transform(g3, g4, combined); + + std::clog << "rotated & translated:\t" << boost::geometry::dsv(g4) << std::endl; + svg.put(g4, "g4 = g3.(rotate(45) * translate(0,250))"); + + std::clog << "Saved SVG file:\t" << file << std::endl; + } + catch (std::exception const& e) + { + std::cerr << e.what() << std::endl; + } + catch (...) + { + std::cerr << "unknown error" << std::endl; + } + return 0; +} |