Eu amo PhysicsJS . Quase exatamente o que diz na lata: modular, extensível e fácil de usar (também é divertido!). Mas estava faltando alguma coisa.
No começo eu estava perdido. A aceleração da gravidade padrão é 0,0004. Bem, 0,0004 o quê?
O próprio criador tinha uma resposta para mim: pixels por milissegundo ao quadrado .
Fazendo as contas ( e dandelany funcionou bem ), significa que a escala padrão de uma simulação é quarenta e um pixels por metro.
É tudo muito interessante (eu realmente acho que sim = P) e acho que está bom para a maioria dos casos.
Mas eu queria algo diferente. Eu queria ser capaz de usar valores realistas para minha entrada e, em seguida, converter a saída conforme necessário. Eu queria ser capaz de definir essa proporção de pixels por metro facilmente (e ser capaz de alterá-la sempre que eu quiser, mesmo durante a simulação, quero dizer).
Se eu tiver uma simulação de queda de bola, quero ser capaz de definir a aceleração da gravidade como 9,807 (metros por segundo ao quadrado) para simular a terra ou apenas alterá-la para 1,622 para simular a aceleração da gravidade na lua. Quero ler esses valores no código. Quero mudar a proporção de metros por pixel para dez ou cinco e ver essa bola caindo aparentemente devagar, porque é como se a estivesse vendo de muito longe …
Tudo isso também facilitou a implementação do atrito contra o fundo, como em uma visão de cima para baixo, e a resistência do ar como na simulação 2.1d. (Veja o incrível artigo de Burak Kanber Modeling Physics in Javascript: Gravity and Drag )
O chute
Inicialmente testei minha abordagem com alguns problemas.
O primeiro era Quanta Força o Jogador de Futebol Médio Usa para Chutar a Bola? .
Aqui está o resultado: http://jsfiddle.net/slacktracer/zCc35/
O “chute” acontece após dois segundos. Você terá que verificar o console para ver quanto tempo durou (deve ser aproximadamente 0,05 segundos) e a velocidade resultante (em metros por segundo).
Queda
O segundo problema era o problema da queda da bola.
Você pode vê-lo aqui: http://jsfiddle.net/slacktracer/F5U6h/
Você também terá que verificar o console para obter informações. Usei as seguintes referências (para que você mesmo possa testar diferentes valores): http://www.gravitycalc.com/ & Equações para um corpo em queda .
Como eu faço isso
Nesta situação, como em muitas outras, o tempo é essencial.
Eu pensei que se eu pudesse fazer PhysicsJS integrar usando segundos em vez de milissegundos, todo o resto se seguiria. E foi algo assim. Eu só tive que mudar como a aceleração entrou no sistema.
No integrador de verlet, isso acontece aqui:
// Apply acceleration
// v += a * dt * dt
state.vel.vadd( state.acc.mult( dtdt ) );
O que eu precisava fazer era transformar esses dts de milissegundos para segundos e então eu teria aceleração em pixels por segundo ao quadrado (muito mais próximo do que eu queria).
v += a * dt * dt
Torna-se:
v += a * (dt / 1000) * (dt / 1000)
then
v += a * (dt * dt) / (1000 * 1000)
then
v += a * (dt * dt) / 1000000
Agora, um pixel é o mesmo que um metro. Para tornar o medidor facilmente configurável, tudo o que precisamos fazer é multiplicar por qualquer valor que eu escolher para um medidor. Claro, é melhor fazer com uma variável. Uma opção do integrador.
init: function( options ){
options.metre = options.metre || 41;
// call parent init
parent.init.call(this, options);
},
Estou mantendo os aprox. taxa de inadimplência, bem como inadimplência. =)
E depois:
state.vel.vadd( state.acc.mult( ( dtdt / 1000000 ) * metre ) );
Eu criei um integrador e chamei -o de verlet metro por segundo ao quadrado (não muito criativo, suponho).
Olhando agora, tudo parece muito simples. Mas eu tive que bater minha cabeça contra a parede muito antes de descobrir tudo. Em outras palavras, foi muito divertido! = P
Agora, não estou dizendo que seja perfeito ou final de forma alguma. (Nem tenho certeza se é uma boa abordagem. Ainda tenho muito a aprender sobre os internos do PhysicsJS) Parece estar funcionando bem para minhas necessidades até agora e tenho grandes planos para isso.
Este artigo é muito bruto, eu sei. Eu só tinha que colocar isso para fora. Espero que seja útil para outra pessoa e todo e qualquer feedback é bem-vindo. Sejam outras abordagens, quão bom ou ruim é o meu, dicas para escrever artigos melhores, mais úteis, perguntas. Qualquer coisa, mesmo. Se você leu tudo isso, obrigado. É muito gentil da sua parte.
(Vou melhorar ou fazer um acompanhamento conforme necessário ou solicitado)
Também inspirado em http://natureofcode.com/book/chapter-2-forces/
Escrito com StackEdit .