1

Is it possible to introduce some tolerance with the intersection algorithm, such that close points or almost colinear lines are considered parallel? To be concrete:

I have two line segments that should be considered parallel, however, due to some accuracy problems while doing floating point calculations, the line segments are not entirely parallel, the error is 3.78e-14 which should - by all means - be considered parallel in my case: so boost's intersection should give me two points. However this is not the case and intersection regards those lines as not parallel. Example:

This is very similar to this question. This post is old and doesn't seem to satisfy me needs though. I'm confused as to how the intersection algorithm works in boost, too. I tried to find the code in boosts library but without success. Boosts code base is terrifying.

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, 9641189 }, { -877031, 9560684 });

std::vector<Point> out;

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

Since I consider both segments as parallel, the expected output should be:

{ -1012600, 9641189 }, { -935132, 9595186.14285714179277420043945 }

Intersection indeed gives two points in a parallel case: See for example:

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

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

Will give:

{2, 2}, {3, 3}
Ahiru
  • 25
  • 8

1 Answers1

1

What do you expect the outcome to be? The segments still start in the same point.

And the resulting intersection is that point when I test it:

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";
    }
}

Print

POINT(-1012600.000000 9641189.000000)

On Precision

Otherwise, I've had success replacing double with long double or Boost Multiprecision types: https://stackoverflow.com/search?tab=newest&q=user%3a85371%20geometry%20multiprecision

sehe
  • 374,641
  • 47
  • 450
  • 633
  • I clarified the expected output. replacing double with long double didn't help unfortunately. I will give multiprecision a try – Ahiru May 07 '21 at 12:34
  • Ah. You didn't think the answer was wrong, you just want domain specific non-standard behaviour. In that case, you'll have to write the logic. You can measure the difference in angles and correct for it. It becomes a complicated rounding ballet when you consideer that the starting point might not be 100% the same either. In effect, you might just want to round all your points to a certain grid size before comparisons. The usual approach is to scale the coordinate types and represent them in integral types. – sehe May 07 '21 at 15:36
  • Here's a starting point if you want to tinker with those ideas: http://coliru.stacked-crooked.com/a/e3abd4ab8a74a25a I think you'll soon appreciate it's not that simple, and certainly not something you can expect a general-purpose library to do for you "automagically" – sehe May 07 '21 at 16:12
  • I just implemented my own line intersection algorithm, that takes a certain epsilon tolerance into account. This works just fine :) – Ahiru May 07 '21 at 18:46
  • Of course. The difference is - mostly - that boost geometry intersects arbitrary geometries. If you know you have only line segments you can reduce generality and add some specific logic for you own purpose. Fair gaime. Again, I never meant to say the wish is unreasonable, it's just clearly not the goal for Boost Geometry – sehe May 07 '21 at 21:13
  • By the way, it would be neat if you could share your implementation. So others facing your situation can solve their problem in the future – sehe May 07 '21 at 21:15