2d problema de colisión de la bola: no hay conservación de la energía

Estoy tratando de escribir una simulación física simple donde las bolas con radios y masas diferentes rebotan en un entorno perfectamente elástico y sin fricción. Escribí mi propio código siguiendo este recurso: http://www.vobarian.com/collisions/2dcollisions2.pdf y también probé el código de aquí: Ball to Ball Collision – Detection and Handling

PREGUNTA EDITADA

Con la ayuda de Rick Goldstein y Ralph, he conseguido mi código para trabajar (hubo un error tipográfico ..). Muchas gracias por su ayuda. Sin embargo, todavía estoy confundido en cuanto a por qué el otro algoritmo no está funcionando para mí. Las bolas rebotan en las direcciones correctas, pero la energía total del sistema nunca se conserva. Las velocidades se hacen más y más rápido hasta que las bolas empiezan a parpadear en posiciones estáticas en la pantalla. De hecho, quiero usar este código en mi programa, porque es mucho más conciso que el que escribí.

Aquí está el algoritmo funcional que escribí (aunque tomé el primer pedacito de esa otra fuente). Su en una clase de la burbuja:

public void resolveCollision(Bubble b) { // get the minimum translation distance Vector2 delta = (position.subtract(b.position)); float d = delta.getMagnitude(); // minimum translation distance to push balls apart after intersecting Vector2 mtd = delta.multiply(((getRadius() + b.getRadius())-d)/d); // resolve intersection -- // inverse mass quantities float im1 = 1 / getMass(); float im2 = 1 / b.getMass(); // push-pull them apart based off their mass position = position.add(mtd.multiply(im1 / (im1 + im2))); b.position = b.position.subtract(mtd.multiply(im2 / (im1 + im2))); //get the unit normal and unit tanget vectors Vector2 uN = b.position.subtract(this.position).normalize(); Vector2 uT = new Vector2(-uN.Y, uN.X); //project ball 1 & 2 's velocities onto the collision axis float v1n = uN.dot(this.velocity); float v1t = uT.dot(this.velocity); float v2n = uN.dot(b.velocity); float v2t = uT.dot(b.velocity); //calculate the post collision normal velocities (tangent velocities don't change) float v1nPost = (v1n*(this.mass-b.mass) + 2*b.mass*v2n)/(this.mass+b.mass); float v2nPost = (v2n*(b.mass-this.mass) + 2*this.mass*v1n)/(this.mass+b.mass); //convert scalar velocities to vectors Vector2 postV1N = uN.multiply(v1nPost); Vector2 postV1T = uT.multiply(v1t); Vector2 postV2N = uN.multiply(v2nPost); Vector2 postV2T = uT.multiply(v2t); //change the balls velocities this.velocity = postV1N.add(postV1T); b.velocity = postV2N.add(postV2T); } 

Y aquí está el que no funciona

 public void resolveCollision(Bubble b) { // get the minimum translation distance Vector2 delta = (position.subtract(b.position)); float d = delta.getMagnitude(); // minimum translation distance to push balls apart after intersecting Vector2 mtd = delta.multiply(((getRadius() + b.getRadius())-d)/d); // resolve intersection -- // inverse mass quantities float im1 = 1 / getMass(); float im2 = 1 / b.getMass(); // push-pull them apart based off their mass position = position.add(mtd.multiply(im1 / (im1 + im2))); b.position = b.position.subtract(mtd.multiply(im2 / (im1 + im2))); // impact speed Vector2 v = (this.velocity.subtract(b.velocity)); float vn = v.dot(mtd.normalize()); // sphere intersecting but moving away from each other already if (vn > 0.0f) return; // collision impulse (1f is the coefficient of restitution) float i = (-(1.0f + 1f) * vn) / (im1 + im2); Vector2 impulse = mtd.multiply(i); // change in momentum this.velocity = this.velocity.add(impulse.multiply(im1)); b.velocity = b.velocity.subtract(impulse.multiply(im2)); } 

Déjeme saber si usted encuentra algo. Gracias

3 Solutions collect form web for “2d problema de colisión de la bola: no hay conservación de la energía”

¿Hay un error tipográfico en la línea que establece v1nPost? Parece que el denominador debe ser this.mass + b.mass , no this.mass * b.mass .

Además, como estás calculando una colisión entre this y b , ¿estás comprobando para asegurarte de que no estás haciendo la misma colisión entre b y this , duplicando así el delta aplicado a cada burbuja participante en la colisión?

Hago una primera suposición: getMass () devuelve un entero (o int) (y no un flotador o doble)?

Si esto es cierto, el problema es que 1 / getMass() resultará en un valor entero (y puede ser sólo 1 o más tiempo 0)). Para corregir esto sustituya 1 por 1.0 o 1.0f

Debido a que la regla general es simple: Si tiene una operación matemática (+, -, *, /), el tipo resultante será entero si ninguno de los dos operadores es una estructura de datos en coma flotante (doble o flotante)

De todos modos: podría haber un segundo problema, puede su calcualtion no es enougth preciso. A continuación, debe utilizar doble en lugar de flotar.

Hay una parte que parece extraña:

Los dos cálculos:

 float v1nPost = (v1n*(this.mass-b.mass) + 2*b.mass*v2n)/(this.mass*b.mass); float v2nPost = (v2n*(b.mass-this.mass) + 2*this.mass*v1n)/(this.mass+b.mass); 

Son simétricos, excepto la última operación, en la primera es * en la segunda es +

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.