简体   繁体   English

使用boost几何来检查两条线是否有交点

[英]Using boost geometry to check if two lines have an intersection

Is it possible to use boost::geometry to check whether two line segments (each given by two points in 2D) intersect each other? 是否可以使用boost :: geometry来检查两个线段(每个由2D中的两个点给出)是否相互交叉? 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? 如果可能的话,boost :: geometry是否也允许检查特殊情况,例如在另一条线上只有一个点(数字),或两条线是否相等?

If you are talking specifically about Boost.Geometry API to it is, of course, possible. 如果您正在特别谈论Boost.Geometry API,那么它当然是可能的。

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. 现在输出将有0,1或2个点,具体取决于位置。

Of course, your Point type should be "compliant" with Boost.Geometry concepts. 当然,您的Point类型应该与Boost.Geometry概念“兼容”。 The following code will make QPointF compliant: 以下代码将使QPointF符合:

#include <boost/geometry/geometries/register/point.hpp>
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(QPointF, qreal, cs::cartesian, x, y, setX, setY);

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 它的工作原理如下:使用3个点的坐标计算其行列式

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). 其中(x1; y1)和(x2; y2)是表示你的线的点,而(x3; y3)代表你的第3点(你的线段的极端之一)。 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. 如果行列式为正,则(x3; y3)从面向(x1; y1)到(x2; y2)的向量向右,如果是负,则向右。 And if the determinant is 0 then the point is on the line. 如果行列式为0,则该点在线上。

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). 所有你需要做的就是两次应用相同的想法,只是第二次你的(x1; y1)和(x2; y2)将是你用于(x3; y3)和你的新(x3; y3)你的值old(x1; y1)和(x2; y2)。

I learned this algorithm under "Sarrus algorithm" so maybe googling it might give a better explanation. 我在“Sarrus算法”下学习了这个算法,所以也许谷歌搜索它可能会给出一个更好的解释。

You could try using the intersection algorithm . 您可以尝试使用交集算法 If the lines intersect, the output will be non-empty. 如果线相交,则输出将为非空。

example for beginners without the use of BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET 不使用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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM