6

Is it possible to use boost::geometry to check whether two line segments (each given by two points in 2D) intersect each other? If this is possible, does boost::geometry allow to check also for special cases such as that only one point is (numerically) on the other line, or that both lines are equal?

anjruu
  • 1,224
  • 10
  • 24
Thomas W.
  • 2,134
  • 2
  • 24
  • 46

4 Answers4

14

If you are talking specifically about Boost.Geometry API to it is, of course, possible.

Your code should look roughly like this

#include <boost/geometry/geometries/segment.hpp> 
#include <boost/geometry/algorithms/intersection.hpp>

typedef boost::geometry::model::segment<Point> Segment;
Segment AB( Point(x1,y1), Point(x2,y2) );
Segment CD; //similar code

bool result = boost::geometry::intersects(AB, CD);

If you need intersection points:

std::vector<Point> output; 
boost::geometry::intersection(AB, CD, output);

Now output will have 0, 1 or 2 points, depending on locations.

Of course, your Point type should be "compliant" with Boost.Geometry concepts. The following code will make QPointF compliant:

#include <boost/geometry/geometries/register/point.hpp>
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(QPointF, qreal, cs::cartesian, x, y, setX, setY);
Michael Simbirsky
  • 3,045
  • 1
  • 12
  • 24
  • As someone new to Boost, would you mind elaborating a bit on the last part about compliance? I don't really understand what is meant there. – michaelgulak Jun 29 '15 at 03:31
  • 2
    The classes and functions from Boost.Geometry use certain metaprogramming tricks to access the coordinates of the point(s). If you try to use them with your custom class Point, you will likely get a lot of compilation errors. The macros similar to BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET explain to Boost.Geometry how to access or modify your custom class Point. – Michael Simbirsky Jul 01 '15 at 08:21
2

example for beginners without the use of BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET

namespace bg = boost::geometry;

typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::segment<point_t> segment_t;

segment_t seg1(point_t(0.0, 0.0), point_t(5.0, 5.0));
segment_t seg2(point_t(10.0, 5.0), point_t(5.0, 0.0));

bool result = boost::geometry::intersects(seg1, seg2);
user1277317
  • 127
  • 11
1

You ask whether two lines intersect. Two lines will always intersect unless they are parallel.

The following algoritm helps you compute if a segment intersects a line. It works as follows: having the coordinates of 3 points you compute the determinant of

x1 y1 1
x2 y2 1
x3 y3 1

Where (x1;y1) and (x2;y2) are the point representing your line and (x3; y3) represent your 3rd point (one of the extremes of your segment). If determinant is positive then (x3; y3) is to the right from the vector oriented from (x1;y1) to (x2;y2), if it is negative it is to the right. And if the determinant is 0 then the point is on the line.

What you have to do is to apply this algorithm twice once for one extreme of the segment and once for the other, if the product of determinants is negative, it intersects, if not, it doesn't.

You can go further and compute if two segments intersect. All you have to do is apply the same idea twice, only that the second time your (x1;y1) and (x2;y2) will be the values you used for (x3;y3) and your new (x3;y3) your old (x1;y1) and (x2;y2).

I learned this algorithm under "Sarrus algorithm" so maybe googling it might give a better explanation.

Alexandru Barbarosie
  • 2,952
  • 3
  • 24
  • 46
  • I thought about it, and it does not work for all corner cases. Just think about first line segment [0,0] -> [1,1] and second line segment [2,2] -> [3,3]. Of coarse, the line segments do not intersect, but both determinants are zero, as both line segments are part of the same (infinite) line. – Thomas W. Nov 08 '13 at 20:34
  • well you can easy check this specific case - you can compute the line function from 2 points, and compare the slopes and the coefficients and then check if they don't overlap. – Alexandru Barbarosie Nov 09 '13 at 00:01
0

You could try using the intersection algorithm. If the lines intersect, the output will be non-empty.

anjruu
  • 1,224
  • 10
  • 24
  • Interesting, but is it efficient? I'm just interested whether both lines intersect or not, I do not need the resulting intersection geometry. And even more crucial, what's about numerical stability of this functions? How it behaves if one point is contained in an epsilon surroundings of the other line? – Thomas W. Nov 08 '13 at 19:49
  • Wait, you're in 2D. The answer is "yes, unless the lines are parallel". – anjruu Nov 08 '13 at 19:53
  • @anjruu I think he means two line segments –  Nov 08 '13 at 19:54
  • Oh, never mind then. I don't know about the numerical stability of boost::geometry::intersection. – anjruu Nov 08 '13 at 19:55