İki segmentin kesişip kesişmediğini nasıl kontrol edebilirim?


Yanıtlar:


64

Bir doğrunun denklemi:

f(x) = A*x + b = y

Bir segment için, x'in bir aralık I'e dahil edilmesi dışında, tamamen aynıdır.

Aşağıdaki gibi tanımlanan iki segmentiniz varsa:

Segment1 = {(X1, Y1), (X2, Y2)}
Segment2 = {(X3, Y3), (X4, Y4)}

Potansiyel kesişme noktasının (Xa, Ya) abcisse Xa'sı, aşağıdaki şekilde tanımlanan hem I1 hem de I2 aralığında bulunmalıdır:

I1 = [min(X1,X2), max(X1,X2)]
I2 = [min(X3,X4), max(X3,X4)]

Ve Xa'nın aşağıdakilere dahil olduğunu söyleyebiliriz:

Ia = [max( min(X1,X2), min(X3,X4) ),
      min( max(X1,X2), max(X3,X4) )]

Şimdi, bu Ia aralığının var olup olmadığını kontrol etmemiz gerekiyor:

if (max(X1,X2) < min(X3,X4)):
    return False  # There is no mutual abcisses

Yani iki satır formülümüz ve karşılıklı bir aralığımız var. Çizgi formülleriniz:

f1(x) = A1*x + b1 = y
f2(x) = A2*x + b2 = y

Parçalara göre iki puan aldığımız için A1, A2, b1 ve b2'yi belirleyebiliyoruz:

A1 = (Y1-Y2)/(X1-X2)  # Pay attention to not dividing by zero
A2 = (Y3-Y4)/(X3-X4)  # Pay attention to not dividing by zero
b1 = Y1-A1*X1 = Y2-A1*X2
b2 = Y3-A2*X3 = Y4-A2*X4

Segmentler paralelse, A1 == A2:

if (A1 == A2):
    return False  # Parallel segments

Her iki çizgide duran bir nokta (Xa, Ya) hem f1 hem de f2 formüllerini doğrulamalıdır:

Ya = A1 * Xa + b1
Ya = A2 * Xa + b2
A1 * Xa + b1 = A2 * Xa + b2
Xa = (b2 - b1) / (A1 - A2)   # Once again, pay attention to not dividing by zero

Yapılacak son şey, Xa'nın Ia'ya dahil edilip edilmediğini kontrol etmektir:

if ( (Xa < max( min(X1,X2), min(X3,X4) )) or
     (Xa > min( max(X1,X2), max(X3,X4) )) ):
    return False  # intersection is out of bound
else:
    return True

Buna ek olarak, tüm bu testlerden kaçınmak için, başlangıçta sağlanan dört noktadan ikisinin eşit olmadığını kontrol edebilirsiniz.


1
Segmentler, bunlar segmentler, üzgünüm. Cevaplarınızı verilen bölümlerde güncelleyebilir misiniz?
aneuryzm

13
Bu o kadar karmaşık değil, bir anlama amacıyla birçok (gereksiz mi?) Ara adım yazdım. Uygulamaların ana noktaları şunlardır: Karşılıklı aralık varlığını kontrol edin, A1, A2, b1, b2 ve Xa'yı hesaplayın ve ardından Xa'nın karşılıklı aralığa dahil olup olmadığını kontrol edin. Hepsi bu :)
OMG_peanuts

3
A1 - A2 asla sıfır olmayacaktır çünkü eğer (A1 == A2) bu durumda bu hesaplamadan önce döndürülürdü.
inkredibl

3
A1 == A2 ve b1 == b2 ise, segmentler birbirinin
üstündedir

6
Formül A1 * x + b1 = y dikey çizgileri işlemez, bu nedenle dikey segmentler bu yöntemle ayrı ayrı ele alınmalıdır.
dmitri

78

Kullanıcı @ i_4_got , Python'da çok etkili bir çözümle bu sayfaya işaret ediyor . Kolaylık olması için burada yeniden üretiyorum (çünkü burada olması beni mutlu ederdi):

def ccw(A,B,C):
    return (C.y-A.y) * (B.x-A.x) > (B.y-A.y) * (C.x-A.x)

# Return true if line segments AB and CD intersect
def intersect(A,B,C,D):
    return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)

8
Çok basit ve zarif, ancak eşdoğrusallıkla iyi bir şekilde ilgilenmiyor ve bu nedenle bu amaç için daha fazla kod gerekiyor.
charles


Bu çözümü seviyorum. Çok basit ve kısa! Bir çizgi çizen ve başka bir çizgiyle kesişip kesişmediğini gören bir wxPython programı yaptım. Buraya yerleştiremedim, bu yüzden bu yorumun altında bir yerde.
user1766438

33

Tam olarak hesaplamak gerekmez nerede kesiştiği segmentleri yok, ama sadece anlamak ister hepsi kesişir. Bu, çözümü basitleştirecektir.

Buradaki fikir, bir segmenti "çapa" olarak ele almak ve ikinci segmenti 2 noktaya ayırmaktır.
Şimdi, her noktanın "bağlantılı" segmente göre göreceli konumunu bulmanız gerekecek (Solda, Sağda veya Doğru).
Her iki nokta için de bunu yaptıktan sonra, noktalardan birinin Solda ve diğerinin Sağda olduğunu kontrol edin (veya uygun olmayan kavşakları da dahil etmek istiyorsanız belki Eşdoğrusal konumu dahil edin ).

Ardından, tutturma ve ayrılmış segment rolleriyle işlemi tekrarlamalısınız.

Bir kavşak, ancak ve ancak noktalardan biri OnLeft ve diğeri OnRight ise mevcuttur. Olası her durum için örnek resimlerle daha ayrıntılı bir açıklama için bu bağlantıya bakın .

Böyle bir yöntemi uygulamak, kesişme noktasını bulan bir yöntemi uygulamaktan çok daha kolay olacaktır (aynı zamanda ele almanız gereken birçok köşe durumu göz önüne alındığında).

Güncelleme

Aşağıdaki işlevler fikri açıklamalıdır (kaynak: C'deki Hesaplamalı Geometri ).
Açıklama: Bu örnek tamsayıların kullanıldığını varsaymaktadır. Bunun yerine bir kayan nokta gösterimi kullanıyorsanız (ki bu, işleri açıkça karmaşıklaştırabilir), o zaman "eşitliği" belirtmek için bir epsilon değeri belirlemelisiniz (çoğunlukla IsCollineardeğerlendirme için).

Elbette, bu fonksiyonları kullanırken, her bir segmentin diğer segment "arasında" bulunduğunu kontrol etmeyi unutmamak gerekir (çünkü bunlar sonlu segmentlerdir ve sonsuz çizgiler değil).

Ayrıca, bu işlevleri kullanarak, doğru ya da düzgün olup olmadığınızı anlayabilirsiniz. yanlış bir kavşak .

  • Uygun : Doğrusal noktalar yoktur. Segmentler birbirini "bir yandan diğer yana" kesişir.
  • Uygunsuz : Bir segment yalnızca diğerine "dokunur" (noktalardan en az biri bağlantılı segmentle eşdoğrusaldır).

+1 Benim fikrim de hemen hemen. Noktaların birbirine göre nerede olduğunu düşünürseniz, herhangi bir hesaplama yapmadan segmentlerinin kesişip kesişmeyeceğine karar verebilirsiniz.
Jochen Ritzel

ve @ THC4k Uhm, aslında net değil. Örneğin soruya eklediğim resmi kontrol edin: 2 nokta "OnLeft" ve "OnRight" ama 2 segment kesişmiyor.
aneuryzm

@Patrick, aslında hayır. Hangi segmentin "çapa" olduğuna bağlı olarak, bu durumda her iki nokta da Solda veya Sağda olur. (Güncellenmiş cevabıma bakın).
Liran

1
+1 Bu soruna onlarca yanıt gördüm, ancak bu şimdiye kadar gördüğüm en açık, en basit ve en verimli olanı. :)
Miguel

16

İki segmentin A, B ve C, D uç noktalarına sahip olduğunu varsayalım. Kesişimi belirlemenin sayısal olarak sağlam yolu, dört belirleyicinin işaretini kontrol etmektir:

| Ax-Cx  Bx-Cx |    | Ax-Dx  Bx-Dx |
| Ay-Cy  By-Cy |    | Ay-Dy  By-Dy |

| Cx-Ax  Dx-Ax |    | Cx-Bx  Dx-Bx |
| Cy-Ay  Dy-Ay |    | Cy-By  Dy-By |

Kesişme için soldaki her determinant sağdakinin zıt işaretine sahip olmalıdır, ancak iki çizgi arasında herhangi bir ilişki olması gerekmez. Temel olarak, diğer segment tarafından tanımlanan çizginin zıt taraflarında uzandıklarından emin olmak için bir segmentin her noktasını diğer segmentle karşılaştırırsınız.

Buraya bakın: http://www.cs.cmu.edu/~quake/robust.html


Uygun olmayan kavşaklar için mi çalışıyor, yani kesişme noktası bir çizgi parçası üzerinde olduğunda?
Sayam Qazi

@SayamQazi En azından bir çizgi segmentinin uç noktasını geçiyorsanız kesişme başarısız görünüyor. Çünkü eğer segmentteyseniz: 0 ile 1 / -1 karşılaştırması olacağını varsayıyorum, bu yüzden hiçbir kesişme tespit etmeyecektir.
Warty

1
Bu arada, bunu açıklamak gerekirse: her determinant, iki çizgi segmentinin vektör uç noktalarının çapraz çarpımını hesaplıyor. Örneğin, sol üst CA x CB ve sağ üst DA x DB'dir. Bu, esasen bir tepe noktasının hangi tarafta olduğunu test eder (saat). Hala sonsuza kadar uzamayan çizgi parçaları için nasıl çalıştığını anlamaya çalışıyorum.
Warty

8

Yöntem kullanılarak Shapely kitaplığı ile çizgi parçalarının kesişip kesişmediğini kontrol etmek çok kolaydır intersects:

from shapely.geometry import LineString

line = LineString([(0, 0), (1, 1)])
other = LineString([(0, 1), (1, 0)])
print(line.intersects(other))
# True

görüntü açıklamasını buraya girin

line = LineString([(0, 0), (1, 1)])
other = LineString([(0, 1), (1, 2)])
print(line.intersects(other))
# False

görüntü açıklamasını buraya girin


6

Liran ve Grumdrig'in mükemmel yanıtlarına dayanarak burada, kapalı segmentlerin kesişip kesişmediğini doğrulamak için eksiksiz bir Python kodu bulunmaktadır . Eşdoğrusal segmentler, Y eksenine paralel segmentler, dejenere segmentler için çalışır (şeytan ayrıntıda gizlidir). Tamsayı koordinatlarını varsayar. Kayan nokta koordinatları, nokta eşitliği testinde bir değişiklik gerektirir.

def side(a,b,c):
    """ Returns a position of the point c relative to the line going through a and b
        Points a, b are expected to be different
    """
    d = (c[1]-a[1])*(b[0]-a[0]) - (b[1]-a[1])*(c[0]-a[0])
    return 1 if d > 0 else (-1 if d < 0 else 0)

def is_point_in_closed_segment(a, b, c):
    """ Returns True if c is inside closed segment, False otherwise.
        a, b, c are expected to be collinear
    """
    if a[0] < b[0]:
        return a[0] <= c[0] and c[0] <= b[0]
    if b[0] < a[0]:
        return b[0] <= c[0] and c[0] <= a[0]

    if a[1] < b[1]:
        return a[1] <= c[1] and c[1] <= b[1]
    if b[1] < a[1]:
        return b[1] <= c[1] and c[1] <= a[1]

    return a[0] == c[0] and a[1] == c[1]

#
def closed_segment_intersect(a,b,c,d):
    """ Verifies if closed segments a, b, c, d do intersect.
    """
    if a == b:
        return a == c or a == d
    if c == d:
        return c == a or c == b

    s1 = side(a,b,c)
    s2 = side(a,b,d)

    # All points are collinear
    if s1 == 0 and s2 == 0:
        return \
            is_point_in_closed_segment(a, b, c) or is_point_in_closed_segment(a, b, d) or \
            is_point_in_closed_segment(c, d, a) or is_point_in_closed_segment(c, d, b)

    # No touching and on the same side
    if s1 and s1 == s2:
        return False

    s1 = side(c,d,a)
    s2 = side(c,d,b)

    # No touching and on the same side
    if s1 and s1 == s2:
        return False

    return True

"Kapalı segmentler" tam olarak ne anlama geliyor?
Sam

@Sam Kapalı segment, uç noktalarını içerir. Örneğin, R'den kapalı bir nokta parçası [0, 1] (0 <= x <= 1) olacaktır, bunun tersine] 0, 1] (0 <x <= 1)
dmitri

6

İşte nokta ürünleri kullanan bir çözüm:

# assumes line segments are stored in the format [(x0,y0),(x1,y1)]
def intersects(s0,s1):
    dx0 = s0[1][0]-s0[0][0]
    dx1 = s1[1][0]-s1[0][0]
    dy0 = s0[1][1]-s0[0][1]
    dy1 = s1[1][1]-s1[0][1]
    p0 = dy1*(s1[1][0]-s0[0][0]) - dx1*(s1[1][1]-s0[0][1])
    p1 = dy1*(s1[1][0]-s0[1][0]) - dx1*(s1[1][1]-s0[1][1])
    p2 = dy0*(s0[1][0]-s1[0][0]) - dx0*(s0[1][1]-s1[0][1])
    p3 = dy0*(s0[1][0]-s1[1][0]) - dx0*(s0[1][1]-s1[1][1])
    return (p0*p1<=0) & (p2*p3<=0)

Desmos'ta bir görselleştirme: Çizgi Segment Kesişimi


Bu harika ve Desmos'u unuttum - bu problem için mükemmel! Teşekkürler!
ponadto

Çözümünüzü Aşk ama iki çizgi parçaları aynı doğrultuda ise başarısız sanki görünüyor
H. Pope

Çok hoş. Bunu farklı bir dile aktaran
başka biri

4

İki çizgi segmentiniz var. Bir segmenti A ve B uç noktaları ile ve ikinci segmenti C ve D uç noktaları ile tanımlayın. Segmentlerin sınırları İÇERİSİNDE kesişmeleri gerektiğini göstermek için güzel bir numara var. (Çizgilerin kendilerinin segment sınırlarının ötesinde kesişebileceğini unutmayın, bu yüzden dikkatli olmalısınız. İyi kod da paralel çizgileri izleyecektir.)

İşin püf noktası, A ve B noktalarının CD çizgisinin zıt taraflarında olması gerektiğini VE C ve D noktalarının AB çizgisinin zıt taraflarında olması gerektiğini test etmektir.

Bu bir ev ödevi olduğu için size açık bir çözüm vermeyeceğim. Ancak, bir noktanın bir çizginin hangi tarafına düştüğünü görmek için basit bir test, bir iç çarpım kullanmaktır. Böylece, belirli bir CD satırı için, o doğrunun normal vektörünü hesaplayın (Ben buna N_C diyeceğim.) Şimdi, bu iki sonucun işaretlerini test edin:

dot(A-C,N_C)

ve

dot(B-C,N_C)

Bu sonuçların zıt işaretleri varsa, A ve B, CD satırının zıt taraflarıdır. Şimdi aynı testi diğer hat için de yapın, AB. Normal vektör N_A'ya sahiptir. İşaretlerini karşılaştırın

dot(C-A,N_A)

ve

dot(D-A,N_A)

Normal bir vektörün nasıl hesaplanacağını size bırakacağım. (2-d'de bu önemsizdir, ancak kodunuz A ve B'nin ayrı noktalar olup olmadığı konusunda endişelenecek mi? Aynı şekilde, C ve D farklı mı?)

Yine de aynı sonsuz çizgi boyunca uzanan çizgi parçaları hakkında endişelenmeniz gerekir veya bir nokta aslında diğer doğru parçasının kendisine denk gelirse. İyi kod, olası her soruna hitap eder.


3

İşte iki noktanın çizgi parçasının zıt taraflarında olup olmadığını kontrol etmek için C kodu. Bu kodu kullanarak iki segmentin de kesişip kesişmediğini kontrol edebilirsiniz.

// true if points p1, p2 lie on the opposite sides of segment s1--s2
bool oppositeSide (Point2f s1, Point2f s2, Point2f p1, Point2f p2) {

//calculate normal to the segment
Point2f vec = s1-s2;
Point2f normal(vec.y, -vec.x); // no need to normalize

// vectors to the points
Point2f v1 = p1-s1;
Point2f v2 = p2-s1;

// compare signs of the projections of v1, v2 onto the normal
float proj1 = v1.dot(normal);
float proj2 = v2.dot(normal);
if (proj1==0 || proj2==0)
        cout<<"collinear points"<<endl;

return(SIGN(proj1) != SIGN(proj2));

}


3

Kapalı segmentlerin kesişip kesişmediğini kontrol etmek için başka bir python kodu. C ++ kodunun http://www.cdn.geeksforgeeks.org/check-if-two-given-line-segments-intersect/ adresinde yeniden yazılmış sürümüdür . Bu uygulama tüm özel durumları kapsar (örneğin tüm noktalar eşdoğrusal).

def on_segment(p, q, r):
    '''Given three colinear points p, q, r, the function checks if 
    point q lies on line segment "pr"
    '''
    if (q[0] <= max(p[0], r[0]) and q[0] >= min(p[0], r[0]) and
        q[1] <= max(p[1], r[1]) and q[1] >= min(p[1], r[1])):
        return True
    return False

def orientation(p, q, r):
    '''Find orientation of ordered triplet (p, q, r).
    The function returns following values
    0 --> p, q and r are colinear
    1 --> Clockwise
    2 --> Counterclockwise
    '''

    val = ((q[1] - p[1]) * (r[0] - q[0]) - 
            (q[0] - p[0]) * (r[1] - q[1]))
    if val == 0:
        return 0  # colinear
    elif val > 0:
        return 1   # clockwise
    else:
        return 2  # counter-clockwise

def do_intersect(p1, q1, p2, q2):
    '''Main function to check whether the closed line segments p1 - q1 and p2 
       - q2 intersect'''
    o1 = orientation(p1, q1, p2)
    o2 = orientation(p1, q1, q2)
    o3 = orientation(p2, q2, p1)
    o4 = orientation(p2, q2, q1)

    # General case
    if (o1 != o2 and o3 != o4):
        return True

    # Special Cases
    # p1, q1 and p2 are colinear and p2 lies on segment p1q1
    if (o1 == 0 and on_segment(p1, p2, q1)):
        return True

    # p1, q1 and p2 are colinear and q2 lies on segment p1q1
    if (o2 == 0 and on_segment(p1, q2, q1)):
        return True

    # p2, q2 and p1 are colinear and p1 lies on segment p2q2
    if (o3 == 0 and on_segment(p2, p1, q2)):
        return True

    # p2, q2 and q1 are colinear and q1 lies on segment p2q2
    if (o4 == 0 and on_segment(p2, q1, q2)):
        return True

    return False # Doesn't fall in any of the above cases

Aşağıda, çalıştığını doğrulamak için bir test işlevi verilmiştir.

import matplotlib.pyplot as plt

def test_intersect_func():
    p1 = (1, 1)
    q1 = (10, 1)
    p2 = (1, 2)
    q2 = (10, 2)
    fig, ax = plt.subplots()
    ax.plot([p1[0], q1[0]], [p1[1], q1[1]], 'x-')
    ax.plot([p2[0], q2[0]], [p2[1], q2[1]], 'x-')
    print(do_intersect(p1, q1, p2, q2))

    p1 = (10, 0)
    q1 = (0, 10)
    p2 = (0, 0)
    q2 = (10, 10)
    fig, ax = plt.subplots()
    ax.plot([p1[0], q1[0]], [p1[1], q1[1]], 'x-')
    ax.plot([p2[0], q2[0]], [p2[1], q2[1]], 'x-')
    print(do_intersect(p1, q1, p2, q2))

    p1 = (-5, -5)
    q1 = (0, 0)
    p2 = (1, 1)
    q2 = (10, 10)
    fig, ax = plt.subplots()
    ax.plot([p1[0], q1[0]], [p1[1], q1[1]], 'x-')
    ax.plot([p2[0], q2[0]], [p2[1], q2[1]], 'x-')
    print(do_intersect(p1, q1, p2, q2))

    p1 = (0, 0)
    q1 = (1, 1)
    p2 = (1, 1)
    q2 = (10, 10)
    fig, ax = plt.subplots()
    ax.plot([p1[0], q1[0]], [p1[1], q1[1]], 'x-')
    ax.plot([p2[0], q2[0]], [p2[1], q2[1]], 'x-')
    print(do_intersect(p1, q1, p2, q2))

1
closed_segment_intersect()test kodundan tanımlanmamıştır.
hhquark

1
@hhquark Teşekkürler. Şimdi bu satırları kaldırdım. Bu satırları, uygulamamın başka bir yanıttan ( stackoverflow.com/a/18524383/7474256 , sanırım) uygulama ile uyumlu olup olmadığını kontrol etmek için test sırasında dahil ettim.
Fabian Ying

1

AB ve CD segmentleri için CD'nin eğimini bulun

slope=(Dy-Cy)/(Dx-Cx)

CD'yi A ve B'nin üzerine uzatın ve düz giden CD'ye olan mesafeyi alın

dist1=slope*(Cx-Ax)+Ay-Cy
dist2=slope*(Dx-Ax)+Ay-Dy

zıt tarafta olup olmadıklarını kontrol edin

return dist1*dist2<0

1
Formüllerden emin misin? B'nin koordinatları kullanılmadığından, 4 köşeyi de dikkate almadan AB ve CD'nin kesişimini nasıl bulabilirsiniz?
mac13k

1
Olması gerektiğini düşünüyorum: dist2 = slope * (Dx-Bx) + By-Dy
mac13k

1

Çizginin kesişme noktasını bulmak istediğinizden bahsetmediğiniz için problemi çözmek daha kolay hale gelir. Kesişme noktasına ihtiyacınız varsa, OMG_peanuts'ın cevabı daha hızlı bir yaklaşımdır. Bununla birlikte, sadece çizgilerin kesişip kesişmediğini bulmak istiyorsanız, bunu çizgi denklemini kullanarak yapabilirsiniz (ax + by + c = 0). Yaklaşım aşağıdaki gibidir:

  1. İki çizgi segmentiyle başlayalım: segment 1 ve segment 2.

    segment1 = [[x1,y1], [x2,y2]]
    segment2 = [[x3,y3], [x4,y4]]
    
  2. İki çizgi parçasının sıfır olmayan uzunlukta bir çizgi ve farklı bölümler olup olmadığını kontrol edin.

  3. Bundan sonra, iki segmentin sıfır olmayan uzunlukta ve farklı olduğunu varsayıyorum. Her bir doğru parçası için, doğrunun eğimini hesaplayın ve ardından ax + ile + c = 0 şeklinde bir doğrunun denklemini elde edin. Şimdi, iki nokta için f = ax + ile + c değerini hesaplayın. diğer çizgi parçası (bunu diğer çizgi parçası için de tekrarlayın).

    a2 = (y3-y4)/(x3-x4);
    b1 = -1;
    b2 = -1;
    c1 = y1 - a1*x1;
    c2 = y3 - a2*x3;
    // using the sign function from numpy
    f1_1 = sign(a1*x3 + b1*y3 + c1);
    f1_2 = sign(a1*x4 + b1*y4 + c1);
    f2_1 = sign(a2*x1 + b2*y1 + c2);
    f2_2 = sign(a2*x2 + b2*y2 + c2);
    
  4. Şimdi geriye kalan tek şey farklı durumlar. Herhangi bir nokta için f = 0 ise, o zaman iki çizgi bir noktaya temas eder. F1_1 ve f1_2 eşitse veya f2_1 ve f2_2 eşitse, çizgiler kesişmez. F1_1 ve f1_2 eşitsiz ise ve f2_1 ve f2_2 eşitsiz, o zaman hat kesimleri kesişir. Dokunan çizgileri "kesişen" olarak değerlendirmek isteyip istemediğinize bağlı olarak, koşullarınızı uyarlayabilirsiniz.


Bu kod hesaplamaz a1ve ortogonal çizgiler için çalışmaz.
Björn Lindqvist

1

Bunu vektörleri kullanarak da çözebiliriz.

Segmentleri olarak tanımlayalım [start, end]. Bu tür iki segment [A, B]ve [C, D]her ikisinin de sıfır olmayan uzunluğa sahip olduğu göz önüne alındığında , referans noktası olarak kullanılacak uç noktalardan birini seçebiliriz, böylece üç vektör elde ederiz:

x = 0
y = 1
p = A-C = [C[x]-A[x], C[y]-A[y]]
q = B-A = [B[x]-A[x], B[y]-A[y]]
r = D-C = [D[x]-C[x], D[y]-C[y]]

Oradan, t ve u in'i hesaplayarak bir kesişme arayabiliriz p + t*r = u*q. Denklemle biraz oynadıktan sonra şunu elde ederiz:

t = (q[y]*p[x] - q[x]*p[y])/(q[x]*r[y] - q[y]*r[x])
u = (p[x] + t*r[x])/q[x]

Böylece işlev şudur:

def intersects(a, b):
    p = [b[0][0]-a[0][0], b[0][1]-a[0][1]]
    q = [a[1][0]-a[0][0], a[1][1]-a[0][1]]
    r = [b[1][0]-b[0][0], b[1][1]-b[0][1]]

    t = (q[1]*p[0] - q[0]*p[1])/(q[0]*r[1] - q[1]*r[0]) \
        if (q[0]*r[1] - q[1]*r[0]) != 0 \
        else (q[1]*p[0] - q[0]*p[1])
    u = (p[0] + t*r[0])/q[0] \
        if q[0] != 0 \
        else (p[1] + t*r[1])/q[1]

    return t >= 0 and t <= 1 and u >= 0 and u <= 1

1

Bu benim çizgi geçişini ve kavşağın nerede gerçekleştiğini kontrol etme yöntemim. X1'den x4'e ve y1'den y4'e kadar kullanalım

Segment1 = {(X1, Y1), (X2, Y2)}
Segment2 = {(X3, Y3), (X4, Y4)}

O zaman onları temsil etmek için bazı vektörlere ihtiyacımız var

dx1 = X2 - X1
dx2 = X4 - X4
dy1 = Y2 - Y1
dy2 = Y4 - Y3

Şimdi determinanta bakıyoruz

det = dx1 * dy2 - dx2 * dy1

Belirleyici 0.0 ise, çizgi segmentleri paraleldir. Bu, üst üste geldikleri anlamına gelebilir. Sadece uç noktalarda örtüşüyorlarsa, o zaman bir kavşak çözümü vardır. Aksi takdirde sonsuz çözümler olacaktır. Sonsuz sayıda çözüm varken, kesişme noktanız ne diyor? Bu yüzden ilginç özel bir durum. Çizgilerin üst üste gelemeyeceğini önceden biliyorsanız, sadece det == 0.0kesişmediklerini ve yapıldıklarını söyleyin. Aksi takdirde devam edelim

dx3 = X3 - X1
dy3 = Y3 - Y1

det1 = dx1 * dy3 - dx3 * dy1
det2 = dx2 * dy3 - dx3 * dy2

Şimdi, eğer det, det1 ve det2 sıfırsa, o zaman çizgileriniz eş doğrusaldır ve örtüşebilir. Det sıfırsa, ancak det1 veya det2 değilse, o zaman bunlar eş doğrusal değillerdir, paraleldirler, dolayısıyla kesişme yoktur. Öyleyse şimdi det sıfırsa geriye kalan şey 2B yerine 1B problemidir. Dx1'in sıfır olup olmadığına bağlı olarak iki yoldan birini kontrol etmemiz gerekecek (böylece sıfıra bölmeyi önleyebiliriz). Eğer dx1 sıfırsa, aynı mantığı aşağıdaki x yerine y değerleriyle yapın.

s = X3 / dx1
t = X4 / dx1

Bu, iki ölçekleyiciyi hesaplar, öyle ki vektörü (dx1, dy1) s ile ölçeklendirirsek (x3, y3) noktasını ve t ile (x4, y4) elde ederiz. Yani s veya t 0.0 ile 1.0 arasındaysa, 3. veya 4. nokta ilk çizgimizde yer alır. Negatif, noktanın vektörümüzün başlangıcının gerisinde olduğu anlamına gelirken,> 1.0, vektörümüzün sonunun daha ilerisinde olduğu anlamına gelir. 0.0, (x1, y1) konumunda olduğu ve 1.0 (x2, y2) konumunda olduğu anlamına gelir. Hem s hem de t <0.0 veya her ikisi de> 1.0 ise, kesişmezler. Ve bu paralel çizgilerin özel durumunu ele alır.

Şimdi, eğer det != 0.0öyleyse

s = det1 / det
t = det2 / det
if (s < 0.0 || s > 1.0 || t < 0.0 || t > 1.0)
    return false  // no intersect

Bu aslında yukarıda yaptığımız şeye benziyor. Şimdi yukarıdaki testi geçersek, doğru segmentlerimiz kesişir ve kesişim noktasını şu şekilde kolayca hesaplayabiliriz:

Ix = X1 + t * dx1
Iy = Y1 + t * dy1

Matematiğin ne yaptığını daha derinlemesine incelemek istiyorsanız, Cramer's Rule'a bakın.



1

Georgy'nin cevabı açık ara en temiz . Brycboe örneğinin basit olmasına rağmen eşdoğrusallıkla ilgili sorunları olduğu için bunu takip etmem gerekiyordu.

Test için kod:

#!/usr/bin/python
#
# Notes on intersection:
#
# https://bryceboe.com/2006/10/23/line-segment-intersection-algorithm/
#
# /programming/3838329/how-can-i-check-if-two-segments-intersect

from shapely.geometry import LineString

class Point:
    def __init__(self,x,y):
        self.x = x
        self.y = y

def ccw(A,B,C):
    return (C.y-A.y)*(B.x-A.x) > (B.y-A.y)*(C.x-A.x)

def intersect(A,B,C,D):
    return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)


def ShapelyIntersect(A,B,C,D):
    return LineString([(A.x,A.y),(B.x,B.y)]).intersects(LineString([(C.x,C.y),(D.x,D.y)]))


a = Point(0,0)
b = Point(0,1)
c = Point(1,1)
d = Point(1,0)

'''
Test points:

b(0,1)   c(1,1)




a(0,0)   d(1,0)
'''

# F
print(intersect(a,b,c,d))

# T
print(intersect(a,c,b,d))
print(intersect(b,d,a,c))
print(intersect(d,b,a,c))

# F
print(intersect(a,d,b,c))

# same end point cases:
print("same end points")
# F - not intersected
print(intersect(a,b,a,d))
# T - This shows as intersected
print(intersect(b,a,a,d))
# F - this does not
print(intersect(b,a,d,a))
# F - this does not
print(intersect(a,b,d,a))

print("same end points, using shapely")
# T
print(ShapelyIntersect(a,b,a,d))
# T
print(ShapelyIntersect(b,a,a,d))
# T
print(ShapelyIntersect(b,a,d,a))
# T
print(ShapelyIntersect(a,b,d,a))

0

Verileriniz çizgiyi tanımlıyorsa, paralel olmadıklarını kanıtlamanız gerekir. Bunu yapmak için hesaplayabilirsiniz

alpha = float(y2 - y1) / (x2 - x1).

Bu katsayı hem Hat1 hem de Hat2 için eşitse, doğrunun paralel olduğu anlamına gelir. Aksi takdirde, kesişecekleri anlamına gelir.

Paralel ise, aynı olmadıklarını kanıtlamanız gerekir. Bunun için hesaplarsın

beta = y1 - alpha*x1

Satır1 ve Satır2 için beta aynıysa, bunlar eşit oldukları için kesiştiğiniz anlamına gelir

Segment iseler, yine de yukarıda her Satır için açıklandığı gibi alfa ve beta hesaplamanız gerekir. Ardından (beta1 - beta2) / (alpha1 - alpha2) 'nin Min'den (x1_line1, x2_line1) büyük ve Max'tan (x1_line1, x2_line1) küçük olduğunu kontrol etmelisiniz.


0

Segmentlerinize yerleştirilen çizgilerin kesişme noktasını hesaplayın (temelde doğrusal bir denklem sistemini çözmek anlamına gelir), ardından segmentlerinizin başlangıç ​​ve bitiş noktaları arasında olup olmadığını kontrol edin.


0

AS3 için sahip olduğum şey bu, python hakkında pek bir şey bilmiyorum ama konsept orada

    public function getIntersectingPointF($A:Point, $B:Point, $C:Point, $D:Point):Number {
        var A:Point = $A.clone();
        var B:Point = $B.clone();
        var C:Point = $C.clone();
        var D:Point = $D.clone();
        var f_ab:Number = (D.x - C.x) * (A.y - C.y) - (D.y - C.y) * (A.x - C.x);

        // are lines parallel
        if (f_ab == 0) { return Infinity };

        var f_cd:Number = (B.x - A.x) * (A.y - C.y) - (B.y - A.y) * (A.x - C.x);
        var f_d:Number = (D.y - C.y) * (B.x - A.x) - (D.x - C.x) * (B.y - A.y);
        var f1:Number = f_ab/f_d
        var f2:Number = f_cd / f_d
        if (f1 == Infinity || f1 <= 0 || f1 >= 1) { return Infinity };
        if (f2 == Infinity || f2 <= 0 || f2 >= 1) { return Infinity };
        return f1;
    }

    public function getIntersectingPoint($A:Point, $B:Point, $C:Point, $D:Point):Point
    {
        var f:Number = getIntersectingPointF($A, $B, $C, $D);
        if (f == Infinity || f <= 0 || f >= 1) { return null };

        var retPoint:Point = Point.interpolate($A, $B, 1 - f);
        return retPoint.clone();
    }

0

JAVA'da uygulanmıştır. Ancak ko-lineer çizgiler için çalışmadığı görülmektedir (aka birbiri içinde bulunan doğru segmentleri L1 (0,0) (10,10) L2 (1,1) (2,2)

public class TestCode
{

  public class Point
  {
    public double x = 0;
    public double y = 0;
    public Point(){}
  }

  public class Line
  {
    public Point p1, p2;
    public Line( double x1, double y1, double x2, double y2) 
    {
      p1 = new Point();
      p2 = new Point();
      p1.x = x1;
      p1.y = y1;
      p2.x = x2;
      p2.y = y2;
    }
  }

  //line segments
  private static Line s1;
  private static Line s2;

  public TestCode()
  {
    s1 = new Line(0,0,0,10);
    s2 = new Line(-1,0,0,10);
  }

  public TestCode(double x1, double y1, 
    double x2, double y2,
    double x3, double y3,
    double x4, double y4)
  {
    s1 = new Line(x1,y1, x2,y2);
    s2 = new Line(x3,y3, x4,y4);
  }

  public static void main(String args[])
  {
     TestCode code  = null;
////////////////////////////
     code = new TestCode(0,0,0,10,
                         0,1,0,5);
     if( intersect(code) )
     { System.out.println( "OK COLINEAR: INTERSECTS" ); }
     else
     { System.out.println( "ERROR COLINEAR: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(0,0,0,10,
                         0,1,0,10);
     if( intersect(code) )
     { System.out.println( "OK COLINEAR: INTERSECTS" ); }
     else
     { System.out.println( "ERROR COLINEAR: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(0,0,10,0,
                         5,0,15,0);
     if( intersect(code) )
     { System.out.println( "OK COLINEAR: INTERSECTS" ); }
     else
     { System.out.println( "ERROR COLINEAR: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(0,0,10,0,
                         0,0,15,0);
     if( intersect(code) )
     { System.out.println( "OK COLINEAR: INTERSECTS" ); }
     else
     { System.out.println( "ERROR COLINEAR: DO NOT INTERSECT" ); }

////////////////////////////
     code = new TestCode(0,0,10,10,
                         1,1,5,5);
     if( intersect(code) )
     { System.out.println( "OK COLINEAR: INTERSECTS" ); }
     else
     { System.out.println( "ERROR COLINEAR: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(0,0,0,10,
                         -1,-1,0,10);
     if( intersect(code) )
     { System.out.println( "OK SLOPE END: INTERSECTS" ); }
     else
     { System.out.println( "ERROR SLOPE END: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(-10,-10,10,10,
                         -10,10,10,-10);
     if( intersect(code) )
     { System.out.println( "OK SLOPE Intersect(0,0): INTERSECTS" ); }
     else
     { System.out.println( "ERROR SLOPE Intersect(0,0): DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(-10,-10,10,10,
                         -3,-2,50,-2);
     if( intersect(code) )
     { System.out.println( "OK SLOPE Line2 VERTIAL: INTERSECTS" ); }
     else
     { System.out.println( "ERROR SLOPE Line2 VERTICAL: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(-10,-10,10,10,
                         50,-2,-3,-2);
     if( intersect(code) )
     { System.out.println( "OK SLOPE Line2 (reversed) VERTIAL: INTERSECTS" ); }
     else
     { System.out.println( "ERROR SLOPE Line2 (reversed) VERTICAL: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(0,0,0,10,
                         1,0,1,10);
     if( intersect(code) )
     { System.out.println( "ERROR PARALLEL VERTICAL: INTERSECTS" ); }
     else
     { System.out.println( "OK PARALLEL VERTICAL: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(0,2,10,2,
                         0,10,10,10);
     if( intersect(code) )
     { System.out.println( "ERROR PARALLEL HORIZONTAL: INTERSECTS" ); }
     else
     { System.out.println( "OK PARALLEL HORIZONTAL: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(0,10,5,13.75,
                         0,18.75,10,15);
     if( intersect(code) )
     { System.out.println( "ERROR PARALLEL SLOPE=.75: INTERSECTS" ); }
     else
     { System.out.println( "OK PARALLEL SLOPE=.75: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(0,0,1,1,
                         2,-1,2,10);
     if( intersect(code) )
     { System.out.println( "ERROR SEPERATE SEGMENTS: INTERSECTS" ); }
     else
     { System.out.println( "OK SEPERATE SEGMENTS: DO NOT INTERSECT" ); }
////////////////////////////
     code = new TestCode(0,0,1,1,
                         -1,-10,-5,10);
     if( intersect(code) )
     { System.out.println( "ERROR SEPERATE SEGMENTS 2: INTERSECTS" ); }
     else
     { System.out.println( "OK SEPERATE SEGMENTS 2: DO NOT INTERSECT" ); }
  }

  public static boolean intersect( TestCode code )
  {
    return intersect( code.s1, code.s2);
  }

  public static boolean intersect( Line line1, Line line2 )
  {
    double i1min = Math.min(line1.p1.x, line1.p2.x);
    double i1max = Math.max(line1.p1.x, line1.p2.x);
    double i2min = Math.min(line2.p1.x, line2.p2.x);
    double i2max = Math.max(line2.p1.x, line2.p2.x);

    double iamax = Math.max(i1min, i2min);
    double iamin = Math.min(i1max, i2max);

    if( Math.max(line1.p1.x, line1.p2.x) < Math.min(line2.p1.x, line2.p2.x) )
      return false;

    double m1 = (line1.p2.y - line1.p1.y) / (line1.p2.x - line1.p1.x );
    double m2 = (line2.p2.y - line2.p1.y) / (line2.p2.x - line2.p1.x );

    if( m1 == m2 )
        return false;

    //b1 = line1[0][1] - m1 * line1[0][0]
    //b2 = line2[0][1] - m2 * line2[0][0]
    double b1 = line1.p1.y - m1 * line1.p1.x;
    double b2 = line2.p1.y - m2 * line2.p1.x;
    double x1 = (b2 - b1) / (m1 - m2);
    if( (x1 < Math.max(i1min, i2min)) || (x1 > Math.min(i1max, i2max)) )
        return false;
    return true;
  }
}

Şimdiye kadarki çıktı

ERROR COLINEAR: DO NOT INTERSECT
ERROR COLINEAR: DO NOT INTERSECT
ERROR COLINEAR: DO NOT INTERSECT
ERROR COLINEAR: DO NOT INTERSECT
ERROR COLINEAR: DO NOT INTERSECT
OK SLOPE END: INTERSECTS
OK SLOPE Intersect(0,0): INTERSECTS
OK SLOPE Line2 VERTIAL: INTERSECTS
OK SLOPE Line2 (reversed) VERTIAL: INTERSECTS
OK PARALLEL VERTICAL: DO NOT INTERSECT
OK PARALLEL HORIZONTAL: DO NOT INTERSECT
OK PARALLEL SLOPE=.75: DO NOT INTERSECT
OK SEPERATE SEGMENTS: DO NOT INTERSECT
OK SEPERATE SEGMENTS 2: DO NOT INTERSECT

0

Güzel bir Swift çözümüne katkıda bulunacağımı düşündüm:

struct Pt {
    var x: Double
    var y: Double
}

struct LineSegment {
    var p1: Pt
    var p2: Pt
}

func doLineSegmentsIntersect(ls1: LineSegment, ls2: LineSegment) -> Bool {

    if (ls1.p2.x-ls1.p1.x == 0) { //handle vertical segment1
        if (ls2.p2.x-ls2.p1.x == 0) {
            //both lines are vertical and parallel
            return false
        }

        let x = ls1.p1.x

        let slope2 = (ls2.p2.y-ls2.p1.y)/(ls2.p2.x-ls2.p1.x)
        let c2 = ls2.p1.y-slope2*ls2.p1.x

        let y = x*slope2+c2 // y intersection point

        return (y > ls1.p1.y && x < ls1.p2.y) || (y > ls1.p2.y && y < ls1.p1.y) // check if y is between y1,y2 in segment1
    }

    if (ls2.p2.x-ls2.p1.x == 0) { //handle vertical segment2

        let x = ls2.p1.x

        let slope1 = (ls1.p2.y-ls1.p1.y)/(ls1.p2.x-ls1.p1.x)
        let c1 = ls1.p1.y-slope1*ls1.p1.x

        let y = x*slope1+c1 // y intersection point

        return (y > ls2.p1.y && x < ls2.p2.y) || (y > ls2.p2.y && y < ls2.p1.y) // validate that y is between y1,y2 in segment2

    }

    let slope1 = (ls1.p2.y-ls1.p1.y)/(ls1.p2.x-ls1.p1.x)
    let slope2 = (ls2.p2.y-ls2.p1.y)/(ls2.p2.x-ls2.p1.x)

    if (slope1 == slope2) { //segments are parallel
        return false
    }

    let c1 = ls1.p1.y-slope1*ls1.p1.x
    let c2 = ls2.p1.y-slope2*ls2.p1.x

    let x = (c2-c1)/(slope1-slope2)

    return (((x > ls1.p1.x && x < ls1.p2.x) || (x > ls1.p2.x && x < ls1.p1.x)) &&
        ((x > ls2.p1.x && x < ls2.p2.x) || (x > ls2.p2.x && x < ls2.p1.x)))
    //validate that x is between x1,x2 in both segments

}

0

Yukarıdaki çözümlerden biri o kadar iyi çalıştı ki wxPython kullanarak eksiksiz bir gösteri programı yazmaya karar verdim. Bu programı şu şekilde çalıştırabilmelisiniz: python " dosya adınız "

# Click on the window to draw a line.
# The program will tell you if this and the other line intersect.

import wx

class Point:
    def __init__(self, newX, newY):
        self.x = newX
        self.y = newY

app = wx.App()
frame = wx.Frame(None, wx.ID_ANY, "Main")
p1 = Point(90,200)
p2 = Point(150,80)
mp = Point(0,0) # mouse point
highestX = 0


def ccw(A,B,C):
    return (C.y-A.y) * (B.x-A.x) > (B.y-A.y) * (C.x-A.x)

# Return true if line segments AB and CD intersect
def intersect(A,B,C,D):
    return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)

def is_intersection(p1, p2, p3, p4):
    return intersect(p1, p2, p3, p4)

def drawIntersection(pc):
    mp2 = Point(highestX, mp.y)
    if is_intersection(p1, p2, mp, mp2):
        pc.DrawText("intersection", 10, 10)
    else:
        pc.DrawText("no intersection", 10, 10)

def do_paint(evt):
    pc = wx.PaintDC(frame)
    pc.DrawLine(p1.x, p1.y, p2.x, p2.y)
    pc.DrawLine(mp.x, mp.y, highestX, mp.y)
    drawIntersection(pc)

def do_left_mouse(evt):
    global mp, highestX
    point = evt.GetPosition()
    mp = Point(point[0], point[1])
    highestX = frame.Size[0]
    frame.Refresh()

frame.Bind(wx.EVT_PAINT, do_paint)
frame.Bind(wx.EVT_LEFT_DOWN, do_left_mouse)
frame.Show()
app.MainLoop()

0

OMG_Peanuts çözümünü kullanarak SQL'e çevirdim . (HANA Skaler İşlevi)

Teşekkürler OMG_Peanuts, harika çalışıyor. Yuvarlak toprak kullanıyorum, ancak mesafeler küçük, bu yüzden sorun olmadığını düşündüm.

FUNCTION GA_INTERSECT" ( IN LAT_A1 DOUBLE,
         IN LONG_A1 DOUBLE,
         IN LAT_A2 DOUBLE,
         IN LONG_A2 DOUBLE,
         IN LAT_B1 DOUBLE,
         IN LONG_B1 DOUBLE,
         IN LAT_B2 DOUBLE,
         IN LONG_B2 DOUBLE) 
    
RETURNS RET_DOESINTERSECT DOUBLE
    LANGUAGE SQLSCRIPT
    SQL SECURITY INVOKER AS
BEGIN

    DECLARE MA DOUBLE;
    DECLARE MB DOUBLE;
    DECLARE BA DOUBLE;
    DECLARE BB DOUBLE;
    DECLARE XA DOUBLE;
    DECLARE MAX_MIN_X DOUBLE;
    DECLARE MIN_MAX_X DOUBLE;
    DECLARE DOESINTERSECT INTEGER;
    
    SELECT 1 INTO DOESINTERSECT FROM DUMMY;
    
    IF LAT_A2-LAT_A1 != 0 AND LAT_B2-LAT_B1 != 0 THEN
        SELECT (LONG_A2 - LONG_A1)/(LAT_A2 - LAT_A1) INTO MA FROM DUMMY; 
        SELECT (LONG_B2 - LONG_B1)/(LAT_B2 - LAT_B1) INTO MB FROM DUMMY;
        IF MA = MB THEN
            SELECT 0 INTO DOESINTERSECT FROM DUMMY;
        END IF;
    END IF;
    
    SELECT LONG_A1-MA*LAT_A1 INTO BA FROM DUMMY;
    SELECT LONG_B1-MB*LAT_B1 INTO BB FROM DUMMY;
    SELECT (BB - BA) / (MA - MB) INTO XA FROM DUMMY;
    
    -- Max of Mins
    IF LAT_A1 < LAT_A2 THEN         -- MIN(LAT_A1, LAT_A2) = LAT_A1
        IF LAT_B1 < LAT_B2 THEN        -- MIN(LAT_B1, LAT_B2) = LAT_B1
            IF LAT_A1 > LAT_B1 THEN       -- MAX(LAT_A1, LAT_B1) = LAT_A1
                SELECT LAT_A1 INTO MAX_MIN_X FROM DUMMY;
            ELSE                          -- MAX(LAT_A1, LAT_B1) = LAT_B1
                SELECT LAT_B1 INTO MAX_MIN_X FROM DUMMY;
            END IF;
        ELSEIF LAT_B2 < LAT_B1 THEN   -- MIN(LAT_B1, LAT_B2) = LAT_B2
            IF LAT_A1 > LAT_B2 THEN       -- MAX(LAT_A1, LAT_B2) = LAT_A1
                SELECT LAT_A1 INTO MAX_MIN_X FROM DUMMY;
            ELSE                          -- MAX(LAT_A1, LAT_B2) = LAT_B2
                SELECT LAT_B2 INTO MAX_MIN_X FROM DUMMY;
            END IF;
        END IF;
    ELSEIF LAT_A2 < LAT_A1 THEN     -- MIN(LAT_A1, LAT_A2) = LAT_A2
        IF LAT_B1 < LAT_B2 THEN        -- MIN(LAT_B1, LAT_B2) = LAT_B1
            IF LAT_A2 > LAT_B1 THEN       -- MAX(LAT_A2, LAT_B1) = LAT_A2
                SELECT LAT_A2 INTO MAX_MIN_X FROM DUMMY;
            ELSE                          -- MAX(LAT_A2, LAT_B1) = LAT_B1
                SELECT LAT_B1 INTO MAX_MIN_X FROM DUMMY;
            END IF;
        ELSEIF LAT_B2 < LAT_B1 THEN   -- MIN(LAT_B1, LAT_B2) = LAT_B2
            IF LAT_A2 > LAT_B2 THEN       -- MAX(LAT_A2, LAT_B2) = LAT_A2
                SELECT LAT_A2 INTO MAX_MIN_X FROM DUMMY;
            ELSE                          -- MAX(LAT_A2, LAT_B2) = LAT_B2
                SELECT LAT_B2 INTO MAX_MIN_X FROM DUMMY;
            END IF;
        END IF;
    END IF;
    
    -- Min of Max
    IF LAT_A1 > LAT_A2 THEN         -- MAX(LAT_A1, LAT_A2) = LAT_A1
        IF LAT_B1 > LAT_B2 THEN        -- MAX(LAT_B1, LAT_B2) = LAT_B1
            IF LAT_A1 < LAT_B1 THEN       -- MIN(LAT_A1, LAT_B1) = LAT_A1
                SELECT LAT_A1 INTO MIN_MAX_X FROM DUMMY;
            ELSE                          -- MIN(LAT_A1, LAT_B1) = LAT_B1
                SELECT LAT_B1 INTO MIN_MAX_X FROM DUMMY;
            END IF;
        ELSEIF LAT_B2 > LAT_B1 THEN   -- MAX(LAT_B1, LAT_B2) = LAT_B2
            IF LAT_A1 < LAT_B2 THEN       -- MIN(LAT_A1, LAT_B2) = LAT_A1
                SELECT LAT_A1 INTO MIN_MAX_X FROM DUMMY;
            ELSE                          -- MIN(LAT_A1, LAT_B2) = LAT_B2
                SELECT LAT_B2 INTO MIN_MAX_X FROM DUMMY;
            END IF;
        END IF;
    ELSEIF LAT_A2 > LAT_A1 THEN     -- MAX(LAT_A1, LAT_A2) = LAT_A2
        IF LAT_B1 > LAT_B2 THEN        -- MAX(LAT_B1, LAT_B2) = LAT_B1
            IF LAT_A2 < LAT_B1 THEN       -- MIN(LAT_A2, LAT_B1) = LAT_A2
                SELECT LAT_A2 INTO MIN_MAX_X FROM DUMMY;
            ELSE                          -- MIN(LAT_A2, LAT_B1) = LAT_B1
                SELECT LAT_B1 INTO MIN_MAX_X FROM DUMMY;
            END IF;
        ELSEIF LAT_B2 > LAT_B1 THEN   -- MAX(LAT_B1, LAT_B2) = LAT_B2
            IF LAT_A2 < LAT_B2 THEN       -- MIN(LAT_A2, LAT_B2) = LAT_A2
                SELECT LAT_A2 INTO MIN_MAX_X FROM DUMMY;
            ELSE                          -- MIN(LAT_A2, LAT_B2) = LAT_B2
                SELECT LAT_B2 INTO MIN_MAX_X FROM DUMMY;
            END IF;
        END IF;
    END IF;
        
    
    IF XA < MAX_MIN_X OR
       XA > MIN_MAX_X THEN  
       SELECT 0 INTO DOESINTERSECT FROM DUMMY;
    END IF;
    
    RET_DOESINTERSECT := :DOESINTERSECT;
END;

-2

Çözüldü ama yine de neden python ile değil ... :)

def islineintersect(line1, line2):
    i1 = [min(line1[0][0], line1[1][0]), max(line1[0][0], line1[1][0])]
    i2 = [min(line2[0][0], line2[1][0]), max(line2[0][0], line2[1][0])]
    ia = [max(i1[0], i2[0]), min(i1[1], i2[1])]
    if max(line1[0][0], line1[1][0]) < min(line2[0][0], line2[1][0]):
        return False
    m1 = (line1[1][1] - line1[0][1]) * 1. / (line1[1][0] - line1[0][0]) * 1.
    m2 = (line2[1][1] - line2[0][1]) * 1. / (line2[1][0] - line2[0][0]) * 1.
    if m1 == m2:
        return False
    b1 = line1[0][1] - m1 * line1[0][0]
    b2 = line2[0][1] - m2 * line2[0][0]
    x1 = (b2 - b1) / (m1 - m2)
    if (x1 < max(i1[0], i2[0])) or (x1 > min(i1[1], i2[1])):
        return False
    return True

Bu:

print islineintersect([(15, 20), (100, 200)], [(210, 5), (23, 119)])

Çıktı:

True

Ve bu:

print islineintersect([(15, 20), (100, 200)], [(-1, -5), (-5, -5)])

Çıktı:

False
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.