![](/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.