Przeskocz do treści

Delta mi!

Zawieramy wielokąty

Tomasz Idziaszek

o artykule ...

  • Publikacja w Delcie: maj 2013
  • Publikacja elektroniczna: 30-04-2013
  • Wersja do druku [application/pdf]: (75 KB)

Na artykule Problemy 3sum-trudne w geometrii autor podał trzy wersje problemu PolygonContainment, które są uważane za trudne – nie umiemy ich rozwiązać w czasie (istotnie) lepszym niż kwadratowy. Uważni Czytelnicy na pewno zauważyli, że nie jest tam wspomniane o wersji, w której wielokąty są wypukłe i dopuszczamy dowolne przesunięcia (ale nie obroty). Ten brak jest w pełni uzasadniony, gdyż tę wersję problemu można rozwiązać w czasie liniowym względem liczby wierzchołków wielokątów, co pokażemy poniżej.

obrazek

Rys. 1 Wielokąt math można umieścić wewnątrz wielokąta math

Rys. 1 Wielokąt math można umieścić wewnątrz wielokąta math

obrazek

Rys. 2 Wierzchołek math jest wierzchołkiem krytycznym dla boku math

Rys. 2 Wierzchołek math jest wierzchołkiem krytycznym dla boku math

Niech math będzie wielokątem o wierzchołkach math który chcemy umieścić wewnątrz wielokąta math  o wierzchołkach math(przyjmujemy, że math  i  math ). Niech math będzie dowolnym punktem wewnątrz wielokąta math (Rys. 1). Załóżmy dla uproszczenia, że żadna para boków wielokątów nie jest równoległa oraz żaden bok nie jest pionowy.

Przez math (dla math ) oznaczmy tę półpłaszczyznę wyznaczoną przez prostą math  która zawiera wielokąt math  Przesuńmy teraz wielokąt math tak, aby zawierał się w  math  i aby odległość punktu math od prostej math  była jak najmniejsza; oznaczmy tę odległość przez math Zauważmy, że math możemy obliczyć bez kłopotu, jeśli wyznaczymy wierzchołek przesuniętego wielokąta math który leży na brzegu półpłaszczyzny math  nazwiemy ten wierzchołek krytycznym dla boku math (Rys. 2).

Zauważmy, że wielokąt math zawiera się w  math  dokładnie wtedy, gdy punkt math zawiera się w półpłaszczyźnie math  która jest wyznaczona przez prostą równoległą do math  w odległości math Jest jasne, że math znajduje się wewnątrz math  dokładnie wtedy, gdy znajduje się w każdej z półpłaszczyzn math  innymi słowy wtedy, gdy punkt math należy do przecięcia półpłaszczyzn math  Co więcej, przecięcie półpłaszczyzn zawiera wszystkie możliwe położenia punktu math

Do pełnego rozwiązania pozostaje zatem pokazanie, jak efektywnie wyznaczyć wierzchołki krytyczne, a następnie przecięcie półpłaszczyzn.


Wyznaczanie wierzchołków krytycznych

obrazek

Rys. 3 Nachylenia boków wielokątów naniesione na okrąg.

Rys. 3 Nachylenia boków wielokątów naniesione na okrąg.

Narysujmy okrąg i zaznaczmy na nim, dla math punkt styczności math prostej stycznej do okręgu i równoległej do prostej math Analogicznie zaznaczamy punkt math  dla prostej math (Rys. 3). Zauważmy, że wierzchołek math jest krytyczny dla boku math jeśli na okręgu punkt math  leży pomiędzy punktami math oraz math Wystarczy zatem wyznaczyć kolejność punktów na okręgu – to można zrobić w czasie math  gdyż należy scalić dwa posortowane ciągi punktów (zakładamy przy tym, że znamy kolejność wierzchołków na obwodach wielokątów).

Na ten problem można spojrzeć też inaczej. Wyobraźmy sobie dwie proste równoległe, które jednocześnie obracają się wokół wielokątów, będąc do nich stycznymi. Ilekroć prosta styczna do math  zawiera pewien jego bok, to prosta styczna do math przechodzi przez wierzchołek krytyczny dla tego boku.

Pozostawiamy Czytelnikowi zaimplementowanie tego pomysłu, tak by działał w czasie math  Metoda prostych równoległych pozwala rozwiązać wiele problemów dotyczących wielokątów wypukłych – zainteresowani Czytelnicy więcej szczegółów mogą znaleźć w Internecie pod hasłem rotating calipers.


Wyznaczanie przecięcia półpłaszczyzn

W ogólności problem ten dla math  półpłaszczyzn wymaga czasu math ale my znowu skorzystamy z tego, że znamy kolejność wierzchołków w wielokącie math  zatem nasze półpłaszczyzny math są posortowane według współczynników kierunkowych ich brzegów (prostych math), co pozwala nam rozwiązać ten problem w czasie math

obrazek

Rys. 4 Rozpatrujemy prostą math na stosie znajdują się proste math Punkt math znajduje się na prawo od punktu math zatem usuwamy ze stosu prostą math Punkt math jest na lewo od math zatem na stosie pozostaną proste math

Rys. 4 Rozpatrujemy prostą math na stosie znajdują się proste math Punkt math znajduje się na prawo od punktu math zatem usuwamy ze stosu prostą math Punkt math jest na lewo od math zatem na stosie pozostaną proste math

Najpierw pokażemy, jak wyznaczyć „dolne” przecięcie, tzn. dla półpłaszczyzn, które mogą stanowić dolny brzeg wielokąta będącego przecięciem. Przeglądamy półpłaszczyzny w kolejności rosnących współczynników kierunkowych prostych math Będziemy utrzymywać następujący niezmiennik: po rozpatrzeniu prostej math na stosie znajdują się te proste z ciągu math które mają nietrywialne przecięcie z brzegiem zbioru math

Rozpatrując math robimy co następuje: dopóki punkt przecięcia prostych math i  math (przedostatniej i ostatniej prostej na stosie) znajduje się na prawo od punktu przecięcia prostych math i  math usuwamy ostatnią prostą ze stosu. Na końcu dodajemy prostą math na stos (patrz Rys. 4).

Analogicznie wyznaczamy przecięcie „górnych” półpłaszczyzn. Obliczenie przecięcia powstałych zbiorów w czasie math  pozostawimy jako ćwiczenie dla Czytelnika.