Uma bola bate no canto, onde ela irá desviar?

46

Preciso retocar minha trigonometria e espero que você possa ajudar aqui com um modelo matemático simples. Aqui está o meu modelo até agora na imagem em anexo. Estou ciente de que a animação do quadro apresenta outros problemas quando a bola está se movendo muito rápido, mas, por enquanto, só preciso calcular ballDx e ballDy. Também é possível que ballDx = 0 (somente movimento vertical), mas quando a bola desviar ballDx pode obter um valor diferente.

Colisão 2D entre a bola e a borda do canto de um objeto sólido e imóvel

Lumis
fonte
22
É isso que eles chamam de "caso de canto"?
Andrew Grimm
2
Definitivamente, como as coisas acontecem, em breve poderemos empregar a teoria da relatividade para resolvê-la - o problema está ganhando massa (cinco).
Lumis

Respostas:

45

Nota: Todos os itens a seguir assumem que a superfície da bola não possui atrito (portanto, ela não começará a girar ou se recuperar de forma diferente porque é).

No momento da colisão, a bola estará tocando o canto. Quando objetos sólidos colidem, uma força age ao longo da superfície normal, ou seja, perpendicular à superfície no ponto de colisão.

Como é uma bola, perpendicular à superfície está em direção ao centro da bola. Ok, então sabemos a direção da força, e quanto à sua magnitude? Assumindo uma colisão elástica (e que o retângulo não pode se mover), a bola deve se recuperar na mesma velocidade em que impactou.

Seja (nDx, nDy) a velocidade após a colisão, (oDx, oDy) a velocidade antes da colisão e (x, y) a posição da bola no ponto de colisão. Vamos assumir ainda que o canto com o qual a bola colide está em (0,0).

Expressando nossas idéias como fórmulas, temos:

(nDx, nDy) = (oDx, oDy) + c * (x, y)
length (nDx, nDy) = length (oDx, oDy)

O que equivale a:

nDx = oDx + c * x
nDy = oDy + c * y
nDx^2 + nDy^2 = oDx^2 + oDy^2

Substituindo as duas primeiras equações na última, obtemos:

(oDx + c * x)^2 + (oDy + c * y)^2 = oDx^2 + oDy^2

Expansão usando o torem binomial

(a+b)^2 = a^2 + 2ab + b^2 

rendimentos:

oDx^2 + 2 * oDx * c * x + (c * x) ^ 2 + oDy^2 + 2 * oDy * c * y + (c * y) ^ 2 = oDx^2 + oDy^2
2 * oDx * c * x + 2 * oDy * c * y + (c * x) ^ 2 + (c * y) ^ 2 = 0
(2 * oDx * x + 2 * oDy * y) * c + (x^2 + y^2) * c^2 = 0

Essa equação quadrática para ctem duas soluções, uma das quais é 0. Obviamente, não é essa a solução em que estamos interessados, pois geralmente a direção da bola muda como resultado da colisão. Para obter a outra solução, dividimos os dois lados por ce obtemos:

(2 * oDx * x + 2 * oDy * y) + (x^2 + y^2) * c = 0

Isso é:

 c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)

Para resumir, temos:

c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)
nDx = oDx + c * x
nDy = oDy + c * y

Editar : No código:

if (collision) {
    float x = ballX - cornerX;
    float y = ballY - cornerY;
    float c = -2 * (ballDx * x + ballDy * y) / (x * x + y * y);
    ballDx = ballDx + c * x;
    ballDy = ballDy + c * y;
}

Algumas considerações de implementação: Embora você possa se aproximar (x, y) da posição da bola após a etapa de simulação, essa aproximação alterará o ângulo de deflexão e, portanto, será muito perceptível, portanto, suas etapas de simulação precisam ser muito boas (talvez tal a bola não move mais de 1/20 do seu diâmetro por etapa). Para uma solução mais precisa, você pode calcular o tempo em que a colisão ocorre e dividir a etapa de simulação naquele momento, ou seja, executar uma etapa parcial até o ponto de colisão e outra etapa parcial para o restante da etapa.

Edit 2: Computando o ponto de impacto

Seja r o raio, (x0, y0) a posição e (dx, dy) a velocidade da bola no início do passo da simulação. Para simplificar, vamos supor que o canto em questão esteja localizado em (0,0).

Nós sabemos:

(x,y) = (x0, y0) + (dx, dy) * t

Nós queremos

length(x,y) = r

Isso é

(x0 + dx * t) ^ 2 + (y0 + dy * t) ^ 2 = r^2
x0^2 + 2 * x0 * dx * t + dx^2 * t^2 + y0^2 + 2 * y0 * dy * t + dy^2 * t^2 = r ^ 2
(dx^2 + dy^2) * t^2 + (2 * x0 * dx + 2 * y0 * dy) * t + (x0^2 + y0^2 - r^2) = 0
\____  _____/         \____________  ___________/       \_______  ________/
     \/                            \/                           \/
     a                             b                            c

Essa é uma equação quadrática em t. Se seu discriminante

D = b^2 - 4 * a * c

é negativo, não tem soluções, ou seja, a bola nunca acertará o canto no seu percurso atual. Caso contrário, suas duas soluções são dadas por

t1 = (-b - sqrt(D)) / (2 * a)
t2 = (-b + sqrt(D)) / (2 * a)

Estamos interessados ​​no momento em que a colisão começou, que é a anterior t1.

Seu método se tornaria:

    // compute a,b,c and D as given above

    if (D >= 0) {
        t = (-b - sqrt(D)) / (2 * a);
        if (0 < t && t <= ts) {
            // collision during this timestep!

            x = x + t * dx;
            y = y + t * dy;
            ts = ts - t;

            // change dx and dy using the deflection formula 
        }
    }

    x = x + ts * dx;
    y = y + ts * dy;
meriton - em greve
fonte
1
isso merece +1
dynamic
1
Sinta-se livre para votar, então :-)
meriton - em greve
3
Você diz isso muito cedo, At the moment of collision, the ball will be touching the cornermas não vejo uma justificativa para essa aproximação (e deve ser uma aproximação porque não é verdade - a bola está tocando em dois lugares, nenhum dos quais é o canto).
22411 Peter
1
@ Peter Taylor: Você notou que o OP puxou a bola para fora do retângulo, e a fórmula de detecção de colisão dada na pergunta também assume isso? Você precisa pensar fora da caixa aqui :-)
meriton - em greve
1
Adore esta resposta, mas ela poderia usar alguma marcação $ \ LaTeX $ da matemática.
Martin Wickman
13

Aqui está uma maneira visual de analisar um problema.

O conjunto de problemas original é círculo x retângulo (cinza na imagem abaixo). Isso é equivalente ao ponto x retângulo arredondado (mostrado em preto).

Portanto, este é um problema de várias partes. Você está testando sua colisão de pontos vs. 4 linhas (extrudadas da borda da caixa pelo raio do círculo original) e 4 círculos (nos cantos do retângulo com o mesmo raio do círculo original).

Com a velocidade aproximada da imagem original, o ponto atingirá o círculo do canto inferior direito. Tudo o que você precisa fazer é descobrir o ponto no círculo do canto em que você atingirá, calcular o ângulo e refletir sobre ele.

insira a descrição da imagem aqui

Deixarei a derivação disso como um exercício para o leitor.

Tetrad
fonte
2

Estou trabalhando em um jogo e também preso aqui. Mas acho que é assim:

insira a descrição da imagem aqui

Há outra visão. Meu problema é que não sei como calcular rapidamente o novo dx, dy (para mim, usar a matemática tradicional requer muitos cálculos).

Risa
fonte
Meu ponto de vista é diferente do do segundo link, porque não acho que o novo vetor de velocidade dependa do centro do bloco assim. Meu irmão me disse que a bola retornará à direção antiga (dx = -dx && dy = - dy), mas acho que não.
Risa
Se a bola bater no canto e a distância da bolaX do cantoX for menor que 1/4 da bolaW, ela retornará, caso contrário, desviará para a direita. Este é um modelo simples que estou usando no momento, que não está ajustado para encontrar o ângulo exato.
Lumis
0

A cinemática tem tudo a ver com escolher o quadro de referência correto, como o mais conveniente para os cálculos.

Aqui, primeiro definiremos a transformação T que resolve nossos eixos em componentes paralelos ( x ' ) e perpendiculares ( y' ) a uma linha entre o centro da bola e o canto. A transformação inversa T * restaurará nosso sistema de coordenadas original.

Nesse novo quadro de referência, pela reflexão (e pela simetria temporal e espacial da física), temos a transformação de velocidade do contato M (um impulso pontual ) como aquele que reverte o componente x ' e deixa inalterado o componente y' . Em termos de matriz , essa é a matriz diagonal com -1 e 1 na diagonal.

Então a velocidade após a colisão é simplesmente: V ' = T * . M . T . Vo .

O momento do impacto t é, em seguida, apenas a solução de ( T . Do ) + ( X . T . Vo ) ( t ) = r onde X é o operador de projecção do eixo X e r é o raio da esfera. Reorganizados, obtemos
t = ( r - ( T . Do )) / (( X . T . Vo ) ( t ))

Isso tem a vantagem distinta de enterrar toda a matemática complexa em bibliotecas gráficas padrão rigorosamente escritas, testadas e depuradas. Essa solução também é idêntica para situações 2D e 3D - basta alternar entre a biblioteca de gráficos. Por fim, destaca que é preciso primeiro pensar em quadros de referência apropriados antes de enfrentar qualquer problema de física. Sempre existe a tentação do NIH, mas na verdade isso é apenas uma receita para bugs quando soluções mais sucintas estão disponíveis.

Pieter Geerkens
fonte