W grze 2D po prostu chcę narysować trajektorię strzały w locie. Przy poniższym kodzie trajektoria (parabola) wygląda dobrze, ale kąt (lub obrót) lub strzałka nie.
float g = -9.8f;
float x = (launchVelocity * time);
float y = (launchVelocity * time) + (0.5f * g * (float)Math.Pow(time, 2));
float angle = (float)Math.Tanh(y / x);
czego mi brakuje? Dzięki.
projectile-physics
Jaskółka oknówka
źródło
źródło
Odpowiedzi:
Arctanh
daje tangens dla krzywej hiperbolicznej! O ile wiem, twoja parabola nie jest hiperbolą.Ale mamy dobre wieści: łatwiej jest znaleźć styczną do swojej paraboli. Równanie to
Gdzie jest twoje
launchVelocity
. Teraz nachylenie twojej strzałki to:Możesz
Arctan
teraz bezpiecznie korzystać, jeśli chcesz.Kilka dodatkowych informacji o fizyce:
Przybliżona trajektoria, którą symulujesz, odnosi się do środka masy twojej strzałki. Kiedy mówisz „pozycja” (x, y), mówisz o pozycji środka masy. Środek masy strzały jest lekko do przodu od punktu środkowego i należy wziąć to pod uwagę, jeśli zamierzasz narysować strzałkę.
Pamiętaj, że nie bierzesz pod uwagę bezwładności pędu strzały (która może się znacznie różnić, jeśli strzelasz olbrzymią balistą) i nie bierzesz pod uwagę płynności strzały: lot strzały łuku nie podąży paraboliczną ścieżką!
źródło
Chcesz kąt strzałki w dowolnym momencie. Pamiętasz, że aby obliczyć kąt, istnieje styczna. Ale tutaj twoje myślenie zaczęło się mylić:
Ok, więc jeśli zaniedbacie tarcie powietrzne, wówczas prędkość x strzałki jest stała.
Najpierw rozłóż prędkość na składowe xiy. Możesz strzelać pod kątem 45 stopni lub 60 stopni. Potrzebujesz więc launchVelocity i kąta, to nie jest skalar.
Po drugie, oblicz wszystko jako podwójne, a nie zmiennoprzecinkowe. Nie jesteś wystarczająco zaawansowany numerycznie, aby wiedzieć, kiedy błąd zaokrągleń cię nie zabije, więc nie próbuj. W każdym razie nie jest to świetna oszczędność czasu.
Po trzecie, nie używaj Math.pow, jest powolny i nie tak dokładny, jak mnożenie potęg liczb całkowitych. Możesz także zaoszczędzić dużo czasu, korzystając z formularza Hornera (patrz poniżej)
Jeśli zależy ci na wydajności, możesz nawet wstępnie obliczyć 0,5 * g, ale powyższy kod zabierze Cię tam w 90%, nie robiąc nic zbyt szalonego. Benchmark, robiąc to 10 milionów razy, jeśli chcesz, to wprawdzie nie jest to dużo czasu, ale pod względem procentowym jest dość duży - biblioteki są bardzo wolne w Javie
Tak więc, jeśli chcesz kąt, pod którym powinna iść strzała, to czego chcesz
W tym przypadku zadziałałoby, ponieważ dx jest stałą. Ale ogólnie dx może wynosić zero, więc zwykle chcesz użyć:
która jest funkcją zaprojektowaną specjalnie do tego zadania.
Ale, jak powiedziałem, funkcje biblioteczne w Javie są strasznie powolne, i w tym przypadku jest lepszy sposób na zrobienie tego bez aluzji @FxIII powyżej.
Jeśli prędkość pozioma wynosi zawsze v0x, a prędkość pionowa wynosi:
wtedy twoja delta to: vx, vy
Nie potrzebujesz kąta. Jeśli chcesz narysować strzałkę, użyj czegoś nominalnie takiego jak:
wykres (x, y, x + vx, y + vy);
Nie wiem, co rysujesz, więc jeśli potrzebujesz kąta, aby go obrócić (tak jak używasz JOGL), to na pewno użyj tego kąta.
Nie zapomnij, jeśli używasz opengl do zmiany kąta z powrotem na stopnie, ponieważ ATAN2 zwraca radiany:
źródło
Tanh () ( tangens hiperboliczny ) przyjmuje jako parametr kąt, ale podałeś mu stosunek boków.
To, czego naprawdę chcesz, to użyć arcus tangensa hiperbolicznego , który przyjmuje parametr boków jako parametr i zwraca kąt. (Nazewnictwo może nazywać się „atanh”, „atanh2”, „arctanh” lub coś podobnego; wydaje się, że różni się w zależności od różnych bibliotek matematycznych)
źródło