Çizgi segmenti kavşakları tespit etmek kolay bir yolu var mı?

2 Cevap php

Bu ilk bakışta göründüğünden daha çok daha karmaşıktır. Ne var yani gibi [bir dizi "x, y" şeklinde] noktaları içeren daha diziler oluşur dev bir dizidir:

Array (
    [0] => Array (
        [0] => "0,9",
        [1] => "0,0",
        [2] => "9,0",
        [3] => "9,9",
        [4] => "0,9"
        )
    [1] => Array (
        [0] => "1,5",
        [1] => "1,6",
        [2] => "3,6",
        [3] => "3,8",
        [4] => "4,8"
    )
    ... and so on ...
)

Peki ne yapmam gerekiyor tüm noktaları aracılığıyla süreçtir ve bir dizide herhangi bir nokta, dizide var olabilecek herhangi bir başka çizgi segmenti ile kesişiyor, $points[0][1] $points[0][2] derseniz bakın . Bütün çizgi parçası kendi ilgili dizilerin her birinde bulunan sırayla art arda şu bulunmaktadır. Yani ilk dizide, "0,9", "0,0" ve bu dizi başka hiçbir nokta gider. Dizideki son nokta geri etrafında bir dizi ilk noktaya döngü değil. Ayrıca, bir kavşak, bir çizgi segmenti bir başka çizgi parçasının kesiştiği biterse, o aslında kesişen çizgi parçasını geçmeye ihtiyacı kabul edilmemelidir.

Ben bunları işlenmiş olarak ben kesimleri komplo düşünüyordum. Yani demek başına bir 'sanal' ızgara üzerinde ve herhangi bir mantıklı eğer zaten, çizilen, ama yine de bu gibi görünüyor başka bir segment kesiştiğini ondan sonra her dizi hesaplar her noktayı komplo diziler aracılığıyla çalıştırmak gibi bir sürebilir çizgi segmentleri bir çok dizide varsa hesaplamak için ise. O (teorik o olduğu aynı dizideki bir segment kesiştiği çünkü) ne yapıyor olurdum kendisine önceki herhangi bir segment kesiştiğini hesaplamak, bir dizideki her segment için gibi görünüyor. Doğru, bunu yapmak için basit bir yolu olmalı var?

P.S. Ben gerçekten bu PHP dışındaki altına düşmesi gereken etiketleri düşünemedim. Eğer herhangi düşünüyorsanız bunu yeniden etiketlemek için çekinmeyin.

2 Cevap

İşte her listede puan sayısı az ise kabul edilebilir basit bir yöntem var:

  1. Sizin dizideki ilk iki çizgi parçalarını alın ve check if they intersect.
  2. Değilse, önceki hat kesimlerinin karşı sonraki çizgi parçasını kontrol
  3. Son noktasına kadar devam edecek ve başka bir dizi için yinelemek (Bunu yapıyoruz, bu onay her bir alt dizi için sayıyorum).

Müthiş değilse, bize bildirin - Bu O(n2) where n tüm altdizilimlerden noktaların sayısı n küçük ise --- olmasıdır.

Update: If O(n2) is not good enough ...

Sweep line algorithm for segment intersection - sözde O(n log (n))

Düzlemde çizgi segmentleri Input: kümesi.

S. kesimleri arasında kesişme noktaları Output: kümesi

Bu oldukça kolay. Her satırın denklemini (eğim ve Y kesişim) bilgisayar başlayın. Eğim (E 1-Y 2) ile / (X 1 X-2). Y kesişim Y 1 - eğim * X 1. Biz o formda çizgiyi ifade edebilir m = eğim ve b, y = mx + b = Y kesişimi.

Eğer bir çifti için bu bilgisayarlı sonra, bu lines çapraz olacak yeri hesaplamak. X ve Y, bir satır diğer hattının eşit X ve Y koordinatı yerdir. Bir satır için denklem diğer çizgi için denklemi eşittir Diğer bir deyişle,: m 1 X + b 1 = m 2 X + b {[ (3)]}. Daha sonra iki satır Y = 3x +5 ve Y = 0,5 x +2 verilen Örneğin, X izole ederek bu denklemi çözebilir:

3x+5 = .5x+2 // subtract 5 from both sides
3x = .5x - 3 // subtract .5x fro both sides
2.5x = -3    // divide by 2.5
x = -3/2.5   // reduce term
x = -1.2

Şimdi iki lines kesişim noktasını tespit ettik, ama biz hem kesimleri bu noktayı eklemek için yeterince uzatmak olmadığını bilmiyorum. Bunu yapmak için, bizim X değeri iki hat kesimleri için X 1 ve X 2 arasında olup olmadığını kontrol etmek gerekir.

Bir lot hatları için kavşak kontrol etmek için gidiyoruz eğer, muhtemelen bir bağlantı eklemek için çalışacağız olmaz ("uçak süpürme algoritması" aramak istiyorum, ama gerektiği için google'da edeceğiz Bulunmuş adil bir dizi) verir.