Oto post, który zawiera linki do artykułów na temat podobnych rodzajów symulacji (w kontekście inżynieryjnym / akademickim, a nie do gier): https://gamedev.stackexchange.com/a/10350/6398
Próbowałem przynajmniej dwóch różnych podejść do wykrywania kolizji + reakcji dla tego rodzaju symulacji „drutowej” (jak widać w grze Umihara Kawase); przynajmniej myślę, że o to ci chodzi - wydaje się, że nie ma określonego terminu dla tego rodzaju symulacji, po prostu nazywam to raczej „drutem” niż „liną”, ponieważ wydaje się, że większość ludzi uważaj „linę” za synonim „łańcucha cząstek”. A jeśli chcesz zachować przyczepność liny ninja (tzn. Może pchać ORAZ ciągnąć), jest to bardziej sztywny drut niż lina. Tak czy inaczej..
Odpowiedź Pekuji jest dobra, możesz zaimplementować ciągłe wykrywanie kolizji, rozwiązując czas, gdy podpisany obszar trzech punktów ma wartość 0.
(Nie mogę w pełni przypomnieć OTOH, ale możesz do niego podejść w następujący sposób: znajdź czas t, kiedy punkt a jest zawarty w linii przechodzącej przez b, c, (Myślę, że zrobiłem to, rozwiązując przypadek, gdy kropka (ab, cb) = 0, aby znaleźć wartości t), a następnie biorąc pod uwagę prawidłowy czas 0 <= t <1, znajdź pozycję parametryczną s na odcinku bc, tj. A = (1-s) b + s c, a jeśli a jest pomiędzy b i c (tzn. jeśli 0 <= s <= 1) jest to prawidłowa kolizja.
AFAICR możesz podejść do tego również na odwrót (tzn. Rozwiązać s, a następnie podłączyć to, aby znaleźć t), ale jest to o wiele mniej intuicyjne. (Przepraszam, jeśli to nie ma sensu, nie mam czasu na kopanie notatek i minęło kilka lat!)
Możesz więc teraz obliczyć wszystkie czasy, w których zdarzają się zdarzenia (tzn. Należy włożyć lub usunąć węzły liny); przetworz najwcześniejsze zdarzenie (wstaw lub usuń węzeł), a następnie powtarzaj / powtarzaj, aż nie będzie już żadnych zdarzeń między t = 0 it = 1.
Jedno ostrzeżenie o tym podejściu: jeśli obiekty, które lina może owijać, są dynamiczne (zwłaszcza jeśli je symulujesz ORAZ ich wpływ na linę i odwrotnie), mogą wystąpić problemy, jeśli obiekty te przeciągną się / przejdą przez siebie inne - drut może się zaplątać. I zdecydowanie wyzwaniem będzie zapobieganie tego rodzaju interakcjom / ruchom (rogi obiektów prześlizgujących się między sobą) w symulacji fizyki w stylu box2d. Niewielkie przenikanie między obiektami jest normalnym zachowaniem w tym kontekście.
(Przynajmniej .. to był problem z jedną z moich implementacji „drutu”.)
Innym rozwiązaniem, które jest znacznie bardziej stabilne, ale w niektórych warunkach brakuje niektórych kolizji, jest po prostu użycie testów statycznych (tj. Nie martw się o zamówienie według czasu, po prostu rekurencyjnie podziel każdy segment w kolizji, gdy go znajdziesz), który może być o wiele bardziej wytrzymały - drut nie zaplątuje się w rogach, a niewielka penetracja będzie w porządku.
Myślę, że podejście Pekuja też do tego służy, jednak istnieją alternatywne podejścia. Jednym z zastosowanych przeze mnie podejść jest dodanie pomocniczych danych kolizji: na każdym wypukłym wierzchołku v na świecie (tj. Na rogach kształtów, które może owinąć lina), dodaj punkt u tworzący skierowany odcinek linii uv, gdzie u jest trochę punkt „w rogu” (tj. w świecie, „za” v; aby obliczyć u, możesz rzucić promień do wewnątrz od v wzdłuż jego interpolowanej normalnej i zatrzymać pewną odległość po v lub zanim promień przecina się z krawędzią świata i wychodzi z obszaru bryłowego lub możesz po prostu ręcznie pomalować segmenty na świecie za pomocą wizualnego edytora narzędzi / poziomów).
W każdym razie masz teraz zestaw „narożnych linii” uv; dla każdego ultrafioletu i każdego odcinka ab w przewodzie sprawdź, czy przecinają ab i ultrafiolet (tj. zapytanie statyczne, boolean lineseg-lineseg przecięcia); jeśli tak, powtórz (podziel linię ab na av i vb, tj. wstaw v), rejestrując, w którym kierunku wygięta jest lina w v. Następnie dla każdej pary sąsiednich linii, ab, bc w drucie, sprawdź, czy bieżący kierunek zgięcia w b jest taki sam, jak w przypadku wygenerowania b (wszystkie te testy „kierunku zgięcia” są tylko testami obszaru ze znakiem); jeśli nie, połącz dwa segmenty w ac (tj. usuń b).
A może połączyłem, a potem podzieliłem, zapominam - ale na pewno działa w co najmniej jednym z dwóch możliwych zamówień! :)
Biorąc pod uwagę wszystkie segmenty drutu obliczone dla bieżącej ramki, możesz następnie symulować ograniczenie odległości między dwoma punktami końcowymi drutu (i możesz nawet zaangażować punkty wewnętrzne, tj. Punkty kontaktu między drutem a światem, ale jest to nieco bardziej zaangażowane ).
W każdym razie, mam nadzieję, że to się przyda ... papiery w poście, które również zamieściłem, powinny również dać ci kilka pomysłów.