forked from boostorg/geometry
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathc06_custom_polygon_example.cpp
141 lines (108 loc) · 3.69 KB
/
c06_custom_polygon_example.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// 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)
//
// Custom Polygon Example
#include <iostream>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/ring.hpp>
struct my_point
{
my_point(double an_x = 0, double an_y = 0)
: x(an_x)
, y(an_y)
{}
double x, y;
};
struct my_ring : std::deque<my_point>
{};
// Define a struct of a polygon, having always two holes
// (of course this can be implemented differently, usually
// with a vector or deque, but it is just an exampe)
struct my_polygon
{
// required for a polygon: an outer ring...
my_ring boundary;
// ... and a Boost.Range compatible inner ring collection
boost::array<my_ring, 2> holes;
// just for the sample
std::string name;
my_polygon(std::string const& n = "") : name(n) {}
};
// We can conveniently use macro's to register point and ring
BOOST_GEOMETRY_REGISTER_POINT_2D(my_point, double, cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_RING(my_ring)
// There is currently no registration macro for polygons
// and besides that a boost::array<T,N> in a macro would
// be very specific, so we show it "by hand":
namespace boost { namespace geometry { namespace traits
{
template<> struct tag<my_polygon> { typedef polygon_tag type; };
template<> struct ring_const_type<my_polygon> { typedef my_ring const& type; };
template<> struct ring_mutable_type<my_polygon> { typedef my_ring& type; };
template<> struct interior_const_type<my_polygon>
{
typedef boost::array<my_ring, 2> const& type;
};
template<> struct interior_mutable_type<my_polygon>
{
typedef boost::array<my_ring, 2>& type;
};
template<> struct exterior_ring<my_polygon>
{
static my_ring& get(my_polygon& p)
{
return p.boundary;
}
static my_ring const& get(my_polygon const& p)
{
return p.boundary;
}
};
template<> struct interior_rings<my_polygon>
{
typedef boost::array<my_ring, 2> holes_type;
static holes_type& get(my_polygon& p)
{
return p.holes;
}
static holes_type const& get(my_polygon const& p)
{
return p.holes;
}
};
}}} // namespace boost::geometry::traits
int main()
{
my_polygon p1("my polygon");
// Fill it the my-way, triangle
p1.boundary.push_back(my_point(2, 0));
p1.boundary.push_back(my_point(1, 5));
p1.boundary.push_back(my_point(7, 6));
p1.boundary.push_back(my_point(2, 0));
// Triangle
p1.holes[0].push_back(my_point(2, 1));
p1.holes[0].push_back(my_point(2.4, 2));
p1.holes[0].push_back(my_point(1.9, 2));
p1.holes[0].push_back(my_point(2, 1));
// Box
p1.holes[1].push_back(my_point(3, 3));
p1.holes[1].push_back(my_point(4, 3));
p1.holes[1].push_back(my_point(4, 4));
p1.holes[1].push_back(my_point(3, 4));
p1.holes[1].push_back(my_point(3, 3));
std::cout << "Representation of " << p1.name << ": "
<< boost::geometry::dsv(p1) << std::endl;
std::cout << "Area of " << p1.name << ": "
<< boost::geometry::area(p1) << std::endl;
std::cout << "Perimeter of " << p1.name << ": "
<< boost::geometry::perimeter(p1) << std::endl;
std::cout << "Centroid of " << p1.name << ": "
<< boost::geometry::dsv(boost::geometry::return_centroid<my_point>(p1)) << std::endl;
return 0;
}