Niestety nadal nie jestem tak silny w zrozumieniu algorytmu linii przeciągania . Wszystkie artykuły i podręczniki na ten temat są już przeczytane, jednak ich zrozumienie jest wciąż bardzo odległe. Aby to wyjaśnić, próbuję rozwiązać jak najwięcej ćwiczeń. Ale naprawdę interesujące i ważne zadania wciąż stanowią dla mnie wyzwanie.
Poniższe ćwiczenie znalazłem w notatkach z wykładu przecięcia segmentów liniowych przez wszechmocnego Jeffa Ericksona.
Ćwiczenie 2. Opisz i przeanalizuj algorytm linii prostej, aby określić, biorąc pod uwagę okręgów na płaszczyźnie, czy dowolne dwa się przecinają, w czasie O ( n log n ) . Każde koło jest określone przez jego środek i promień, więc wejście składa się z trzech tablic X [ 1 .. n ] , Y [ 1 .. n ] i R [ 1 .. n ] . Uważaj, aby poprawnie zaimplementować operacje podstawowe niskiego poziomu.
Spróbujmy uczynić skomplikowaną rzecz łatwiejszą. Co wiemy o przecięciu kół? Jaki analog można znaleźć przy przecięciu linii. Dwie linie mogą się przecinać, jeśli sąsiadują, która właściwość powinna mieć dwa kółka, aby się przecinać? Niech będzie odległością między środkami kół, r 0 i r 1 środkami kół. Rozważ kilka przypadków:
Przypadek 1: Jeśli nie ma rozwiązań, koła są osobne.
Przypadek 2: Jeśli wtedy nie ma rozwiązań, ponieważ jedno koło jest zawarte w drugim.
Przypadek 3: Jeżeli i r 0 = r 1, wówczas koła są zbieżne i istnieje nieskończona liczba rozwiązań.
Wygląda więc na to, że warunki skrzyżowania są gotowe, oczywiście mogą to być złe warunki. Proszę poprawić, jeśli tak jest.
Algorytm. Teraz musimy znaleźć coś wspólnego między dwoma przecinającymi się okręgami. W przypadku przecięcia linii analogowej do linii musimy wprowadzić warunek wstawiania i usuwać warunek do kolejki zdarzeń. Powiedzmy, że punktem zdarzenia jest współrzędna x pierwszego i ostatniego punktu, którego dotyka pionowa linia przeciągnięcia. W pierwszym punkcie wstawiamy okrąg do statusu i sprawdzamy przecięcie (3 przypadki do sprawdzenia są wspomniane powyżej) z najbliższymi okręgami, w ostatnim punkcie usuwamy koło ze statusu .
Wygląda na to, że wystarczy dla algorytmu linii przeciągnięcia. Jeśli coś jest nie tak lub może być coś, co należy zrobić inaczej, podziel się z nami swoimi przemyśleniami.
Dodatek :
Wstawiam okrąg, gdy pionowa linia przeciągnięcia dotyka koła po raz pierwszy, i usuwam okrąg ze stanu, gdy linia przeciągnięcia dotyka go po raz ostatni. Sprawdzanie skrzyżowania należy wykonać dla najbliższego poprzedniego okręgu. Gdybyśmy dodali krąg do statusu i istniał już inny krąg, który dodaliśmy wcześniej, i nadal tam był, dlatego przepadający krąg nie został „zamknięty”, więc może istnieć skrzyżowanie.
status
utrzymuje kółka przecinające linię przeciągnięcia? Załóżmy, że masz obecnie 100 kręgów status
, przetwarzasz zdarzenie wstawiania i wstawiasz 101. krąg. Ile kręgów porównujesz, aby sprawdzić skrzyżowanie? Jak wybrać kręgi do porównania?