Métodos de simulação física para grandes tempos delta?

9

Quais métodos de simulação física são mais adequados para um tempo delta realmente grande (horas a semanas)?

Além disso, enfrentaria problemas ao combinar diferentes métodos para grandes e pequenos tempos delta?

fread2281
fonte
11
Depende em grande parte da sua área de destino. Difícil dizer qualquer coisa sem saber mais sobre seus objetivos reais lá. Muito amplo.
Kromster
Esta questão está relacionada.
Anko
Em princípio, a escala de tempo adequada depende do que o jogador experimenta. Deseja que seja preciso na escala de tempo de semanas e faça com que o player interaja com ele em tempo real? Isso é muito mais difícil do que fazê-lo funcionar na escala de tempo de semanas que o jogador experimenta muitas vezes em tempo real ( ou seja, um segundo da experiência do jogador é uma semana em tempo real).
Mklingen
se você estiver simulando movimentos de nuvens ou variáveis ​​termodinâmicas em células de centenas de metros de largura, com um dt de 10 minutos, é razoável. mas corpo rígido em escalas usuais, não muito. qual é a aplicação?
v.oddou
O aplicativo é um mecanismo de "recuperação", onde a simulação é executada desde a última carga (de uma parte do mundo), a lógica do jogo é toda baseada em retorno de chamada, onde retornos de chamada são temporizadores ou retornos de colisão, quero poder executar a física para a próxima cronômetro de retorno de forma eficiente e faça com que a simulação física lide com os retornos de chamada de colisão. As colisões são relativamente improváveis, mas eu gostaria que os retornos de chamada de colisão tivessem o estado de jogo (física) disponível no momento da colisão.
fread2281

Respostas:

5

Você provavelmente usará aceleração constante para esses períodos de tempo grandes (que podem ser aceleração zero). A derivada da aceleração constante em relação ao tempo é 0. Isso significa que não muda em relação ao tempo, portanto, não importa o tamanho do seu tempo delta.

Essa pequena integração com relação ao tempo fornece as equações necessárias.

a = a
v = at + v0
s = .5at^2 + v0*t + s0

Onde: a = aceleração, v = velocidade, v0 = velocidade inicial, s = posição, s0 = posição inicial, t = tempo

Usando essa estratégia, você pode usar períodos de milissegundos a semanas, se desejar. Combiná-los seria resolvido nos parâmetros v0e s0da equação.

Para lidar com colisões, você precisará implementar estratégias semelhantes às usadas para objetos pequenos de alta velocidade . Primeiro calcule a nova posição usando a equação acima e depois varra entre a posição antiga e a nova para todos os objetos. Como qualquer um desses objetos pode ter se cruzado (minutos ou dias antes), isso pode se tornar muito complexo. É provável que, como você tenha um período delta tão grande, espere ter tempo de sobra para processar essas possíveis colisões.

MichaelHouse
fonte
e as colisões?
fread2281
Atualizei a resposta para incluir estratégias para lidar com colisões.
MichaelHouse
isto é falso. Sabe-se que a integração de Euler se desvia para integrações constantes, enquanto Verlet (ou RK2, RK4) não.
v.oddou
@ v.oddou Considerando que essas simulações são para jogos, não acho que a precisão necessária seja necessária. A complexidade adicional e a dificuldade de adicionar colisões ao Verlet tornam a integração do Euler uma escolha superior.
MichaelHouse
2

Vamos dar um exemplo com gravidade.

Na função abaixo, assuma que temos variáveis ​​de membro de classe para posição e velocidade. Precisamos atualizá-los devido à força da gravidade a cada dt segundos.

void update( float dt )
{
   acceleration = G * m / r^2;
   velocity = velocity + acceleration * dt;
   position = position + velocity * dt;
}

À medida que dtcada vez menores, nossa simulação se torna cada vez mais precisa (embora, se dtfor pequena demais, podemos encontrar erros de precisão ao adicionar números pequenos a grandes).

Basicamente, você precisa decidir o máximo que dtsua simulação pode suportar para obter bons resultados. E se o dtque entra é muito grande, basta dividir a simulação em etapas menores, onde cada etapa é o máximo dtque você permite.

void update( float dt )
{
   acceleration = G * m / r^2;
   velocity = velocity + acceleration * dt;
   position = position + velocity * dt;
}

// this is the function we call. The above function is a helper to this function.
void updateLargeDt( float dt )
{
    const float timeStep = 0.1;
    while( dt > timeStep   )
    {
        update( timeStep  );
        dt -= timeStep ;
    }

    update( dt );  // update with whatever dt is left over from above
}

Portanto, com essa estratégia, você pode simplesmente se ajustar timeStep à fidelidade necessária (espere um segundo, minuto, hora ou o que for necessário para obter uma representação precisa da física.

padrão
fonte
1

A maioria dos jogos costuma usar o simples método Euler de integração direta (ou seja, integrar a velocidade na posição ao longo do tempo e integrar a aceleração na velocidade). Infelizmente, o método Euler é adequado apenas para escalas de tempo muito pequenas e tiragens curtas.

Existem métodos mais complexos que são mais precisos em escalas de tempo muito longas. O mais popular e mais fácil de implementar é talvez Runge-Kutte-4 . O RK4 determina a posição no futuro, amostrando quatro posições e velocidades no passado e interpolando. Ele tende a ser muito mais preciso que o método Euler em escalas de tempo mais longas, mas é mais caro em termos computacionais.

Por exemplo, se você quiser calcular a física de um planeta em órbita real, atualizando a cada poucos dias em tempo real, o método Euler fará com que o planeta caia no espaço depois de apenas algumas órbitas devido a erros numéricos. O RK4 geralmente mantém o planeta em órbita quase da mesma forma milhares de vezes antes de acumular muitos erros.

No entanto, implementar colisões no RK4 pode ser muito desafiador ...

mklingen
fonte