Boost logo

Geometry :

Subject: [geometry] self_ip_exception thrown doing ::intersection
From: James Turner (zakalawe_at_[hidden])
Date: 2013-11-19 09:08:56


Hello,

I have some code which is raising an exception doing bg::intersection.

Roughly, the code is:

BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(QVector2D, float,
    boost::geometry::cs::cartesian, x, y, setX, setY)

typedef QVector<QVector2D> Contour;
BOOST_GEOMETRY_REGISTER_RING(Contour)

void foo()
{
        Contour a = … some code …
        Contour b = .. some code ...

        // output of these included below
        std::cout << boost::geometry::wkt(a) << std::endl;
        std::cout << boost::geometry::wkt(b) << std::endl;

        QVector<Contour> result;
        boost::geometry::intersection(a, b, result);
}

At runtime, for certain input data (shown below), this leads to the following:

======

0 __cxa_throw 0x7fff89f9f521
1 boost::geometry::detail::self_get_turn_points::self_section_visitor<QVector<QVector2D>, std::deque<boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> >, std::allocator<boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> > > >, boost::geometry::detail::overlay::get_turn_info<QVector2D, QVector2D, boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> >, boost::geometry::detail::overlay::assign_null_policy>, boost::geometry::detail::disjoint::disjoint_interrupt_policy>::apply<boost::geometry::section<boost::geometry::model::box<QVector2D>, 1ul> > self_turn_points.hpp 97 0x100049de5
2 boost::geometry::partition<boost::geometry::model::box<QVector2D>, boost::geometry::detail::get_turns::get_section_box, boost::geometry::detail::get_turns::ovelaps_section_box, boost::geometry::visit_no_policy>::apply<boost::geometry::sections<boost::geometry::model::box<QVector2D>, 1ul>, boost::geometry::detail::self_get_turn_points::self_section_visitor<QVector<QVector2D>, std::deque<boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> >, std::allocator<boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> > > >, boost::geometry::detail::overlay::get_turn_info<QVector2D, QVector2D, boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> >, boost::geometry::detail::overlay::assign_null_policy>, boost::geometry::detail::disjoint::disjoint_interrupt_policy> > partition.hpp 370 0x1000493d5
3 boost::geometry::detail::self_get_turn_points::get_turns<QVector<QVector2D>, std::deque<boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> >, std::allocator<boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> > > >, boost::geometry::detail::overlay::get_turn_info<QVector2D, QVector2D, boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> >, boost::geometry::detail::overlay::assign_null_policy>, boost::geometry::detail::disjoint::disjoint_interrupt_policy>::apply self_turn_points.hpp 140 0x1000490a7
4 boost::geometry::self_turns<boost::geometry::detail::overlay::assign_null_policy, QVector<QVector2D>, std::deque<boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> >, std::allocator<boost::geometry::detail::overlay::turn_info<QVector2D, boost::geometry::detail::overlay::turn_operation, boost::array<boost::geometry::detail::overlay::turn_operation, 2ul> > > >, boost::geometry::detail::disjoint::disjoint_interrupt_policy> self_turn_points.hpp 294 0x1000481aa
5 boost::geometry::detail::overlay::has_self_intersections<QVector<QVector2D> > has_self_intersections.hpp 66 0x10004573c
6 boost::geometry::detail::overlay::backtrack_check_self_intersections<QVector<QVector2D>, QVector<QVector2D> >::apply<boost::geometry::detail::overlay::traversal_turn_operation<QVector2D>, std::deque<QVector<QVector2D>, std::allocator<QVector<QVector2D> > >, std::deque<boost::geometry::detail::overlay::traversal_turn_info<QVector2D>, std::allocator<boost::geometry::detail::overlay::traversal_turn_info<QVector2D> > > > backtrack_check_si.hpp 98 0x100044861
7 boost::geometry::detail::overlay::traverse<false, false, QVector<QVector2D>, QVector<QVector2D>, boost::geometry::detail::overlay::backtrack_check_self_intersections<QVector<QVector2D>, QVector<QVector2D> > >::apply<std::deque<boost::geometry::detail::overlay::traversal_turn_info<QVector2D>, std::allocator<boost::geometry::detail::overlay::traversal_turn_info<QVector2D> > >, std::deque<QVector<QVector2D>, std::allocator<QVector<QVector2D> > > > traverse.hpp 306 0x100070f62
8 boost::geometry::detail::overlay::overlay<QVector<QVector2D>, QVector<QVector2D>, false, false, false, QVector<QVector2D>, (boost::geometry::overlay_type)1>::apply<std::back_insert_iterator<QVector<QVector<QVector2D> > >, boost::geometry::strategy_intersection<boost::geometry::cartesian_tag, QVector<QVector2D>, QVector<QVector2D>, QVector2D, void> > overlay.hpp 226 0x100070238
9 boost::geometry::dispatch::intersection<QVector<QVector2D>, QVector<QVector2D>, boost::geometry::ring_tag, boost::geometry::ring_tag, false>::apply<QVector<QVector<QVector2D> >, boost::geometry::strategy_intersection<boost::geometry::cartesian_tag, QVector<QVector2D>, QVector<QVector2D>, QVector2D, void> > intersection.hpp 103 0x10007008d
10 boost::geometry::intersection<QVector<QVector2D>, QVector<QVector2D>, QVector<QVector<QVector2D> > > intersection.hpp 198 0x100032be3
                
====

self_turn_points.hpp is indeed:

 if (m_interrupt_policy.has_intersections)
        {
            // TODO: we should give partition an interrupt policy.
            // Now we throw, and catch below, to stop the partition loop.
            throw self_ip_exception();
        }

====

A and B are defined as follows; note A is a regular polygon centred on (4,8) with radius = 3. If I change the number of sides generated for A, the issue goes away, but I would like to understand the exception before deploying this code!

====
POLYGON((7 8,6.42705 6.23664,4.92705 5.14683,3.07295 5.14683,1.57295 6.23664,1 8,1.57295 9.76336,3.07295 10.8532,4.92705 10.8532,6.42705 9.76336,7 8))
POLYGON((4 4,4 8,12 8,12 4,4 4))
===

Again, small perturbations in the input data can avoid the exception, but other inputs do generate the same issue.

Have I made some error adapting the Qt types/container to Boost.Geometry? Or what else might explain this?

Kind regards,
James Turner


Geometry list run by mateusz at loskot.net