W wielokącie masz dość dużo linii. Odległość między wielokątami wynosi zero, jeśli punkt leży w obrębie wielokąta lub leży na krawędzi.
Więc rzeczywiście szukasz dwóch przypadkach:
- sprawdź, czy punkt leży wewnątrz dowolnego wielokąta (pamiętacie może to być więcej niż jednym wielokąta
- Uzyskaj zbiór wszystkich krawędzi i obliczyć każdy odległość punktu od krawędzi. Najbliższa odległość daje dystans wielokąta krawędź należy też.
jest to więc prosty algorytm, że jeśli weźmiemy pod uwagę 10 krawędzie za wielokąta zajmuje o (10 * 10) * 142 dla wszystkie twoje punkty. To sprawia, że 100 * 142 = 14200 operacji. => O (m * deltaE) * n (m to liczba wielokątów, deltaE to średnia liczba krawędzi na wielokąt, n to liczba punktów).
Teraz sprawdzamy, czy możemy to przyspieszyć. Pierwszą rzeczą, która przychodzi do głowy, jest to, że możemy użyć sprawdzania obwiedni lub okręgów ograniczających dla każdego wielokąta.
Innym pomysłem jest przygotowanie najbliższych krawędzi dla każdego wielokąta dla zestawu kątów.Na przykład, jeśli masz 8 kątów (co 45 °), możesz usunąć wszystkie krawędzie z listy, które są zastąpione przez inną krawędź (dlatego każdy punkt usuniętej krawędzi da zawsze większą odległość niż jakikolwiek punkt drugiej krawędzi tego samego wielokąt:
W ten sposób zwykle możesz zmniejszyć złożoność z dużym marginesem.Jeśli myślisz o prostokącie, masz tylko jedną lub dwie krawędzie zamiast 4. Jeśli myślisz o zwykłym wielokącie o krawędzi 8, możesz skończyć z zwykle jeden lub dwa i maksymalnie 3 krawędzie na wielokąt:
Jeśli dodasz normalny wektor do każdej krawędzi, możesz obliczyć, czy punkt może być w środku i musisz wykonać linię skanowania lub cokolwiek sprawdzić (lub znasz jego konvex), aby mieć pewność,
Dostępne są również indeksy odwzorowań, takie jak oddzielenie przestrzeni dwuwymiarowej przez xiy w równorzędnym mannor. W związku z tym wystarczy przetestować poligony leżące w 9 sektorach.
Następna wersja może wykorzystywać drzewo R, że każda ramka ograniczająca (okrąg) każdego węzła musi być sprawdzona pod kątem minimalnej oczekiwanej odległości i maksymalnej oczekiwanej odległości. Nie trzeba więc sprawdzać poligonów węzła, które powodują znacznie większe minimalne odległości niż maksymalne odległości innego węzła.
Inną rzeczą jest, jeśli posiadasz dane drzewo, takie jak w przypadku danych map. Na mapie ulic zawsze masz świat -> region -> kraj -> region -> miasto -> sektor miejski -> ...
Dzięki temu możesz wyszukać najbliższą lokalizację na mapie całego świata zawierającej miliony wielokątów w rozsądnym czasie, głównie < 10 ms.
Można powiedzieć, że masz tu wiele opcji. Przetwarzaj listę wieloboków i wyodrębniaj odpowiednie krawędzie, korzystając z binarnych drzewek z partycjami przestrzennymi wielokątów lub użyj podejścia kątowego, a nawet przejdź z czymś jeszcze bardziej wyszukanym. To zależy od Ciebie. Spodziewam się, że skończysz, robiąc coś w zakresie logarytmicznym, takim jak O (log (n) * log (deltaE)), który staje się O (log (n)) jako średnia złożoność.
Sądząc po twoim ostatnim akapicie, wydaje się, że masz problem matematyczny: znajdź lepszy algorytm niż zestaw porównawczy, prawda? To może być bardziej odpowiednie dla matematyki SE. – Frank
Pakiet 'spatstat' może być w stanie zrobić, co chcesz. Nie jestem ekspertem od tego zestawu narzędzi, więc nie mogę potwierdzić na pewno. –
Z liczbami tutaj zaangażowanymi, 10 wielokątów i 142 punktów (1420 odległości!) Brute Force nie powinno stanowić problemu. Pakiet 'plyr' powinien ci pomóc, jeśli nie lubisz pętli. – Gregor