Determinar o ângulo resultante da colisão na parede

14

Então, eu tenho um objeto se movendo em uma direção em direção a uma parede horizontal ou vertical fixa. Como computo o ângulo em que o objeto deve refletir? O objeto pode se aproximar da parede em um ângulo arbitrário.

DRiFTy
fonte

Respostas:

18

Se você conhece o vetor normal da parede e tem uma direção de entrada para o objeto, então o que você quer é o reflexo de um vetor através de um plano .

Se n é um vetor normalizado e v é a direção de entrada , então o que você deseja é - (2 ( n · v ) n - v ). O sinal de menos explica o fato de que a fórmula de reflexão não inverte realmente a direção, pois a velocidade de um objeto se inverte.

Essa resposta é dada em termos de matemática vetorial, não de ângulo, porque geralmente é preferível se você não tiver um motivo explícito para usar um ângulo. Observe que, se você precisar falar sobre ângulos, o ângulo de reflexão é igual ao ângulo de incidência. Se o ângulo é medido a partir do normal, o ângulo de saída é a negação do ângulo de entrada; se o ângulo é medido a partir da parede, é o complemento do ângulo de entrada.

John Calsbeek
fonte
Ótima explicação. Funcionou muito bem para mim! Obrigado!
DRiFTy
13

Você não especificou se era um jogo 2D ou 3D. Mas se é um jogo em 2D e suas paredes são garantidas como horizontais ou verticais e você apenas deseja ressaltar o objeto, há uma maneira muito mais fácil do que lidar com reflexões.

Simplesmente negue o componente X da velocidade do objeto ao atingir uma parede vertical ou o componente Y da velocidade do objeto ao atingir uma parede horizontal. Exemplo:

if( /* hit vertical wall */ )
{
    object.velocity.x *= -1;
}
if( /* hit horizontal wall */ )
{
    object.velocity.y *= -1;
}

Mas se você realmente se importa em conhecer o ângulo, em termos gerais, o ângulo de reflexão é o mesmo que o ângulo de incidência. Este ângulo é medido em relação ao normal da parede. Aqui está uma figura que deve deixar claro:

insira a descrição da imagem aqui

Caso você precise lidar com isso para paredes arbitrárias, precisará analisar como refletir um vetor. É realmente apenas uma fórmula pequena que pega o vetor normal e de incidência da parede e retorna o vetor refletido para você. Aqui está a fórmula que o XNA usa:

public static Vector3 Reflect(Vector3 vector, Vector3 normal)
{
    return vector - 2 * Vector3.Dot(vector, normal) * normal;
}

E para 2D, você pode simplesmente fazer:

public static Vector2 Reflect(Vector2 vector, Vector2 normal)
{
    return vector - 2 * Vector2.Dot(vector, normal) * normal;
}
David Gouveia
fonte
Desculpe por isso, é um jogo 2D. Gostaria de mantê-lo com base no ângulo, porque, como você disse, gostaria de poder usar qualquer parede. Obrigado!
DRiFTy
Eu editei para cobrir 2D também. Na verdade, é o mesmo, apenas com vetores 2D, mesmas operações e fórmulas
Gustavo Maciel
Uma parede em um jogo 2D pode ser inclinada, portanto a afirmação if it's a 2D game and your walls are guaranteed to be horizontal or verticalnão está correta. A segunda parte da resposta aborda a implementação correta. IMHO, a ordem das partes deve ser revertida, apresentando a solução geral primeiro e com ênfase, enquanto a solução em ângulo reto é apresentada como uma simplificação para o caso excepcional.
XenoRo 15/01/19