Boost logo

Geometry :

Subject: Re: [geometry] segment_ratio<__int64> causes a real number value corruption in boost::geometry::difference()
From: Barend Gehrels (barend_at_[hidden])
Date: 2015-04-01 17:37:52


Hi Mike,

Welcome to the list.

1-4-2015 om 23:13:
> To make the story short double value
>
> "*1.3999999999999999*"
>
> gets converted into
>
> "*1.4000000000000057*"
>
> when calling /boost::geometry::difference()/ on two polygons. Polygons were
> defined in a standard way, that is:
>
> /BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
> BOOST_GEOMETRY_REGISTER_BOOST_ARRAY_CS(cs::cartesian)
> BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
>
> typedef boost::geometry::model::d2::point_xy<double> point_xy;
> typedef boost::geometry::model::polygon<point_xy > polygon;/
>
>
> I found (after 2.5 hours being lost in the haunted template forest :p) that
> the culprit is the following code (or I am d hing terribly wrong):
>
> / set<0>(point, boost::numeric_cast<coordinate_type>(
> get<0, 0>(segment)
> + ratio.numerator() * dx / ratio.denominator()));/
>
> in:
>
> function:
> /boost::geometry::policies::relate::segments_intersection_points::assign(..)/
> location: /boost\geometry\policies\relate\intersection_points.hpp/
>
> Which curiously enough means that value was stored/manipulated NOT a
> *double* but as a /*rational number*/!
>
> Were there any gobrutaly to handle this problem without having to bluntly
> round off the values?
>
> Would be happy to post an example if there are any answers to follow...
>
>
> --------------
> boost version: 1.56.0
>

Of course there are answers...

First, 1.56 was the first release having approach. Please upgrade to
1.57 or, better, to 1.58 which is now nearly released.

Second, yes we store some values as rational numbers during the process,
this is to solve FP errors which are often culprits in FP problem
domain, causing more problems than a slight rounding error.

Third, yes please post a concise example because it is unclear to me
that 1.39etc is the right answer and we round to 1.400etc. But it might
be, of course.

Fourth, this is using the rescale-to-integer approach internally,
optionally that can be turned off

Thanks, Barend


Geometry list run by mateusz at loskot.net