Jak obliczyć kąt odbicia?

Bawiłem się nim przez jakiś czas, ale po prostu nie mogę tego rozgryźć.

Zrobiłem czołg, który wystrzeliwuje pociski, i kiedy pociski uderzą w ściany, chcę, żeby się odbiły, ale chcę, żeby odbiły się pod odpowiednim kątem.

W tej chwili nie mam żadnych przeszkód, pociski po prostu odbijają się, gdy wychodzą poza viewportRectangle zrobiłem.

Czy rozwiązanie, którego szukam, jest dość zaawansowane?

Czy jest na to relatywnie prosty sposób?

Author: Peter Mortensen, 2009-02-21

10 answers

Myślę, że łatwiejszym sposobem na to jest użycie prędkości pocisku zamiast obliczania kątów. Powiedzmy, że masz pocisk, który ma xVelocity i yVelocity, aby reprezentować jego ruch w poziomie i pionie. Te prędkości mogą być dodatnie lub ujemne, aby reprezentować lewo, prawo, górę lub dół.

  • jeśli pocisk uderzy w górną lub dolną granicę, Odwróć znak yVelocity.
  • jeśli pocisk uderzy w lewą lub prawą granicę, Odwróć znak xVelocity.

To zachowa ruch w przeciwnej osi tak samo.

Zapożyczając obraz z odpowiedzi ChrisF , powiedzmy, że pocisk startuje na pozycji I.

Kąt odbicia

Z xVelocity i yVelocity oba są dodatnie (w grafice 2D w prawo i w dół są zazwyczaj dodatnie) pocisk będzie poruszał się we wskazanym kierunku. Po prostu przypiszmy wartości

xVelocity = 3
yVelocity = 4

Kiedy pocisk uderzy w ścianę w pozycji C , jego xVelocity nie powinno się zmieniać, ale jego yVelocity powinien być odwrócony do -4 tak, aby podróżował z powrotem w górę, ale nadal idzie w prawo.

Zaletą tej metody jest to, że wystarczy tylko śledzić pocisk xPosition, yPosition, xVelocity, i yVelocity. Używając tylko tych czterech komponentów i szybkości aktualizacji gry, pocisk będzie zawsze przerysowany we właściwej pozycji. Gdy napotkasz bardziej skomplikowane przeszkody, które nie są pod kątem prostym lub poruszają się, o wiele łatwiej będzie pracować z X i Y prędkości niż przy kątach.

 68
Author: Bill the Lizard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:53

Możesz pomyśleć, że ponieważ twoje ściany są wyrównane do osi współrzędnych, sensowne jest pisanie specjalnego kodu przypadku(dla ściany pionowej neguj współrzędną x prędkości; dla ściany poziomej neguj współrzędną Y prędkości). Jednak, gdy już gra działa dobrze z pionowymi i poziomymi ścianami, prawdopodobnie następną rzeczą, którą pomyślisz, jest: "a co ze ścianami pod dowolnymi kątami?"Warto więc pomyśleć o ogólnej sprawie z początek.

W ogólnym przypadku, Załóżmy, że pocisk ma prędkość v i uderza w ścianę o powierzchni normalnej n .

Pocisk z wektorem v o ukośnie uderzył w ścianę o powierzchni normalnej N.

Podziel v na elementy U prostopadłe do ściany i w równoległe do niej.

Trójkąt prostokątny z przeciwprostokątną dla v, krótki bok u równoległy do ściany i długi bok w równoległy do ściany.

Gdzie:

U = (v · n / n · n) n
w = v - u

Tutaj, v · N jest iloczyn punktowy wektorów v i n . Zobacz link, aby uzyskać wyjaśnienie, jak to obliczyć. Produkt dot n · n oblicza się do kwadratu długości wektora normalnego; jeśli zawsze masz swoje normalne w postaci wektorów jednostkowych to n · n = 1 i można pominąć podział.

Po odbiciu Składnik ruchu równoległego do ściany ulega tarciu f, a składnik prostopadle do ściany ma wpływ sprężystość, którą można podać w postaci współczynnika restytucji r .

Więc prędkość po zderzeniu wynosi v' = f w - r u . W idealnie sprężystym, beztarciowym zderzeniu, v' = w - u ; czyli ruch jest odbity o normie w punkcie zderzenia, jak na diagramie podanym w odpowiedzi Billa.

This approach działa tak samo w trzech wymiarach.

(oczywiście jest to bardzo uproszczone pojęcie odbijania; nie bierze pod uwagę momentu pędu ani deformacji. Ale dla wielu rodzajów gier wideo tego rodzaju uproszczenie jest całkowicie odpowiednie.)

 192
Author: Gareth Rees,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-11 14:32:29

Dla cząstek doskonałych (i światła) kąt odbicia jest równy kątowi padania, jak pokazano na poniższym wykresie (z commons.wikimedia.org).

Kąt odbicia

Wykonaj wyszukiwanie "kąt odbicia" (bez cudzysłowów) w Google.

Jest to trochę bardziej skomplikowane, jeśli wziąć pod uwagę elastyczność i materiały obiektu i przeszkód;)

 9
Author: ChrisF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 14:10:27

Miałem taki problem, jedyny sposób jaki znalazłem to oddzielenie osi kolizji!

Spróbuj:

x += velocity * Math.cos(angle * Math.PI /180);
y += velocity * Math.sin(angle * Math.PI /180);

if (x < 0 || x > canvas.width) {
     angle = 180 - angle;   
}
else if (y < 0 ||y > canvas.height) {
     angle = 360 - angle; 
}
Mam nadzieję, że to wam pomoże!
 6
Author: Diogenes Silveira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-18 01:43:51

Na marginesie konkretnego pytania fizyki, które zadajesz, polecam książkę" początek matematyki i fizyki dla programistów gier " Wendy Stahler. Uważam, że jest to bardzo przydatne dla moich projektów programowania gier/fizyki.

Kod, który towarzyszy książce jest C++ , ale jeśli znasz C#, byłoby dość łatwo dokonać konwersji.

Miłego dnia!

 5
Author: itsmatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-21 15:51:55

180-a nie będzie działać we wszystkich przypadkach, chyba że pracujesz tylko odbicie na górnej powierzchni, gdy x rośnie.

Jednym z kierunków jest forum XNA lub pobranie przykładowego kodu XNA. Jest to C# i służy do budowania gier. Nie twierdzę, że chcesz budować swoje gry w XNA, ale jest to świetne narzędzie i jest bezpłatne.

 4
Author: Gregory A Beamer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-21 14:27:37

Wcale nie skomplikowane - pseudo-kod:

angleObjectHitWall = a;
bounceAngle = 180-a;

Oczywiście jest to bardzo proste obliczenie i jest całkowicie nieistotne, gdy zaczniesz brać pod uwagę czynniki takie jak materiał, grawitacja, ściany, które nie są proste, itp...

 2
Author: Yuval Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-21 14:23:23

To jest naprawdę pytanie fizyki, więc jeśli nie jesteś fizykiem (a ponieważ zadajesz to pytanie, wezmę to, że nie jesteś) będzie to wymagało dużo czytania i burzy mózgów, aby to zrobić dobrze.

Proponuję przeczytać ten wpis Wikipedii, aby uzyskać podstawowe pojęcie o głębi twojego pytania.

Jeśli tylko chcesz, aby to "wyglądało wiarygodnie", to nie martwiłbym się o to zbytnio i użyłbym Bill The Lizard ' s answer, jednak jeśli chcesz aby to naprawić, będziesz miał niezłą przygodę. Nie daj się przestraszyć! Powodzenia!

 0
Author: David Božjak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-21 14:45:10

a = 2w - b

gdzie:
a = > kąt wynikowy
w = > kąt ściany lub podłogi lub sufitu
b = > kąt kulowy

Oto, co wymyśliłem po próbie znalezienia najprostszego wzoru na obliczenie uzyskanego kąta odbijania się piłki od ścian, sufitu i podłogi. Wynik może wykraczać poza +360 lub -360 stopni, ale nadal są one równoważne kąt.

na przykład, jeśli kąt sufitu wynosi 270 stopni, a kąt kuli wynosi 30 stopni, uzyskany kąt wynosi 510 stopni, co jest odpowiednik +150 stopni lub -210 stopni. Jeśli użyjesz 90Deg dla sufitu zamiast 270deg, wynik będzie nadal 150deg.

 0
Author: d_air,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-19 04:37:00
if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}
To działa i jest proste, powodzenia.
 -4
Author: grant fisher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-08 22:47:43