]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/example/06_b_transformation_example.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / geometry / example / 06_b_transformation_example.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Example: Affine Transformation (translate, scale, rotate)
3 //
4 // Copyright (c) 2009-2012 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/io/wkt/read.hpp>
25
26 #if defined(HAVE_SVG)
27 # include <boost/geometry/io/svg/write.hpp>
28 #endif
29
30 #include <boost/random.hpp>
31 #include <boost/range.hpp>
32 #include <boost/shared_ptr.hpp>
33
34 using namespace boost::geometry;
35
36 struct random_style
37 {
38 random_style()
39 : rng(static_cast<int>(std::time(0))), dist(0, 255), colour(rng, dist)
40 {}
41
42 std::string fill(double opacity = 1)
43 {
44 std::ostringstream oss;
45 oss << "fill:rgba(" << colour() << "," << colour() << "," << colour() << "," << opacity << ");";
46 return oss.str();
47 }
48
49 std::string stroke(int width, double opacity = 1)
50 {
51 std::ostringstream oss;
52 oss << "stroke:rgba(" << colour() << "," << colour() << "," << colour() << "," << opacity << ");";
53 oss << "stroke-width:" << width << ";";
54 return oss.str();
55 }
56
57 template <typename T>
58 std::string text(T x, T y, std::string const& text)
59 {
60 std::ostringstream oss;
61 oss << "<text x=\"" << static_cast<int>(x) - 90 << "\" y=\"" << static_cast<int>(y) << "\" font-family=\"Verdana\">" << text << "</text>";
62 return oss.str();
63 }
64
65 boost::mt19937 rng;
66 boost::uniform_int<> dist;
67 boost::variate_generator<boost::mt19937&, boost::uniform_int<> > colour;
68 };
69
70 template <typename OutputStream>
71 struct svg_output
72 {
73 svg_output(OutputStream& os, double opacity = 1) : os(os), opacity(opacity)
74 {
75 os << "<?xml version=\"1.0\" standalone=\"no\"?>\n"
76 << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n"
77 << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
78 << "<svg width=\"100%\" height=\"100%\" version=\"1.1\"\n"
79 << "xmlns=\"http://www.w3.org/2000/svg\">" << std::endl;
80 }
81
82 ~svg_output()
83 {
84 os << "</svg>" << std::endl;
85 }
86
87 template <typename G>
88 void put(G const& g, std::string const& label)
89 {
90 std::string style_str(style.fill(opacity) + style.stroke(5, opacity));
91 #if defined(HAVE_SVG)
92 os << boost::geometry::svg(g, style_str) << std::endl;
93 #endif
94 if (!label.empty())
95 {
96 typename point_type<G>::type c;
97 centroid(g, c);
98 os << style.text(static_cast<int>(get<0>(c)), static_cast<int>(get<1>(c)), label);
99 }
100 }
101
102 private:
103
104 OutputStream& os;
105 double opacity;
106 random_style style;
107 };
108
109
110 int main()
111 {
112 using namespace boost::geometry::strategy::transform;
113
114 typedef boost::geometry::model::d2::point_xy<double> point_2d;
115
116 try
117 {
118 std::string file("06_b_transformation_example.svg");
119 std::ofstream ofs(file.c_str());
120 svg_output<std::ofstream> svg(ofs, 0.5);
121
122 // G1 - create subject for affine transformations
123 model::polygon<point_2d> g1;
124 read_wkt("POLYGON((50 250, 400 250, 150 50, 50 250))", g1);
125 std::clog << "source box:\t" << boost::geometry::dsv(g1) << std::endl;
126 svg.put(g1, "g1");
127
128 // G1 - Translate -> G2
129 translate_transformer<double, 2, 2> translate(0, 250);
130 model::polygon<point_2d> g2;
131 transform(g1, g2, translate);
132 std::clog << "translated:\t" << boost::geometry::dsv(g2) << std::endl;
133 svg.put(g2, "g2=g1.translate(0,250)");
134
135 // G2 - Scale -> G3
136 scale_transformer<double, 2, 2> scale(0.5, 0.5);
137 model::polygon<point_2d> g3;
138 transform(g2, g3, scale);
139 std::clog << "scaled:\t" << boost::geometry::dsv(g3) << std::endl;
140 svg.put(g3, "g3=g2.scale(0.5,0.5)");
141
142 // G3 - Combine rotate and translate -> G4
143 rotate_transformer<degree, double, 2, 2> rotate(45);
144
145 // Compose matrix for the two transformation
146 // Create transformer attached to the transformation matrix
147 matrix_transformer<double, 2, 2> combined(rotate.matrix() * translate.matrix());
148
149 // Apply transformation to subject geometry point-by-point
150 model::polygon<point_2d> g4;
151 transform(g3, g4, combined);
152
153 std::clog << "rotated & translated:\t" << boost::geometry::dsv(g4) << std::endl;
154 svg.put(g4, "g4 = g3.(rotate(45) * translate(0,250))");
155
156 std::clog << "Saved SVG file:\t" << file << std::endl;
157 }
158 catch (std::exception const& e)
159 {
160 std::cerr << e.what() << std::endl;
161 }
162 catch (...)
163 {
164 std::cerr << "unknown error" << std::endl;
165 }
166 return 0;
167 }