Jestem programistą gier flashowych, który jest trochę zacofany w matematyce, choć uważam, że fizyka jest zarówno interesująca, jak i fajna.
Dla porównania jest to gra podobna do tej, którą tworzę : gra flashowa Untangled
Sprawiłem, że ta nieplątana gra jest prawie pełna logiki. Ale kiedy przecinają się dwie linie, potrzebuję tych przeciętych lub „splątanych” linii, aby pokazać inny kolor; czerwony.
Byłoby naprawdę miło z twojej strony, gdybyś mógł zasugerować algorytm do wykrywania kolizji segmentów linii . Jestem w zasadzie osobą, która lubi myśleć „wizualnie” niż „arytmetycznie” :)
Edycja: Chciałbym dodać kilka diagramów, aby wyraźniej przekazać pomysł
PS Próbuję zrobić funkcję jako
private function isIntersecting(A:Point, B:Point, C:Point, D:Point):Boolean
Z góry dziękuję.
Odpowiedzi:
Korzystam z następującej metody, która jest właściwie tylko implementacją tego algorytmu . Jest w C #, ale przetłumaczenie go na ActionScript powinno być trywialne.
Jest jednak subtelny problem z algorytmem, w którym dwie linie są zbieżne, ale nie nakładają się. W takim przypadku algorytm nadal zwraca przecięcie. Jeśli zależy ci na tej sprawie, uważam, że ta odpowiedź na stackoverflow ma bardziej złożoną wersję, która rozwiązuje ten problem.
Edytować
To dziwne, przetestowałem to i działa dla mnie, z wyjątkiem tego jednego przypadku, który opisałem powyżej. Używając dokładnie tej samej wersji, którą zamieściłem powyżej, otrzymałem te wyniki, gdy wziąłem to na jazdę testową:
źródło
Bez podziałów! Więc nie ma problemu z precyzją ani dzieleniem przez zero.
Segment linii 1 to A do B Segment linii 2 to C do D
Linia jest niekończącą się linią, segment linii jest zdefiniowaną częścią tej linii.
Sprawdź, czy dwie ramki ograniczające się przecinają: jeśli nie ma przecięcia -> Bez krzyża! (obliczenia wykonane, zwróć false)
Sprawdź, czy linia seg 1 rozciąga się na linii seg 2 i czy linia seg 2 rozciąga się na linii seg 1 (tj. Linia Segment 1 znajduje się po obu stronach linii zdefiniowanej przez linię Segment 2).
Można tego dokonać, tłumacząc wszystkie punkty przez -A (tzn. Przesuwasz 2 linie, aby A było na początku (0,0))
Następnie sprawdzasz, czy punkty C i D znajdują się po różnych stronach linii określonej przez 0,0 do B
Jeśli nie masz jeszcze „No Cross”, kontynuuj używanie nie A, B w porównaniu z C, D, ale C, D w porównaniu z A, B (te same cielęta, po prostu zamień A i C, B i D), jeśli nie ma „Bez krzyża!” wtedy masz skrzyżowanie!
Szukałem dokładnych obliczeń dla produktu krzyżowego i znalazłem ten post na blogu, który wyjaśnia również tę metodę.
źródło
Chcę tylko powiedzieć, że potrzebowałem go do mojej gry Gamemaker Studio i działa dobrze:
źródło
Przyjęta odpowiedź dała złą odpowiedź w tym przypadku:
Te linie oczywiście się nie przecinają, ale zgodnie z funkcją w „poprawnej odpowiedzi” linie się przecinają.
Oto, czego używam:
zwraca 0 = linie nie przecinają się
zwraca> 0 = linie przecinają się
Zaktualizuj, aby odpowiedzieć na pytanie:
Sam nie stworzyłem tego kodu. Ma ponad 5 lat i nie wiem, jakie jest oryginalne źródło. Ale..
Myślę, że wartością zwracaną jest względna pozycja pierwszego wiersza, w którym przecinają się (aby źle to wytłumaczyć). Aby obliczyć punkt przecięcia, prawdopodobnie możesz użyć Lerp w następujący sposób:
(NIE TESTOWAŁEM TEGO)
źródło