PageRenderTime 46ms CodeModel.GetById 14ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/libs/geometry/example/06_b_transformation_example.cpp

http://hadesmem.googlecode.com/
C++ | 170 lines | 126 code | 28 blank | 16 comment | 1 complexity | 787c2cbaea8d5c20e08b7b3f9c91d4cc MD5 | raw file
  1// Boost.Geometry (aka GGL, Generic Geometry Library)
  2// Example: Affine Transformation (translate, scale, rotate)
  3//
  4// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
  5//
  6// Use, modification and distribution is subject to the Boost Software License,
  7// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8// http://www.boost.org/LICENSE_1_0.txt)
  9
 10
 11#include <ctime> // for std::time
 12#include <algorithm>
 13#include <fstream>
 14#include <iostream>
 15#include <limits>
 16#include <sstream>
 17
 18#include <boost/geometry/geometry.hpp>
 19#include <boost/geometry/geometries/point_xy.hpp>
 20#include <boost/geometry/geometries/polygon.hpp>
 21#include <boost/geometry/algorithms/centroid.hpp>
 22#include <boost/geometry/strategies/transform.hpp>
 23#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
 24#include <boost/geometry/domains/gis/io/wkt/read_wkt.hpp>
 25
 26#if defined(HAVE_SVG)
 27#  include <boost/geometry/extensions/io/svg/write_svg.hpp>
 28#endif
 29
 30#include <boost/bind.hpp>
 31#include <boost/random.hpp>
 32#include <boost/range.hpp>
 33#include <boost/shared_ptr.hpp>
 34
 35using namespace boost::geometry;
 36
 37struct random_style
 38{
 39    random_style()
 40        : rng(static_cast<int>(std::time(0))), dist(0, 255), colour(rng, dist)
 41    {}
 42
 43    std::string fill(double opacity = 1)
 44    {
 45        std::ostringstream oss;
 46        oss << "fill:rgba(" << colour() << "," << colour() << "," << colour() << "," << opacity << ");";
 47        return oss.str();
 48    }
 49
 50    std::string stroke(int width, double opacity = 1)
 51    {
 52        std::ostringstream oss;
 53        oss << "stroke:rgba(" << colour() << "," << colour() << "," << colour() << "," << opacity << ");";
 54        oss << "stroke-width:" << width  << ";";
 55        return oss.str();
 56    }
 57
 58    template <typename T>
 59    std::string text(T x, T y, std::string const& text)
 60    {
 61        std::ostringstream oss;
 62        oss << "<text x=\"" << static_cast<int>(x) - 90 << "\" y=\"" << static_cast<int>(y) << "\" font-family=\"Verdana\">" << text << "</text>";
 63        return oss.str();
 64    }
 65
 66    boost::mt19937 rng;
 67    boost::uniform_int<> dist;
 68    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > colour;
 69};
 70
 71template <typename OutputStream>
 72struct svg_output
 73{
 74    svg_output(OutputStream& os, double opacity = 1) : os(os), opacity(opacity)
 75    {
 76        os << "<?xml version=\"1.0\" standalone=\"no\"?>\n"
 77            << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n"
 78            << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
 79            << "<svg width=\"100%\" height=\"100%\" version=\"1.1\"\n"
 80            << "xmlns=\"http://www.w3.org/2000/svg\">" << std::endl;
 81    }
 82
 83    ~svg_output()
 84    {
 85        os << "</svg>" << std::endl;
 86    }
 87
 88    template <typename G>
 89    void put(G const& g, std::string const& label)
 90    {
 91        std::string style_str(style.fill(opacity) + style.stroke(5, opacity));
 92#if defined(HAVE_SVG)
 93        os << boost::geometry::svg(g, style_str) << std::endl;
 94#endif
 95        if (!label.empty())
 96        {
 97            typename point_type<G>::type c;
 98            centroid(g, c);
 99            os << style.text(static_cast<int>(get<0>(c)), static_cast<int>(get<1>(c)), label);
100        }
101    }
102
103private:
104
105    OutputStream& os;
106    double opacity;
107    random_style style;
108};
109
110
111int main()
112{
113    using namespace boost::geometry::strategy::transform;
114
115    typedef boost::geometry::model::d2::point_xy<double> point_2d;
116
117    try
118    {
119        std::string file("06_b_transformation_example.svg");
120        std::ofstream ofs(file.c_str());
121        svg_output<std::ofstream> svg(ofs, 0.5);
122
123        // G1 - create subject for affine transformations
124        model::polygon<point_2d> g1;
125        read_wkt("POLYGON((50 250, 400 250, 150 50, 50 250))", g1);
126        std::clog << "source box:\t" << boost::geometry::dsv(g1) << std::endl;
127        svg.put(g1, "g1");
128
129        // G1 - Translate -> G2
130        translate_transformer<point_2d, point_2d> translate(0, 250);
131        model::polygon<point_2d> g2;
132        transform(g1, g2, translate);
133        std::clog << "translated:\t" << boost::geometry::dsv(g2) << std::endl;
134        svg.put(g2, "g2=g1.translate(0,250)");
135
136        // G2 - Scale -> G3
137        scale_transformer<point_2d, point_2d> scale(0.5, 0.5);
138        model::polygon<point_2d> g3;
139        transform(g2, g3, scale);
140        std::clog << "scaled:\t" << boost::geometry::dsv(g3) << std::endl;
141        svg.put(g3, "g3=g2.scale(0.5,0.5)");
142
143        // G3 - Combine rotate and translate -> G4
144        rotate_transformer<point_2d, point_2d, degree> rotate(45);
145
146        // Compose matrix for the two transformation
147        // Create transformer attached to the transformation matrix
148        ublas_transformer<point_2d, point_2d, 2, 2>
149                combined(boost::numeric::ublas::prod(rotate.matrix(), translate.matrix()));
150                //combined(rotate.matrix());
151
152        // Apply transformation to subject geometry point-by-point
153        model::polygon<point_2d> g4;
154        transform(g3, g4, combined);
155
156        std::clog << "rotated & translated:\t" << boost::geometry::dsv(g4) << std::endl;
157        svg.put(g4, "g4 = g3.(rotate(45) * translate(0,250))");
158
159        std::clog << "Saved SVG file:\t" << file << std::endl;
160    }
161    catch (std::exception const& e)
162    {
163        std::cerr << e.what() << std::endl;
164    }
165    catch (...)
166    {
167        std::cerr << "unknown error" << std::endl;
168    }
169    return 0;
170}