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;
}
|