Obliczanie minimalnej prędkości pocisku potrzebnej do trafienia celu w łuk paraboliczny

Odpowiedzi:

15

Paraboliczna funkcja trayectory jest zdefiniowana jako:

   Fx = Vox*t + Ox;
   Fy = -0.5 * g * t * t + Voy*t + Oy;      
  • Znane wartości:

    P: the target point.
    O: the origin point.
    g: gravity.
    t: time needed to impact.
    
  • Nieznane wartości:

    Vo: Initial Velocity
  • Aby obliczyć „Vo”, możemy nadać wartości funkcji F:

    't' = flight time  'duration' 
    'F' = target point 'P'        
    
          (Px-Ox)
    Vox = --------
          duration
    
          Py + 0.5* g * duration * duration - Oy 
    Voy = ---------------------------------------
                     duration
  • Możesz teraz uzyskać wszystkie wartości, aby osiągnąć cel od początku, podając wartości t do równania F:

     When t = 0         => F == O (Origin)
     When t = duration  => F == P (Target)      
Blau
źródło
świetna odpowiedź. po prostu zdaj sobie sprawę, że g nie jest podpisany. wraz ze wzrostem g Voy powinien również wzrosnąć.
milkplus,
Jak wiadomo t (czas potrzebny na uderzenie)?
Dewald Swanepoel,
13

Niedawno musiałem rozwiązać podobny problem, wymyśliłem dwa rozwiązania oparte na formule, którą znalazłem na stronie wikipedii „Dan the Man”, o której już wspominałem: trajektoria pocisku

W tym rozwiązaniu faktycznie potrzebujesz stałego kąta startu lub prędkości x. Prędkość Y nie jest potrzebna, ponieważ wystrzeliwujemy pocisk pod określonym kątem.

Rozwiązanie 1, kąt startu jest stały, obliczyć prędkość:

g = 9.81; // gravity
x = 49; // target x
y = 0; // target y
o = 45; // launch angle
v = (sqrt(g) * sqrt(x) * sqrt((tan(o)*tan(o))+1)) / sqrt(2 * tan(o) - (2 * g * y) / x); // velocity

Rozwiązanie 2, prędkość jest stała, oblicz kąt startu:

g = 9.81; // gravity
v = 40; // velocity
x = 42; // target x
y = 0; // target y
s = (v * v * v * v) - g * (g * (x * x) + 2 * y * (v * v)); //substitution
o = atan(((v * v) + sqrt(s)) / (g * x)); // launch angle

W moim przypadku te rozwiązania działały całkiem dobrze.

jonas
źródło
2

Jeśli nie obchodzi cię, czy jest to poprawne matematycznie, wystarczy, że wygląda wystarczająco poprawnie, oblicz prostą ścieżkę i spraw, aby pocisk podążał tą ścieżką, ale „popchnij ją w górę” wzdłuż normalnej linii w zależności od jej odległości w dół segment linii, więc unosi się, gdy zbliża się do środka segmentu i spada, gdy odchodzi od środka segmentu linii.

Możesz użyć do tego fali sinusoidalnej, używając zakresu stopni od -90 do +90 (gdzie -90 to lewy punkt na segmencie linii, 90 to prawy punkt, a ty lerp na środku) i pomnóż wynik przez stałą, aby zwiększyć skalę.

Jeśli potrzebujesz czysto poprawnej odpowiedzi matematycznej / fizycznej, to nie pomoże. Jeśli tego nie zrobisz, prawdopodobnie będzie to dla ciebie całkiem dobre!

Nie zapominaj, że w programowaniu gier chodzi o stosowanie złudzeń, które wyglądają poprawnie (i są tańsze w obliczeniach), zamiast realizmu.

Atrix256
źródło
7
Re: „używając złudzeń, które wyglądają poprawnie (i są tańsze w obliczeniach)”, zgadzam się ogólnie, ale w tym przypadku wydaje się to trochę głupie, biorąc pod uwagę, jak łatwe i tanie jest użycie matematycznie poprawnego łuku parabolicznego.
Nathan Reed,
1
To prawda, że ​​wydaje się to niepotrzebnym uproszczeniem, ale nie sądzę, aby ta odpowiedź była zła w złym sensie i nie zasługuje na głosowanie negatywne (nawet jeśli nie zasługuje na wiele pozytywnych opinii).
Czy
Właściwie, jeśli zamierzasz użyć fali sinusoidalnej, powinna ona wynosić od 0 do 180 (lub 0 do pi w radianach)
Daniel Kaplan
2

Jeśli potrzebujesz czegoś, co jest w porządku i masz stałą prędkość, możesz użyć tej bardzo uproszczonej metody.

distance = to.x - from.x;
angleToPoint = atan2(to.y - from.y, to.x - from.x);
distanceFactor = 1/1000;
angleCorrection = (PI*0.18) * (distance * distanceFactor);
velocity.X = cos(angleToPoint+angleCorrection) * power;
velocity.Y = sin(angleToPoint+angleCorrection) * power;

Odległość może być ujemna, ale nadal będzie działać, ponieważ kąt zależy również od odległości. Jeśli odległość jest ujemna, kąt, który należy dodać, jest również ujemny.

Będziesz musiał bawić się z DistanceFactor, aby znaleźć właściwą wartość. Zależy to od grawitacji i mocy pocisku. Powinien być blisko 1 podzielony przez maksymalną odległość, jaką pocisk może pokonać.

API-Beast
źródło
1
Heads-up. Kiedy wypróbowałem twój kod, miałeś cos i grzech do tyłu. Zmodyfikowałem Twój kod, więc powinien być poprawny.
MrValdez