Obter pontos em uma linha entre dois pontos

9

Estou criando um jogo espacial simples em JavaScript, mas agora bati um muro em relação a vetores.

A visualização do jogo é de cima para baixo em uma grade 2D. Quando o usuário clica na grade, a nave espacial voa para esse local.

Então, se eu tiver dois conjuntos de pontos:

{ x : 100.2, y : 100.6 }; // the ship
{ x : 20.5,  y : 55.95 }; // the clicked coordinates

Se o loop do jogo marca 60 iterações por segundo e a velocidade desejada do navio é de 0,05 pontos por tick (3 pontos por segundo), como faço para calcular o novo conjunto de coordenadas do navio para cada tick do loop do jogo?

ps Não quero explicar a inércia ou vários vetores que afetam a nave, só quero que a nave pare o que estiver fazendo (por exemplo, voando para um lado) e vá para as coordenadas clicadas a uma velocidade estática.

Stephen
fonte

Respostas:

8

No pseudocódigo:

speed_per_tick = 0.05
delta_x = x_goal - x_current
delta_y = y_goal - y_current
goal_dist = sqrt( (delta_x * delta_x) + (delta_y * delta_y) )
if (dist > speed_per_tick)
{
    ratio = speed_per_tick / goal_dist
    x_move = ratio * delta_x  
    y_move = ratio * delta_y
    new_x_pos = x_move + x_current  
    new_y_pos = y_move + y_current
}
else
{
    new_x_pos = x_goal 
    new_y_pos = y_goal
}
Tristan
fonte
@Tristan: Você quer dizer goal_distcom sua ifcondição?
Nate W.
21

LERP - Interpolação Linear

Eu dei essa resposta para um problema semelhante há alguns dias, mas aqui vamos nós:

Interpolação linear é uma função que fornece um número entre dois números, com base no progresso. Você poderia, na verdade, obter um ponto entre dois pontos.


A Grande Fórmula - Como calcular

A fórmula geral do LERP é dada por pu = p0 + (p1 - p0) * u. Onde:

  • pu: O número do resultado
  • p0: o número inicial
  • p1: O número final
  • u: O progresso. É dado em porcentagem, entre 0 e 1.

Como obter porcentagem

Você pode estar se perguntando: "Como posso obter essa porcentagem !?". Não se preocupe. É assim: quanto tempo leva para viajar até o vetor inicial terminar? Ok, divida pelo tempo que já passou. Isso lhe dará a porcentagem.

Olha, algo como isto: percentage = currentTime / finalTime;


Cálculo de vetores

Para obter um vetor resultante, tudo que você precisa fazer é aplicar a fórmula duas vezes, uma para o componente X e outra para o componente Y. Algo assim:

point.x = start.x + (final.x - start.x) * progress;
point.y = start.y + (final.y - start.y) * progress;

Cálculo do tempo variável

Você pode querer que seus pontos viajem a uma velocidade de 0,5 pontos, sim? Então, digamos, uma distância maior será percorrida em um período maior.

Você pode fazer o seguinte:

  • Obter o comprimento da distância Para isso, você precisará de duas coisas. Obtenha o vetor de distância e depois transforme-o em um valor de comprimento.

    distancevec = final - start;
    distance = distancevec.length();

Espero que você conheça matemática de vetores. Caso contrário, você pode calcular um comprimento vetorial por esta fórmula d = sqrt(pow(v.x, 2) + pow(v.y, 2));.

  • Obtenha o tempo necessário e atualize a hora final. Este é fácil. Como você deseja que cada tick receba um comprimento de 0,5, basta dividir e obter quantos ticks conseguimos.

    finalTime = distance / 0.5f;

Feito.

AVISO: Talvez essa não seja a velocidade pretendida para você, mas esta é a certa. para que você tenha um movimento linear, mesmo em movimentos diagonais. Se você quiser fazer x + = 0,5f, y + = 0,5f, leia um livro de matemática vetorial e verifique novamente seus planos.

Gustavo Maciel
fonte
E se você quiser% deixado para o destino da sua posição? SE você não pode usar o tempo delta, mas sim x: y coordena.
Dave
Se você calculou progresscomo indicado nesta resposta, ele deve estar no 0..1intervalo. Apenas faça:progressLeft = 1.0 - progress;
Gustavo Maciel
3

Isso pode ser feito calculando o normal da direção e calculando a posição atual através da equação paramétrica

newPoint = startPoint + directionVector * velocity * t

Onde t é o tempo decorrido desde que o navio começou a viajar na direção desejada. Você também pode fazer isso por atualização via

newPoint = currentPoint + directionVector * velocity * timeDelta

E você apenas calcula isso em cada quadro / física / etc. atualizar até que o navio chegue ao seu destino.

hatboyzero
fonte