W jednym z moich projektów mam obszar gry w kształcie koła. Wewnątrz tego koła porusza się kolejny mały okrąg. Chcę, aby małe kółko nie poruszało się poza większym. Poniżej widać, że w ramce 2 małe kółko jest częściowo na zewnątrz, potrzebuję sposobu, aby przenieść je z powrotem tuż przed tym, jak ma zamiar wyjść na zewnątrz. Jak można to zrobić?
Potrzebuję też punktu kolizji wzdłuż łuku dużego koła, aby móc zaktualizować prędkość małego koła. Jak przejść do obliczenia tego punktu?
Przed przesunięciem małego koła przewiduję jego następną pozycję, a jeśli jest na zewnątrz, znajduję czas kolizji między t = 0 it = 1 (t = 1 pełny krok czasu). Jeśli mam czas kolizji t, to po prostu poruszam małym kółkiem podczas t zamiast kroku pełnego czasu. Ale znowu problem polega na tym, że nie wiem, jak wykryć, że w tym momencie dochodzi do kolizji dwóch kół i jednego z nich.
EDYTOWAĆ:
Przykład punktu kolizji (zielony), który chcę znaleźć. Być może zdjęcie jest trochę nie w porządku, ale masz pomysł.
źródło
B
, ik=0
. Teraz, jeśli chcesz rozwiązania kolizji , nie udzieliłem tego w mojej odpowiedzi, ponieważ wymagałoby to wiedzy o fizycznych właściwościach obiektów. Co się stanie? Czy wewnętrzny okrąg powinien odbijać się w środku? A może rzucić? Zamiatać?V
, spraw, aby wewnętrzny okrąg przesunął sięV*t
wzdłuż obwoduR-r
koła. Oznacza to obrótV*t/(R-r)
radianów kątowych wokół punktuA
. Wektor prędkości można obracać w ten sam sposób. Nie trzeba znać normalnej (która i tak zawsze jest zorientowana w stronę środka koła), ani aktualizować prędkości w jakikolwiek inny sposób.Powiedz, że duży okrąg to okrąg A, a mały okrąg to okrąg B.
Sprawdź, czy B znajduje się w środku A:
Jeśli w ramce
n-1
B znajdował się wewnątrz A, a w ramcen
B znajduje się na zewnątrz A, a czas między ramkami nie był zbyt duży (inaczej B nie poruszał się zbyt szybko), możemy przybliżyć punkt zderzenia, po prostu znajdując współrzędne kartezjańskie względnego B do A:Następnie możemy przekonwertować te punkty na kąt:
Jeśli chcesz dowiedzieć się dokładniej, co
t
B znajduje się poza A, po raz pierwszy możesz wykonać skrzyżowanie promień-okrąg w każdej klatce, a następnie porównać, czy odległość od B do punktu zderzenia jest większa niż odległość B, którą może przebyć, biorąc pod uwagę, że obecna prędkość. Jeśli tak, możesz obliczyć dokładny czas kolizji.źródło
Niech (Xa, Ya) pozycję dużego koła i jego promień R, a (Xb, Yb) pozycję mniejszego koła i jego promień r.
Możesz sprawdzić, czy te dwa kręgi kolidują, jeśli
Aby znaleźć pozycję kolizji, znajdź dokładny moment, w którym zderzają się koła, używając wyszukiwania binarnego, ale ze stałą liczbą kroków. W zależności od tego, jak tworzona jest gra, możesz zoptymalizować tę część kodu (podałem to rozwiązanie, aby być niezależnym od zachowania małej kulki. Jeśli ma stałe przyspieszenie lub stałą prędkość, tę część kodu można zoptymalizować i zastąpiony prostą formułą).
Kiedy znasz czas kolizji, oblicz pozycje dwóch kół w ostatnim czasie, a końcowym punktem kolizji jest
źródło
Zaimplementowałem demo piłki odbijającej się w kręgu na jsfiddle za pomocą algorytmu opisanego przez Sama Hocevara :
http://jsfiddle.net/klenwell/3ZdXf/
Oto javascript, który identyfikuje punkt kontaktowy:
źródło