使用增强相交覆盖浮点容差

问题描述

是否可以在相交算法中引入一些容差,以便将接近的点或几乎共线的线视为平行? 具体来说:

我有两条线段应该被认为是平行的,但是,由于在进行浮点计算时存在一些精度问题,线段并不完全平行,误差为 3.78e-14,这应该 - 无论如何 -在我的情况下被认为是平行的:所以 boost 的交叉点应该给我两点。 然而,情况并非如此,相交将这些线视为不平行。示例:

这与this question非常相似。这篇文章很旧,但似乎不能满足我的需求。我也对交集算法在 boost 中的工作方式感到困惑。我试图在 boosts 库中找到代码,但没有成功。 Boosts 代码库太可怕了。

struct Point {
    double x,y;

    Point(double x_,double y_) : x(x_),y(y_) {};
}
BOOST_GEOMETRY_REGISTER_POINT_2D(Point,double,boost::geometry::cs::cartesian,x,y);
typedef boost::geometry::model::segment<Point> Segment;

Segment seg1({ -1012600,9641189 },{ -935132,9595186.14285714179277420043945 });
Segment seg2({ -1012600,{ -877031,9560684 });

std::vector<Point> out;

boost::geometry::intersection(seg1,seg2,out);

因为我认为这两个段是并行的,所以预期的输出应该是:

{ -1012600,9595186.14285714179277420043945 }

在平行情况下,交集确实给出了两点: 参见示例:

Segment seg1({0,0},{6,6});
Segment seg2({2,2},{3,3});

boost::geometry::intersection(seg1,out);

会给:

{2,3}

解决方法

你期望结果是什么?各段仍从同一点开始。

结果交点就是我测试时的那个点:

Live On Coliru

#include <boost/geometry.hpp>
#include <iostream>
#include <boost/geometry/geometries/register/point.hpp>

struct Point {
    double x,y;

    Point(double x_= 0,double y_= 0) : x(x_),y(y_) {};
};

BOOST_GEOMETRY_REGISTER_POINT_2D(Point,double,boost::geometry::cs::cartesian,x,y)
typedef boost::geometry::model::segment<Point> Segment;

int main() {
    Point P1{-1012600,9641189};
    std::cout << std::fixed;
    Segment seg1(P1,{-935132,9595186.14285714179277420043945});
    Segment seg2(P1,{-877031,9560684});

    std::vector<Point> out;
    boost::geometry::intersection(seg1,seg2,out);

    for (auto& p : out) {
        std::cout << boost::geometry::wkt(p) << "\n";
    }
}

打印

POINT(-1012600.000000 9641189.000000)

关于精度

否则,我已经成功地将 double 替换为 long double 或 Boost Multiprecision 类型:https://stackoverflow.com/search?tab=newest&q=user%3a85371%20geometry%20multiprecision