![](/img/trans.png)
[英]How do Boost.Geometry operations like union_ deal with the fundamental imprecision of floating point types?
[英]How to override the floating point tolerance in the boost::geometry::equals algorithm?
我正在使用Boost几何库来比较两个不同的多边形。 具体来说,我使用的是equals算法 ,看两个多边形是否相等(相等尺寸)。
问题在于算法上的公差太小,两个本应相等的多边形(经过一些浮点运算)不在算法定义的公差内。
我几乎可以确定该库正在使用std::numeric_limits<double>::epsilon()
(〜2.22e-16)来建立公差。 我想将公差设置为更大(例如1.0e-10)。
有关如何执行此操作的任何想法?
编辑:我已经更改标题以反映评论中的回复。 请回应以下后续行动:
是否可以仅覆盖boost::geometry::math::detail::equals<Type,true>::apply
函数?
这样,我可以只替换发生浮点比较的代码,而不必重写大多数boost::geometry::equals
算法。
作为参考,这是boost库中的当前代码:
template <typename Type, bool IsFloatingPoint>
struct equals
{
static inline bool apply(Type const& a, Type const& b)
{
return a == b;
}
};
template <typename Type>
struct equals<Type, true>
{
static inline Type get_max(Type const& a, Type const& b, Type const& c)
{
return (std::max)((std::max)(a, b), c);
}
static inline bool apply(Type const& a, Type const& b)
{
if (a == b)
{
return true;
}
// See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17,
// FUTURE: replace by some boost tool or boost::test::close_at_tolerance
return std::abs(a - b) <= std::numeric_limits<Type>::epsilon() * get_max(std::abs(a), std::abs(b), 1.0);
}
};
可以在boost/geometry/util/math.hpp
找到提到的代码,当前在Boost 1.56或更早的版本中(在GitHub上 )。
有一个免费的功能boost::geometry::math::equals()
内部调用boost::geometry::math::detail::equals<>::apply()
。 因此,要更改默认行为,您可以重载此函数或将结构专用于某些坐标类型。 请记住,在某些算法中,该类型可能会提升为更精确的类型。
当然,您也可以使用自己的非标准坐标类型并实现所需的运算符或重载上述功能。
但是...当您认为计算结果错误时,可以考虑描述一个特定情况,以确保此问题不是XY问题 。 在某些情况下,使用epsilon可能会改善结果,但在另一些情况下会使情况更糟。 如果算法中与比较无关的某些部分可以改善怎么办? 然后,如果您编写了所使用的Boost.Geometry版本,编译器等,将很有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.