Możesz wypróbować mój kod, używam boost::geometry
i umieszczam małą próbkę w głównej funkcji.
Definiuję linię klasy z dwoma punktami jako atrybutami.
Produkt krzyżowy to bardzo prosty sposób sprawdzenia, czy dwie linie przecinają się. W 2D można obliczyć produkt perp dot (patrz funkcja perp
), który jest rzutowaniem iloczynu krzyżowego na normalnym wektorze płaszczyzny 2D. Aby to obliczyć, musisz uzyskać wektor kierunkowy dla każdej linii (patrz metoda getVector
).
W 2D można uzyskać punkt przecięcia dwóch linii za pomocą produktu perp dot i parametrycznego równania linii. Znalazłem wyjaśnienie here.
Funkcja intersect
zwraca wartość boolowską, aby sprawdzić, czy dwie linie przecinają się. Jeśli się przecinają, oblicza punkt przecięcia przez odniesienie.
#include <cmath>
#include <iostream>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
namespace bg = boost::geometry;
// Define two types Point and Vector for a better understanding
// (even if they derive from the same class)
typedef bg::model::d2::point_xy<double> Point;
typedef bg::model::d2::point_xy<double> Vector;
// Class to define a line with two points
class Line
{
public:
Line(const Point& point1,const Point& point2): p1(point1), p2(point2) {}
~Line() {}
// Extract a direction vector
Vector getVector() const
{
Vector v(p2);
bg::subtract_point(v,p1);
return v;
}
Point p1;
Point p2;
};
// Compute the perp dot product of vectors v1 and v2
double perp(const Vector& v1, const Vector& v2)
{
return bg::get<0>(v1)*bg::get<1>(v2)-bg::get<1>(v1)*bg::get<0>(v2);
}
// Check if lines l1 and l2 intersect
// Provide intersection point by reference if true
bool intersect(const Line& l1, const Line& l2, Point& inter)
{
Vector v1 = l1.getVector();
Vector v2 = l2.getVector();
if(std::abs(perp(v1,v2))>0.)
{
// Use parametric equation of lines to find intersection point
Line l(l1.p1,l2.p1);
Vector v = l.getVector();
double t = perp(v,v2)/perp(v1,v2);
inter = v1;
bg::multiply_value(inter,t);
bg::add_point(inter,l.p1);
return true;
}
else return false;
}
int main(int argc, char** argv)
{
Point p1(0.,0.);
Point p2(1.,0.);
Point p3(0.,1.);
Point p4(0.,2.);
Line l1(p1,p2);
Line l2(p3,p4);
Point inter;
if(intersect(l1,l2,inter))
{
std::cout<<"Coordinates of intersection: "<<inter.x()<<" "<<inter.y()<<std::endl;
}
return 0;
}
EDIT: więcej szczegółów na iloczynu i sprawca iloczynu skalarnego + Delete tol
argumentu (off topic)
Jeśli pytasz o linki ani zaleceń dla biblioteki wówczas pytanie jest wyłączony -temat. Jeśli nie, twoje pytanie jest szerokie. –
Jak przedstawiasz linię ... dwa punkty? Hough-Space? m, p? –
Każda linia jest reprezentowana jako y = kx + b, a w punkcie przecięcia xiy wartości dla obu linii są równe, więc możemy znaleźć je za pomocą równania {y = k1x + b1; y = k2x + b2} – user3514538