Movimento de Projétil - Seta

13

Em um jogo 2D, eu simplesmente quero desenhar a trajetória de uma flecha em voo. Com o código abaixo, a trajetória (a parábola) parece correta, mas o ângulo (ou rotação) ou a seta não.

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);

o que estou perdendo? Obrigado.

Martin
fonte
3
Uma captura de tela pode ajudar
doppelgreener

Respostas:

10

Arctanhdá-lhe a tangente para a curva hiperbólica! Tanto quanto sei, sua parábola não é uma hipérbole.

Mas temos boas notícias: encontrar a tangente para a sua parábola é mais fácil. A equação é

x = s · t => t = x / s; y = s · t + g / 2 · t² => y = x + g / 2 · x² / s²

Onde está o seu launchVelocity. Agora, a inclinação da sua flecha é:

∂y / ∂y = g / (2s²) · x + 1

Você pode usar com segurança Arctanagora, se quiser.

Algumas informações adicionais sobre física:

A trajetória aproximada que você está simulando se aplica ao centro de massa da sua flecha. Quando você diz "posição" (x, y), está falando sobre a posição do centro de massa. O centro de massa de uma flecha está levemente à frente a partir do ponto médio, e você deve levar isso em consideração se quiser desenhar a flecha.

Lembre-se de que você não está considerando o momento inercial da flecha (que pode variar muito se estiver atirando em uma balista gigante) e não está considerando a dinâmica de fluidos da flecha: o vôo da flecha não seguirá um caminho parabólico!

FxIII
fonte
Obrigado Fxlll. Alguma idéia de onde eu poderia obter as fórmulas que se aplicam ao físico de uma flecha?
Martin
Eu acho que você quer dizer:! [& Part; y / & part; x = g / (2s & sup2;) & middot; x + 1] [2] mas, em qualquer caso, acho que recomendei uma abordagem melhor abaixo. Por um lado, você não explicou sobre a separação dos componentes x e y, portanto, isso é codificado em um ângulo arbitrário de 45 graus, com o launchVelocity não sendo verdadeiramente launchVelocity, mas o componente em x e y
Dov
Pode-se calcular com facilidade os momentos de inércia. São dois para as hastes, uma para a rotação sobre o centro de massa e a outra para a rotação sobre o eixo da haste. O princípio de superposição se aplica a momentos de inércia para que a flecha possa ser dividida em três partes: penas, corpo e ponta.
FXIII
1
O problema é que o único momento fácil de calcular é aquele devido à variação do ângulo (você pode ver que, derivando duas vezes uma parábola, resta apenas um termo constante). O outro é causado pela rotação devido à pena traseira. Aqui, o desgaste de penas e o atrito envolvem a conversão de energia cinética em rotação, diminuindo a velocidade da seta, mas adicionando efeito giroscópico. Isso influencia a trajetória e é bastante difícil de modelo
FXIII
De qualquer forma, se você pode relacionar o momento com a velocidade, dada uma configuração simples, tudo pode ser computado com integração completa, mas não tenho certeza de que você possa ter um formulário fechado para as equações de movimento (ou seja, você pode obter um algoritmo de integração, mas não um parâmetro) equação).
FXIII
4

Você deseja o ângulo da seta a qualquer momento. Você lembrou que, para calcular um ângulo, há uma tangente. Mas aqui é onde seu pensamento começou a dar errado:

  1. O que você deseja é delta y / delta x, porque a inclinação é a taxa de mudança (mencionada em uma das outras respostas). Observe que x é apenas a posição em que você está a qualquer momento, e não dx.

Ok, então se você negligenciar a fricção do ar, a velocidade x da seta é uma constante.

Primeiro, decomponha a velocidade nos componentes x e y. Você pode fotografar em um ângulo de 45 graus ou 60 graus. Então você precisa do launchVelocity e de um ângulo, não é um escalar.

Segundo, calcule tudo como duplo, e não flutuante. Você não é numericamente sofisticado o suficiente para saber quando o erro de arredondamento não o mata, portanto, não tente. De qualquer forma, não economiza muito tempo.

Terceiro, não use Math.pow, é lento e não é tão preciso quanto multiplicar por potências inteiras. Além disso, você pode economizar muito tempo usando o formulário de Horner (veja abaixo)

final double DEG2RAD = Math.PI/180;
double ang = launchAngle * DEG2RAD;
double v0x = launchVelocity * cos(ang); // initial velocity in x
double v0y = launchVelocity * sin(ang); // initial velocity in y

double x = (v0x * time);
// double y = (v0y * time) + (0.5 * g * (float)Math.Pow(time, 2));
double y = (0.5 * g * time + v0y) * time

Se você está desesperado por desempenho, pode até precompor 0,5 * g, mas o código acima o levará 90% do caminho sem fazer nada muito louco. Faça benchmark fazendo isso 10 milhões de vezes, se desejar, não é uma quantidade enorme de tempo, mas em termos percentuais é bastante grande - as bibliotecas são muito lentas em Java

Então, se você queria o ângulo em que a flecha deveria ir, o que você quer é

atan(dy/dx)

E, neste caso, isso funcionaria porque dx é uma constante. Mas, em geral, dx pode ser zero, então você geralmente deseja usar:

atan2(dy, dx)

que é uma função projetada especificamente para este trabalho.

Mas, como eu disse, as funções de biblioteca em Java são terrivelmente lentas e, nesse caso, há uma maneira melhor de fazê-lo sem o mencionado @FxIII acima.

Se a velocidade horizontal for sempre v0x e a velocidade vertical for:

double vy = v0y - 0.5 * g * time;

então seu delta é: vx, vy

Você não precisa do ângulo. Se você quiser desenhar uma flecha, use algo nominalmente como:

plot (x, y, x + vx, y + vy);

Não sei o que você está desenhando, portanto, se você precisar do ângulo para girá-lo (como se estivesse usando o JOGL), use o ângulo.

Não se esqueça de usar o opengl para transformar o ângulo novamente em graus, porque o ATAN2 retorna radianos:

final double RAD2DEG = 180 / Math.PI;
double ang = Math.atan2(vy,vx); // don't forget, vy first!!!
double deg = ang * RAD2DEG;
Dov
fonte
2

Tanh () ( tangente hiperbólica ) assume um ângulo como parâmetro, mas você alimentou a proporção dos lados.

O que você realmente deseja é usar o arco tangente hiperbólico , que toma a proporção dos lados como parâmetro e retorna o ângulo. (Nomear isso pode ser "atanh", "atanh2", "arctanh" ou algo semelhante; parece variar muito entre diferentes bibliotecas de matemática)

Trevor Powell
fonte
Não, você não quer nada hiperbólica
Dov
Gah, você está absolutamente certo. Eu imediatamente percebi o erro "uso da trigonometria básica" e perdi que a função que ele estava usando estava completamente incorreta pelo resto de sua abordagem.
Trevor Powell
Tan () assume um ângulo. Atan assume uma razão lateral do triângulo (sin / cos).
3Dave