Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: CoLSoN2 en 29 de Diciembre de 2004, 11:52:53 PM

Título: Física: Velocidad Después De Una Colisión
Publicado por: CoLSoN2 en 29 de Diciembre de 2004, 11:52:53 PM
 Voy a ir al grano.

Situación:
- Tengo dos partículas circulares (2D) que en un momento colisionan (distancia de centros > suma radios)
- De cada particula tengo:
   - Posición actual
   - Posición anterior (con lo cual tengo la velocidad instantánea)
   - Masa
   - Coeficiente de restitución. En el rango [0.0, 1.0]
   - Coeficiente de fricción. En el rango [0.0, 1.0]
   - Masa
- Además tengo Aceleración y Radio pero no creo que sean útiles para este problema.

Lo que quiero obtener:
- La nueva posición de ambas particulas (así como "posición anterior", de modo que concuerden con la velocidad resultante que quiero), teniendo en cuenta todos los atributos antes descritos.

Los coef. de restitución y fricción que se usarán en la fórmula, ¿cuáles son? ¿la media de los coefs. de ambas partículas?

Ahora mismo el código que uso es:



/// pNormal = normal de la colisión
/// pDepth = (suma radios - distancia centros=
bool Particle::collisionResponse(Particle& pParticle, const Vector2& pNormal, float pDepth)
{
// move particle away from plane
float invmass = (mInvMass + pParticle.mInvMass);

Vector2 v0 = mCurPos - mOldPos;
Vector2 v1 = pParticle.mCurPos - pParticle.mOldPos;

mCurPos += pNormal * (pDepth * mInvMass/invmass);
pParticle.mCurPos -= pNormal * (pDepth * pParticle.mInvMass/invmass);

v0 = v0.reflect(pNormal.perpendicular());
v1 = v1.reflect(pNormal.perpendicular());

// apply friction & elasticity
float friction = (mKineticFriction + pParticle.mKineticFriction) / 2.0f;

Vector2 Vn0 = v0.dotProduct(pNormal) * pNormal;
Vector2 Vt0 = v0 - Vn0;
v0 = (Vn0*mElasticity + Vt0*(1 - friction)) * mInvMass/invmass;

Vector2 Vn1 = v1.dotProduct(pNormal) * pNormal;
Vector2 Vt1 = v1 - Vn1;
v1 = (Vn1*pParticle.mElasticity + Vt1*(1 - friction)) * pParticle.mInvMass/invmass;

mOldPos = mCurPos;
mCurPos = mOldPos + v0;
pParticle.mOldPos = pParticle.mCurPos;
pParticle.mCurPos = pParticle.mOldPos + v1;

return true;
}

El problema con este código ocurre principalmente en la siguiente situación (en un eje para simplificar el ejemplo)

Partícula A se mueve con velocidad V = (10, 0)
Partícula B está a la izquierda de A se mueve con velocidad V = (20, 0)

cuando B alcanza a A, no es un choque frontal, y entonces la proyección de B.V con la normal de colisión da efectivamente que la nueva velocidad es hacia atrás, mientras que la de A, que iba en la misma dirección de B, hace que retroceda (cuando, realmente, seguiría en la misma dirección o como muchiiisimo si fuera una colisión inelástica, se pararía).

Es decir:
                     O ---->    O->
                         O ----> O->
                            [...]
                                O O->
                      [Procesar colisión]
                          <--O <-O               = Velocidad de B erroneamente invertida!

Espero haberme explicado con claridad :)
Título: Física: Velocidad Después De Una Colisión
Publicado por: BeRSeRKeR en 30 de Diciembre de 2004, 12:16:43 AM
 A ver si esta página te ayuda.

Saludos.
Título: Física: Velocidad Después De Una Colisión
Publicado por: ethernet en 30 de Diciembre de 2004, 12:40:27 AM
 Estás haciendo un billar?

Título: Física: Velocidad Después De Una Colisión
Publicado por: senior wapo en 30 de Diciembre de 2004, 01:47:30 AM
 Ya ni me acuerdo de la física del instituto pero me has picado la curiosidad xD

Me apuesto los huevecillos del perro que no tengo a que los coeficientes de restitución se multiplican, no se calcula la media.

En un choque perfectamente elastico ambos serian 1, 1x1=1 se mantiene toda la energia. Si una particula es de goma bastante dura (restitución=0.75) y la otra de goma blanda (rest=0.5, se deforma mas) el coeficiente de restitución del choque no seria 0.75*0.5= 0.375 ?

A mi me parece lógico que se combinen, pero vamos, ni puta idea. Yo lo digo por si acaso  :P

PD: Lo de las normales ni puta idea pero cuéntanoslo cuando lo sepas que me tienes intrigado  :D