2015-12-21 28 views
7

there is no way to compute line line intersection using boost::geometry gibi görünüyor, fakat C++'da bunu yapmanın en yaygın yolu nedir acaba?Hat çizgisi kesişimini hesaplamanın en yaygın yolu C++?

bool line_intersection(line,line); 
point line_intersetion(line,line); 

P.S.:

Ben olacaksa daha hızlı o gibi iki farklı fonksiyonlar olabilir, 2B'de iki sonsuz hatları için kesişim algoritmaları ihtiyaç Gerçekten bir tekerlek icatından kaçınmaya çalışıyorum, bu yüzden bazı kütüphaneleri kullanmaya meyilliyim.

+0

(konu dışı) tol argüman silin ardından soru kapalıyken -topic. Eğer değilse, sorunuz geniş olacaktır. –

+0

Bir çizgiyi nasıl temsil ediyorsunuz .. iki nokta? hough uzayı? m, p? –

+0

Her satır y = kx + b olarak gösterilir ve her iki çizgi için kesişme noktasında x ve y değerleri eşittir, dolayısıyla denklemle {y = k1x + b1; y = k2x + b2} – user3514538

cevap

0

Bu kod sizin için çalışmalıdır.

template <class Tpoint> 
    Tpoint line<Tpoint>::intersect(const line& other) const{ 
     Tpoint x = other.first - first; 
     Tpoint d1 = second - first; 
     Tpoint d2 = other.second - other.first; 

     auto cross = d1.x*d2.y - d1.y*d2.x; 

     auto t1 = (x.x * d2.y - x.y * d2.x)/static_cast<float>(cross); 
     return first + d1 * t1; 

    } 
1

Ben hatlarının kavşak bulma için bulduğum en iyi algoritmalar bulunmaktadır: Sen bunu biraz optimize etmek mümkün olabilir Real Time Collision Detection by Christer Ericson, kitabın bir kopyasını here bulunabilir. sayfa 146 den

Bölüm 5 itibaren C. örnek kodu ile ...

Not 2D hatlarının geçiş noktası da 3D çizgilerinin en yakın noktasını bulmak açıklamaktadır: paralel çizgilerin onlar dikkat sıfır hatayla bölünmeye neden olabilir.

0

Express parametrik şeklinde çizgilerin bir ve örtük biçimde diğer: Eğer t olsun Bundan

ilişkilerin Doğrusallık yoluyla
X = X0 + t (X1 - X0), Y= Y0 + t (Y1 - Y0) 

S(X, Y) = (X - X2) (Y3 - Y2) - (Y - Y2) (X3 - X2) = 0 

, sahip

S(X, Y) = S(X0, Y0) + t (S(X1, Y1) - S(X0, Y0)) = S0 + t (S1 - S0) = 0 

ve t dan kesişme koordinatları.

Toplam 15 ek, 6 çoklu ve tek bir bölme alır. Dejenere, S1 == S0 ile belirtilir, bu da çizgilerin paralel olduğu anlamına gelir. Pratikte, kesişme hataları veya diğerleri nedeniyle koordinatlar kesin olmayabilir, böylece eşitlik testi 0'a başarısız olabilir. Bir geçici çözüm küçük µ için testi

|S0 - S1| <= µ |S0| 

dikkate almaktır.

0

Belki de sonsuzluğa yaklaşmanın ortak bir yolu mu? boost :: geometri kullanarak Kitaplığıma Gönderen:

// prev and next are segments and RAY_LENGTH is a very large constant 
// create 'lines' 
auto prev_extended = extendSeg(prev, -RAY_LENGTH, RAY_LENGTH); 
auto next_extended = extendSeg(next, -RAY_LENGTH, RAY_LENGTH); 
// intersect! 
Points_t isection_howmany; 
bg::intersection(prev_extended, next_extended, isection_howmany); 

o zaman 'satırları' böyle kesiştiği olmadığını test edebilir:

if (isection_howmany.empty()) 
    cout << "parallel"; 
else if (isection_howmany.size() == 2) 
    cout << "collinear"; 

extendSeg() basitçe verilen miktarlarda tarafından her iki yönde segmenti uzanır.


Ayrıca akılda tutulması - Bir sonsuz hat aritmetik ayrıca sonsuz değerini desteklemelidir noktası türünü desteklemek için. Ancak burada varsayım, sayısal bir çözüm aradığınızdır!

+0

Ayrıca, artırılmış geometri, kendim kullanmak için henüz kullanmıyorum bool döndüren bir intersects() işlevi vardır. :) http://www.boost.org/doc/libs/1_60_0/libs/geometry/doc/html/geometry/reference/algorithms/intersects/intersects_2_two_geometries.html –

1

Kodumu deneyebilirsin, boost::geometry kullanıyorum ve ana işlevde küçük bir test durumu koydum.

Öznitelik olarak iki nokta içeren bir sınıf satırı tanımlarım.

Çapraz ürün, iki çizginin kesişip kesmediğini bilmek için çok basit bir yoldur. 2D'de, 2B düzleminin normal vektöründe çapraz ürünün bir projeksiyonu olan perp nokta ürününü hesaplayabilirsiniz (bkz. perp fonksiyonu). Bunu hesaplamak için, her satırın bir yön vektörünü almanız gerekir (bkz. getVector yöntemi).

2B'de, perp nokta ürününü ve satırın parametrik denklemini kullanarak iki satırın kesişim noktasını alabilirsiniz. Bir açıklama here buldum.

intersect işlevi, iki çizginin kesişip kesmediğini kontrol etmek için bir boole döndürür. Kesişirse, kesişme noktasını referans olarak hesaplar.

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

DÜZENLEME: Bir kütüphane için bağlantıları veya öneriler için soruyorsanız çapraz ürün ve Fail nokta ürünün + üzerinde daha ayrıntılı

+0

çapraz ürün tanımı gereği bir vektörtür, ancak kodunuzda skalar mı? – mrgloom

+0

Evet Bir skalar hesaplıyorum, çünkü yalnızca 2D düzlemine dik olan bileşen sıfırdan farklıdır. [Bu açıklamaya bir bakın] (http://stackoverflow.com/questions/243945/calculating-a-2d-vectors-cross-product) – cromod

+0

Bunu perp nokta ürünü olarak görebilirsiniz. Mesajımı düzenleyeceğim :) – cromod