Respostas:
A função de bandeja parabólica é definida como:
Fx = Vox*t + Ox;
Fy = -0.5 * g * t * t + Voy*t + Oy;
Valores conhecidos:
P: the target point.
O: the origin point.
g: gravity.
t: time needed to impact.
Valores desconhecidos:
Vo: Initial Velocity
Para calcular 'Vo', podemos atribuir valores à função F:
't' = flight time 'duration'
'F' = target point 'P'
(Px-Ox)
Vox = --------
duration
Py + 0.5* g * duration * duration - Oy
Voy = ---------------------------------------
duration
Agora você pode obter todos os valores para atingir o alvo desde a origem, fornecendo valores para t na equação F:
When t = 0 => F == O (Origin)
When t = duration => F == P (Target)
Recentemente, tive que resolver um problema semelhante, encontrei duas soluções, baseadas na fórmula que encontrei na página da Wikipedia 'Dan the Man' já mencionada: Trajetória de um projétil
Nesta solução, você precisa, de qualquer maneira, do ângulo de lançamento fixo ou da velocidade x. A velocidade Y não é necessária, pois lançamos o projétil em um ângulo específico.
Solução 1, o ângulo de lançamento é fixo, calcule a velocidade:
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
Solução 2, a velocidade é fixa, calcule o ângulo de lançamento:
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
No meu caso, essas soluções funcionaram muito bem.
Se você não se importa se é matematicamente correto, apenas se parece correto o suficiente, calcule o caminho reto e faça seu projétil seguir esse caminho, mas "empurre para cima" ao longo do normal dessa linha, em função da sua distância para baixo o segmento de linha, por isso aumenta à medida que se aproxima do meio do segmento e cai à medida que se afasta do meio do segmento de linha.
Você pode usar uma onda senoidal para isso, usando o intervalo de graus de -90 a +90 (onde -90 é o ponto esquerdo no segmento de linha, 90 é o ponto direito e você lê no meio) e multiplica o resultado por uma constante para ampliá-lo.
Se você precisar de uma resposta matemática / física puramente correta, isso não ajudará. Caso contrário, isso provavelmente pode funcionar muito bem para você!
Não se esqueça, a programação de jogos é sobre o uso de ilusões que parecem corretas (e são mais baratas de calcular), em vez de realismo.
Se você precisar apenas de algo que esteja quase certo e com uma velocidade fixa, poderá usar esse método muito simplificado.
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;
A distância pode ser negativa, mas ainda funcionará porque o ângulo também depende da distância. Se a distância for negativa, o ângulo que precisa ser adicionado também é negativo.
Você precisará brincar com o distanceFactor para encontrar o valor certo. Depende da gravidade e do poder do projétil. Deve estar próximo de 1 dividido pela distância máxima que o projétil pode percorrer.