Próbuję połączyć dwie rzeczy. Piszę grę i muszę określić kwadraty siatki leżące na linii z zmiennoprzecinkowymi punktami końcowymi.
Ponadto muszę uwzględnić wszystkie kwadraty siatki, których dotyka (tj. Nie tylko linię Bresenhama, ale niebieską):
Czy ktoś może zaoferować mi jakiś wgląd w to, jak to zrobić? Oczywistym rozwiązaniem jest użycie naiwnego algorytmu linii, ale czy istnieje coś bardziej zoptymalizowanego (szybszego)?
c#
algorithm
grid
interpolation
floating-point
SmartK8
źródło
źródło
Odpowiedzi:
Szukasz algorytmu przechodzenia przez siatkę. Ten dokument daje dobre wdrożenie;
Oto podstawowa implementacja w 2D znaleziona na papierze:
Na papierze dostępna jest również wersja do rzucania promieni 3D.
W przypadku zepsucia łącza można znaleźć wiele kopii lustrzanych o jego nazwie: Szybszy algorytm przechodzenia wokseli do raytracingu .
źródło
Pomysł Blue jest dobry, ale implementacja jest nieco niezdarna. W rzeczywistości możesz to łatwo zrobić bez sqrt. Załóżmy na chwilę, że wykluczysz przypadki zdegenerowane (
BeginX==EndX || BeginY==EndY
) i skupimy się tylko na kierunkach linii w pierwszej ćwiartce, więcBeginX < EndX && BeginY < EndY
. Będziesz musiał zaimplementować wersję dla co najmniej jeszcze jednej ćwiartki, ale jest to bardzo podobne do wersji dla pierwszej ćwiartki - sprawdzasz tylko inne krawędzie. W pseudokodzie C'ish:Teraz w przypadku innych ćwiartek wystarczy zmienić warunek pętli
++cx
lub++cy
. Jeśli użyjesz tego do kolizji, prawdopodobnie będziesz musiał zaimplementować wszystkie 4 wersje, w przeciwnym razie możesz uniknąć dwóch, odpowiednio zamieniając punkty początkowy i końcowy.źródło
Twoim założeniem niekoniecznie jest znalezienie komórek, ale linie, które przecinają na tej siatce.
Na przykład robiąc zdjęcie nie możemy wyróżnić komórek, ale linie przecinającej się siatki:
To pokazuje, że jeśli przecina linię siatki, komórki po obu stronach tej linii są wypełnione.
Możesz użyć algorytmu przecięcia, aby sprawdzić, czy linia zmiennoprzecinkowa przecina je, skalując punkty do pikseli. Jeśli masz współczynnik pływających współrzędnych: pikseli wynoszący 1,0: 1, to jesteś posortowany i możesz po prostu przetłumaczyć go bezpośrednio. Za pomocą algorytmu przecięcia segmentu linii możesz sprawdzić, czy twoja lewa dolna linia (1,7) (2,7) przecina się z twoją linią (1.3,6.2) (6.51,2.9). http://alienryderflex.com/intersect/
Konieczne będzie tłumaczenie z c na C #, ale pomysł można uzyskać z tego artykułu. Wstawię poniższy kod na wypadek, gdyby link się zepsuł.
Jeśli chcesz dowiedzieć się tylko, kiedy (i gdzie) przecinają się segmenty linii, możesz zmodyfikować funkcję w następujący sposób:
źródło
JS Demo:
Pokaż fragment kodu
źródło
Zetknąłem się dzisiaj z tym samym problemem i zrobiłem całkiem dużą górę spaghetti z kretowiska, ale skończyło się na czymś, co działa: https://github.com/SnpM/Pan-Line-Algorytm .
Z ReadMe:
ReadMe wyjaśnia rozwiązanie znacznie lepiej niż kod. Planuję wprowadzić zmiany, aby nie powodowały bólu głowy.
Wiem, że spóźniłem się o rok z tym pytaniem, ale mam nadzieję, że dotrze to do innych, którzy szukają rozwiązania tego problemu.
źródło