Wykrywanie kolizji 2D

11

Załóżmy, że używam tej postaci.

ptak
(źródło: iconbug.com )

Jak zaimplementowałbyś w tym celu wykrywanie kolizji? Korzystanie z obwiedni nie wydaje się dobrym przybliżeniem, ponieważ kształt ptaka nie jest zbliżony do kwadratu.

Zastanawiałem się nad tym, czy wewnątrz obiektu reprezentuje rodzaj struktury drzewa quad reprezentującego fragmenty obrazu. Każdy liść może być albo false(jeśli pokrywa białą / przezroczystą przestrzeń na zewnątrz ptaka) albo true(jeśli reprezentuje obszar ptaka, tj. Dziób, oko itp.). Następnie w jakiś sposób przetestuj jedyną przeszkodę na scenie pod kątem kolizji z ptakiem.

Ale moje problemy w moim podejściu to:

  1. Nie wiem, jak zainicjować drzewo quadów.
  2. Po zainicjowaniu drzewa quadów nie jestem pewien, jak przejść i użyć go, gdy przeszkoda znajdzie się we współrzędnych obrazu.

Jak zrobiłbyś wykrywanie kolizji z nie kwadratowymi postaciami?

LE: Innym podejściem, które widziałem, było użycie wielu obwiedni. Na przykład miałbym jedno lub kilka pudełek ograniczających na dziób, a następnie kilka na włosy lub ogon. Ale może być nudne. Jeśli w moim przypadku jest to prawidłowe podejście, jak wygenerowałbym te ramki graniczne? Wątpię, czy musiałbym mieć je na stałe zakodowane w moim programie.

LE2: Dbam o dość precyzyjne zderzenia. Nie mogę sobie wyobrazić, jak pojedynczy obwiednia lub okrąg może przynajmniej przyzwoicie przybliżać ten kształt, więc to podejście nie zadziała.

asynchronizacja
źródło
2
Uwaga ogólna: użyłbym zarówno ramki granicznej, jak i bardziej szczegółowego czeku: Granularny czek będzie miał wyższą karę wydajności, więc chcesz, aby uruchamiał się tak rzadko, jak to możliwe. Dlatego najpierw zaznacz pole ograniczające i tylko jeśli zostanie trafione, wejdź na poziom głębiej i przetestuj bardziej szczegółowe podejście (cokolwiek to będzie).
Philip Allgaier
Dzięki, i tak zamierzałem to zrobić, ale nie jestem do końca pewien, jaki powinien być „test granularny”. :)
async
1
Brakuje tylko ważnego szczegółu: co chcesz z tym zrobić? Czy zależy Ci na dokładnych kolizjach? Czy z przyjemnością przybliżasz postać kółkiem? Czy chcesz, aby cząsteczki pyłu zderzały się z oczami postaci niezależnie od reszty?
Anko
@Anko Jak możesz przybliżyć ten kształt za pomocą koła? Dbam o dość precyzyjne kolizje - nie bardzo precyzyjne w pikselach, ale coś, co będzie wyglądać dobrze / naturalnie -.
asynchronizuje
1
Jak ten . Co w ogóle oznaczają „dobre” i „naturalne”? Czy to pytanie filozoficzne?
Anko

Odpowiedzi:

12

Zderzacz kół. Wystarczająco dobrze, powiedziałbym, chyba że robisz coś fantazyjnego z niektórymi częściami pod wpływem fizyki lub kolidującym wyglądem nienaturalnym, a nawet jeśli musisz podzielić to na kilka części, mam ci jedno do powiedzenia:

Nie komplikuj tego zbytnio.

Nie potrzebujesz do tego pełnej struktury drzewa quad. Wystarczy mieć kilka pól lub okręgów w prostej tablicy, a następnie przecinać je wszystkie. Nie może to być wystarczająco krytyczne pod względem wydajności i nie zyskasz tak wiele na korzystaniu z drzewa quadów.

Jonkel
źródło
3
Tak, po prostu stwórz mały zestaw kilku kształtów, jeśli jeden kształt go nie pokryje. Na przykład: i.imgur.com/Dd4yyGN.png
MichaelHouse
Dzięki Jonkel i @ Byte56. Używanie kilku kształtów wydaje się właściwym rozwiązaniem w mojej sytuacji. Łatwe do wdrożenia, dokładne i szybkie. Nie mogę uwierzyć, że skoczyłem prosto na quady, nie biorąc tego pod uwagę! Uh
asynchronuje
Zderzak kół dla ciała i prostokąt dla dzioba, dla dodatkowej dokładności.
Kroltan
14

Dwuetapowy proces sprawdzania

W pierwszym kroku zaznaczasz obwiednię , a jeśli nie ma tam kolizji, test się kończy. W przypadku kolizji przechodzisz do drugiego przejścia

W drugim przejściu , jeśli chcesz uzyskać większą precyzję i chcesz rozwiązanie z prawdziwym pikselem, możesz to zrobić, sprawdzanie z pikselem

Ponieważ obraz jest w formacie PNG (lub innym formacie zawierającym kanał alfa), byłoby to raczej łatwe

  1. Oblicz obszar przecięcia między tym jednym obiektem w scenie a ptakiem, generując prosty prostokąt przecięcia na obu obrazach
  2. W obrębie tego skrzyżowania sprawdź, czy każdy piksel ma wartość alfa> 0 OBIE OBRAZY
  3. Jeśli istnieją takie piksele, masz kolizję. W przeciwnym razie nie

Jeśli spojrzysz na kanał alfa zdjęć, zobaczysz, że zawiera on już wszystkie informacje, których możesz potrzebować do idealnej kolizji pikseli

kanał alfa z obrazka

Idealne kolizje w pikselach są zwykle drogie, więc wstępne oszacowanie za pomocą ramki granicznej lub bardziej szczegółowej liczby kolizji (jak ta sugerowana przez Anko) może zaoszczędzić trochę cennego czasu

„Dokładniejsza” szczegółowa ramka ograniczająca kolizję Anko zasugerowała:

bardziej szczegółowe obwiednia

PS: Jeśli twój obraz ma aureolę, efekt lub inny kanał alfa inny niż 0, z którym nie chcesz się zderzyć, próg algorytmu można łatwo dostosować, aby to uwzględnić

klucz kodowy
źródło
1
Dziękuję Ci! Ale w końcu nie będę potrzebować doskonałej precyzji pikseli. Doskonała odpowiedź przyda się jednak później.
asynchronuje
oczywiście kolego, tak, idealna kolizja pikseli jest prawie zawsze przesadą, z wyjątkiem gier, które naprawdę tego potrzebują (np. myśliwce 2D)
codemonkey
3

Użyłbym koła dla ciała i jednego prostokąta dla dzioba, ale to tylko moja opinia. Nadmierna komplikacja geometrii kolizji może spowolnić działanie aplikacji, praktycznie podwajasz (lub więcej) liczbę znaków na ekranie.

igrad
źródło
0

Może przydałby Ci się jakiś zwariowany zderzak wielokątów / krawędzi.

Nie jestem pewien, jak to dokładnie będzie działać, ale:

dwa obiekty: obiekt 1: ptak (o1), obiekt 2: rzecz, która może trafić ptaka (o2)

1) Zdefiniuj obwiednię, która jest wielokątem, który ściśle przylega do pierwszego obiektu (o1).

2) Zdobądź krawędzie o1, o2, które mogą zderzyć się bez, i mogą zderzyć się bez przejścia przez o2 lub odwrotnie.

Z położeniem i rozmiarem kształtu (o2) można prawdopodobnie izolować krawędzie (o1), których nie można uderzyć, niezależnie od tego, czy są one „za” inną krawędzią (o1), która jest bliższa o2. Jeśli masz prostokątny trójkąt, którego przeciwprostokątna skierowana jest w górę i w prawo, i prostokąt zbliżający się do niego prosto (długim bokiem wzdłuż osi x), możesz powiedzieć, które krawędzie należy pominąć, ponieważ obie wartości początkowe i końcowe są albo powyżej lub poniżej prostokąta.

3) Sprawdź, czy jeden z punktów na krawędzi o2 jest taki sam jak punkt na którejkolwiek z krawędzi o1, który wybrałeś w kroku 2.

ta koncepcja prawdopodobnie działa najlepiej w przypadku zderzania się wielokątów (tj. rzeczy z wyraźnymi krawędziami), ale może można traktować okrąg jako jedną długą krawędź (np. jeśli o2 był okręgiem).

Jeremy Harton
źródło