Jak widać na rysunku, pytanie brzmi:
Jak znaleźć prostokąt o minimalnej powierzchni (MAR) dopasowany do danych punktów?
a pytanie pomocnicze brzmi:
Czy istnieje jakieś analityczne rozwiązanie problemu?
(Opracowanie pytania będzie polegało na dopasowaniu ramki (3D) do klastra punktów w chmurze punktów 3D).
Jako pierwszy etap proponuję znaleźć wypukły kadłub dla punktów, które reformują problem (poprzez usunięcie tych punktów nie są zaangażowane w rozwiązanie) w celu: dopasowania MAR do wielokąta. Wymagana metoda zapewni X ( środek prostokąta ), D ( dwa wymiary ) i A ( kąt ).
Moja propozycja rozwiązania:
- Znajdź środek ciężkości wielokąta (patrz Znajdowanie środka geometrii obiektu? )
- [S] Dopasuj prosty dopasowany prostokąt, tzn. Równolegle do osi X i Y
- możesz użyć
minmax
funkcji dla X i Y podanych punktów (np. wierzchołków wielokąta)
- możesz użyć
- Przechowuj obszar dopasowanego prostokąta
- Obróć wielokąt wokół środka ciężkości o np. 1 stopień
- Powtarzaj od [S] aż do pełnego obrotu
- Podaj jako wynik kąt minimalnej powierzchni
Wydaje mi się to obiecujące, jednak istnieją następujące problemy:
- wybór dobrej rozdzielczości dla zmiany kąta może być trudny,
- koszt obliczeń jest wysoki,
- rozwiązanie nie jest analityczne, ale eksperymentalne.
Aby uzupełnić świetne rozwiązanie @ julien, oto działająca implementacja w
R
, która może służyć jako pseudokod, który poprowadzi każdą implementację specyficzną dla GIS (lubR
oczywiście można ją zastosować bezpośrednio ). Dane wejściowe to tablica współrzędnych punktowych. Dane wyjściowe (wartośćmbr
) to tablica wierzchołków minimalnego prostokąta ograniczającego (z pierwszym powtórzeniem w celu zamknięcia). Zwróć uwagę na całkowity brak jakichkolwiek obliczeń trygonometrycznych.Oto przykład jego użycia:
Czas jest ograniczony przez szybkość algorytmu wypukłego kadłuba, ponieważ liczba wierzchołków kadłuba jest prawie zawsze znacznie mniejsza niż suma. Większość wypukłych algorytmów kadłuba ma asymptotycznie O (n * log (n)) dla n punktów: można obliczyć prawie tak szybko, jak można odczytać współrzędne.
źródło
Właśnie to zaimplementowałem i opublikowałem swoją odpowiedź na StackOverflow , ale pomyślałem, że upuszczę moją wersję tutaj, aby inni mogli ją zobaczyć:
Oto cztery różne przykłady tego działania. Dla każdego przykładu wygenerowałem 4 losowe punkty i znalazłem obwiednię.
Dla tych próbek jest też stosunkowo szybki w 4 punktach:
źródło
points = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
, a wynik jest tym,array([[1.00000000e+00, 6.12323400e-17], [0.00000000e+00, 0.00000000e+00], [6.12323400e-17, 1.00000000e+00], [1.00000000e+00, 1.00000000e+00]])
który jest kwadratem jednostkowym (włączając pewne błędy zaokrąglania zmiennoprzecinkowego). Uwaga: kwadrat jest tylko prostokątem o równych bokach, więc zakładam, że może obsłużyć kwadrat, który uogólnia na wszystkie prostokąty.W Whitebox GAT ( http://www.uoguelph.ca/~hydrogeo/Whitebox/ ) znajduje się narzędzie o nazwie Minimalna ramka ograniczająca do rozwiązania tego konkretnego problemu. Jest tam również narzędzie z minimalnym wypukłym kadłubem. Kilka narzędzi w przyborniku kształtu łatki, np. Orientacja i wydłużenie łatki, opiera się na znalezieniu minimalnego obwiedni.
źródło
Natknąłem się na ten wątek, szukając rozwiązania w języku Python dla prostokąta ograniczającego obszar minimalny.
Oto moja implementacja , dla której wyniki zostały zweryfikowane za pomocą Matlaba.
Dołączono kod testowy dla prostych wielokątów i używam go do znalezienia minimalnej ramki granicznej 2D i kierunków osi dla 3D PointCloud.
źródło
Dzięki @ odpowiedź Whubera. To świetne rozwiązanie, ale wolne dla dużych chmur punktów. Odkryłem, że
convhulln
funkcja w pakiecie Rgeometry
jest znacznie szybsza (138 s vs 0,03 s za 200000 punktów). Wkleiłem tutaj moje kody, aby każdy był ciekawy dla szybszego rozwiązania.Dwie metody uzyskują tę samą odpowiedź (przykład na 2000 punktów):
źródło
Po prostu polecam wbudowaną funkcję OpenCV
minAreaRect
, która znajduje obrócony prostokąt o minimalnym obszarze otaczającym wejściowy zestaw punktów 2D. Aby zobaczyć, jak korzystać z tej funkcji, zapoznaj się z tym samouczkiem .źródło