Boost logo

Geometry :

Subject: [ggl] Re: Incorrect polygon area and problem with the boost::geometry::correct
From: Vishnu (vrang3)
Date: 2011-03-18 12:31:55


Hi Barend,

On Mar 18-3-2011 04:39am, Barend wrote:

>>I cannot reproduce your steps. It is right that without calling correct,
the polygon area is incorrect: holes (in the sample accidentally turned
clockwise) are added. That was already in 0.6 and it is still the case in
0.8, it is by design.

Let me clarify. With boost-geometry-0.8, I see no difference when I use
'correct'. Here are the results I get with MS Visual Studio 2008:

Area when using 'correct' with boost-geometry-0.6: 0.92
Area when *not* using 'correct' with boost-geometry-0.6: 1.08
Area when using 'correct' with boost-geometry-0.8: 1.08
Area when *not* using 'correct' with boost-geometry-0.8: 1.08

>>I do not have g++ 4.2.4. Using gcc 4.4 it runs fine.

I get the compiler error with g++ 4.4.3. Just to be sure, did you use
boost_1_46_1 with boost-geometry-0.8? If not, what version of boost did you
use?

bagend vishnu 230% g++ --version
g++ (GCC) 4.4.3
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

bagend vishnu 231% g++ -I/usr/raidhome/vishnu/boost_1_46_1 -o
c06_custom_polygon_example.2.using.bg0.8 c06_custom_polygon_example.2.cpp
In file included from
/usr/raidhome/vishnu/boost_1_46_1/boost/geometry/geometry.hpp:43,
                 from c06_custom_polygon_example.2.cpp:12:
/usr/raidhome/vishnu/boost_1_46_1/boost/geometry/algorithms/correct.hpp: In
static member function ?static void
boost::geometry::detail::correct::correct_polygon::apply(Polygon&) [with
Polygon = my_polygon]?:
/usr/raidhome/vishnu/boost_1_46_1/boost/geometry/algorithms/correct.hpp:238:
instantiated from ?void boost::geometry::correct(Geometry&) [with Geometry =
my_polygon]?
c06_custom_polygon_example.2.cpp:134: instantiated from here
/usr/raidhome/vishnu/boost_1_46_1/boost/geometry/algorithms/correct.hpp:161:
error: no matching function for call to
?boost::geometry::detail::correct::correct_ring<my_ring,
std::less<double> >::apply(my_ring)?
/usr/raidhome/vishnu/boost_1_46_1/boost/geometry/algorithms/correct.hpp:122:
note: candidates are: static void
boost::geometry::detail::correct::correct_ring<Ring,
Predicate>::apply(Ring&) [with Ring = my_ring, Predicate = std::less]

>>Are you sure you have defined the correct ring-types traits? There were
changes between 0.6.0 and trunk.

What do I need to do here? I haven't changed anything with respect to the
ring traits in the example which is taken from the boost-geometry-0.8
distribution. I only use an std::vector instead of a boost::array for the
holes and add a call to 'correct'.

>>In the diff output you sent some < > tags are missing, probably by the
HTML-parsing, so I cannot see exactly what you're doing there.

I am attaching the whole program below.

Vishnu

// Boost.Geometry (aka GGL, Generic Geometry Library)
//
// Copyright Barend Gehrels 2007-2009, Geodan, Amsterdam, the Netherlands
// 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
#include

#include &lt;boost/geometry/geometry.hpp&gt;

#include &lt;boost/geometry/geometries/register/point.hpp&gt;
#include &lt;boost/geometry/geometries/register/ring.hpp&gt;

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

// 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
    std::vector 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&lt;T,N&gt; in a macro would
// be very specific, so we show it "by hand":
namespace boost { namespace geometry { namespace traits
{

template<> struct tag { typedef polygon_tag type; };
template<> struct ring_type { typedef my_ring type; };

template<> struct interior_type
{
    typedef std::vector type;
};

template<> struct exterior_ring
{
    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
{
    typedef std::vector 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()
{
                using namespace boost::geometry;
                
    my_polygon p1("my polygon");

    // Fill it with a square
    p1.boundary.push_back(my_point(0, 0));
    p1.boundary.push_back(my_point(0, 1));
    p1.boundary.push_back(my_point(1, 1));
    p1.boundary.push_back(my_point(1, 0));
    p1.boundary.push_back(my_point(0, 0));
    
    // Hole 1
    my_ring ring;
    ring.push_back(my_point(0.2, 0.2));
    ring.push_back(my_point(0.2, 0.4));
    ring.push_back(my_point(0.4, 0.4));
    ring.push_back(my_point(0.4, 0.2));
    ring.push_back(my_point(0.2, 0.2));
        
    p1.holes.push_back(ring);

                ring.clear();
                 
    ring.push_back(my_point(0.6, 0.6));
    ring.push_back(my_point(0.6, 0.8));
    ring.push_back(my_point(0.8, 0.8));
    ring.push_back(my_point(0.8, 0.6));
    ring.push_back(my_point(0.6, 0.6));

                p1.holes.push_back(ring);

    correct(p1);

    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::make_centroid(p1)) <<
std::endl;

    return 0;
}

--
View this message in context: http://boost-geometry.203548.n3.nabble.com/Incorrect-polygon-area-and-problem-with-the-boost-geometry-correct-tp2694059p2698598.html
Sent from the Boost Geometry mailing list archive at Nabble.com.

Geometry list run by mateusz at loskot.net