29/09/2012 - 23:20
Stworzyłem git Repo tutaj:
https://github.com/ArthurWulfWhite/Bezier-Distance/
Stąd możesz pobrać pliki źródłowe w formacie zip. Zawiera także demo, które można skompilować za pomocą FlashDevelop. Aby skorzystać z wersji demo, otwórz projekt we Flash Develop i kliknij „Testuj projekt”. Podczas uruchamiania wersji demo kliknij LMB, aby losowo wyznaczyć nową krzywą Beziera i nowy okrąg.
Powodzenia!
Link zip jest trudny do zobaczenia - wystarczy użyć Ctrl + F i wpisać zip. To źródło przedstawia kilka tygodni badań i programowania, mam nadzieję, że ci się spodoba.
Jeśli planujesz rekurencyjne dzielenie Beziera na segmenty i sprawdzanie kolizji z nimi, sugeruję utworzenie 100 100 tablic (siatki) i umieszczenie każdego segmentu w czterech najbliższych kwadratach, więc musisz tylko sprawdzić kolizje z 4/10 000 z segmentuje każdą ramkę.
Myślę, że skorzystasz z box2d zarówno jako programista, jak i twórca gier, ponieważ istnieje wiele ukrytych przeszkód w tworzeniu „prostego” silnika fizyki, który sprawia, że ruch wydaje się nieco wyboisty i mniej płynny, niż mógłby być.
Stara odpowiedź: czysty sposób.
Możesz faktycznie sprawdzić, czy koło koliduje z krzywą Beziera, sprawdzając odległość między odległością między środkiem okręgu a najbliższym punktem na krzywej.
Równanie odległości (ogólnie)
wyjaśnione:
Równanie Beziera:
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Można to podsumować do (z pewną algebrą) - pominę. (X, y) dla czytelności (wciąż są punktami, a nie jedną liczbą)
q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start
Odległość od punktu (x, y) wynosi:
sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)
Aby znaleźć najbliższy punkt beziera do piłki, musisz wyprowadzić i znaleźć wszystkie punkty, w których pochodna jest równa zero (pierwiastki). Jest to wielomian trzeciego stopnia, więc możesz użyć formuły zamkniętej, ale może to być niewiarygodne, ponieważ precyzja ułamków reprezentowanych przez zmiennoprzecinkowy komputer może być niewystarczająca. O wiele lepiej jest użyć Newtona lub czegoś takiego.
Pochodna, dla której musisz znaleźć korzenie, to:
Zakładając: a = początek b = kontrola c = koniec d = punkt środkowy koła
Trudną częścią jest pomnożenie tych punktów, musisz użyć iloczynu.
Jeśli chcesz, mam do tego kod i mogę go tutaj udostępnić w postaci funkcji, która po prostu zwraca wartość logiczną, jeśli występuje kolizja lub nie i kąt kolizji. Podczas naiwnego wdrażania takiego silnika zderzeniowego mogą pojawić się pewne problemy, na przykład szybko poruszająca się kula może zostać złapana między dwiema krzywymi.
Zalecam na razie tego unikać, po prostu zsumuj współczynniki dla osi x i dla osi y i dodaj je.
Użyj dowolnej niezawodnej metody, takiej jak Newton, aby znaleźć pierwiastki, sprawdź odległość od punktów początkowych na ramce, 0 <= t <= 1 do środka okręgu i sprawdź odległość dla dwóch końców bezier (początek i koniec) do środka okręgu, w zależności od tego, który z nich jest najbliższy, powie ci, czy doszło do kolizji.
Jeśli promień jest mniejszy niż minimalna odległość, dochodzi do kolizji.
Kąt jest w przybliżeniu tym, który znajduje się między środkiem okręgu a najbliższym punktem na ramce.
Biorąc to pod uwagę, jeśli naprawdę chcesz stworzyć grę z fizyką kolizyjną, proponuję po prostu iterować bez Beziera
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Podziel każdy kawałek na środku rekurencyjnie, aż będzie wystarczająco mały, powiedzmy 10 pikseli lub mniej, następnie z grubsza zbuduj bezier z pudełek i użyj Box2d do fizyki, ponieważ możliwe jest, że napisanie całego tego kodu wykrywania kolizji okaże się świetnym czas, który nie poprawia rozgrywki. Korzystanie z Box2d sprawdziło się w wielu projektach w przeszłości.