1
\$\begingroup\$

I am trying to create a simple elastic collision simulation in java. (I am using some helper libs like StdRandom)

Here is my Ball class :

class Ball
{
    double cx, cy;      
    Vector velocity;    
    double radius;
    double mass;            

    public Ball()
    {
        mass = 1.0;
        radius = 0.025;

        cx = StdRandom.uniform( 0.000+radius, 1.000-radius );
        cy = StdRandom.uniform( 0.000+radius, 1.000-radius );

        // vx = 0.015;
        // vy = 0.025;
        velocity = new Vector();
        velocity.setX( StdRandom.uniform( 0.0010, 0.015 ) );
        velocity.setY( StdRandom.uniform( 0.0010, 0.015 ) );    

    }

    public void move()
    {
        cx = cx + velocity.getX();
        cy = cy + velocity.getY();
    }


    // getter methods
    public double getCx(){  return cx;  }
    public double getCy(){  return cy;  }
    public double getVx(){  return velocity.getX(); }
    public double getVy(){  return velocity.getY(); }
    public double getRadius(){  return radius;  }
    public double getMass(){    return mass;    }

    // setter methods
    public void setCx( double val ){    cx = val; } 
    public void setCy( double val ){    cy = val; } 
    public void setVx( double val ){    velocity.setX( val ); } 
    public void setVy( double val ){    velocity.setY( val ); } 
    public void setRadius( double val ){    radius = val; } 
    public void setMass( double val ){  mass = val; }
}

And here is my method for resolving collisions:

if ( distSqr == radii_sum*radii_sum )
        {
            double phi, theta1, theta2;         // collision angle, a's movement angle, b's movement angle
            double v1, v2;                      // scalar values of velocity for balls a and b
            double m1, m2;                      // mass for ball's a and b
            double v1xf, v1yf, v2xf, v2yf;      // x and y components of final velocities after collision

            // calculate angles
            phi = Math.atan2( cy1-cy2, cx1-cx2 );
            theta1 = Math.atan2( a.getVy(), a.getVx() );
            theta2 = Math.atan2( b.getVy(), b.getVx() );

            // get mass
            m1 = a.getMass();
            m2 = b.getMass();

            // calculate scalar values of velocities
            v1 = Math.sqrt( a.getVx()*a.getVx() + a.getVy()*a.getVy() );
            v2 = Math.sqrt( b.getVx()*b.getVx() + b.getVy()*b.getVy() );

            v1xf = ((((v1 * Math.cos(Math.toRadians(theta1 - phi)) * (m1 - m2)) + (2 * m2 * v2 * Math.cos(Math.toRadians(theta2 - phi)))) / (m1 + m2)) * Math.cos(Math.toRadians(phi))) + (v1 * Math.sin(Math.toRadians(theta1 - phi)) * Math.cos(Math.toRadians(phi + (Math.PI/2))));
            v2xf = ((((v2 * Math.cos(Math.toRadians(theta2 - phi)) * (m2 - m1)) + (2 * m1 * v1 * Math.cos(Math.toRadians(theta1 - phi)))) / (m1 + m2)) * Math.cos(Math.toRadians(phi))) + (v2 * Math.sin(Math.toRadians(theta2 - phi)) * Math.cos(Math.toRadians(phi + (Math.PI/2))));

            v1yf = ((((v1 * Math.cos(Math.toRadians(theta1 - phi)) * (m1 - m2)) + (2 * m2 * v2 * Math.cos(Math.toRadians(theta2 - phi)))) / (m1 + m2)) * Math.sin(Math.toRadians(phi))) + (v1 * Math.sin(Math.toRadians(theta1 - phi)) * Math.sin(Math.toRadians(phi + (Math.PI/2))));
            v2yf = ((((v2 * Math.cos(Math.toRadians(theta2 - phi)) * (m2 - m1)) + (2 * m1 * v1 * Math.cos(Math.toRadians(theta1 - phi)))) / (m1 + m2)) * Math.sin(Math.toRadians(phi))) + (v2 * Math.sin(Math.toRadians(theta2 - phi)) * Math.sin(Math.toRadians(phi + (Math.PI/2))));



            a.setVx( v1xf );
            a.setVy( v1yf );
            b.setVx( v2xf );
            b.setVy( v2yf );
        }

I had some questions -

  1. Have I calculated the scalar velocities and angles correctly? The code does not work and balls pass through each other, sometimes even pushing other balls beyond boundary.
  2. How do I reflect velocity? As x and y components given above OR single speed var and an angle? If latter then can I use different speeds for x and y components?
  3. Should I use a timestep for collision detection? If yes, an example would help!
  4. I tried using a randomly generated angle and changed it on collision as:
    1. (vertical wall) newangle = 180-oldangle
    2. (horizontal wall) newangle = (oldangle > 180) ? 360 -(oldangle - 180) : 180-oldangle

it worked but it becomes a specialized case. How to use a generic case for all lines(since x,y axis are lines indeed)? I know it uses normals but don't know the whole thing.

The collision method has been programmed by following the below link.

Wikipedia Elastic collision in two dimensions, both balls moving

\$\endgroup\$
2
  • \$\begingroup\$ "...trying to create a simple elastic collision simulation in java." There's your first problem, right there. \$\endgroup\$
    – Krythic
    Commented Oct 25, 2016 at 17:33
  • \$\begingroup\$ @Krythic what do you mean by this? \$\endgroup\$
    – Sopel
    Commented Mar 2, 2017 at 9:35

1 Answer 1

1
\$\begingroup\$

I have found the solution, though partially.

Apparently for ball to ball collisions the tangential component remains same because no force acts along it. So normal component can be calculated using one dimension newtonian formula for elastic collisions.

There are two issues though.

  1. I had to write specialized case code for wall collisions by hard coding values.
  2. The velocity cannot be more than 2*radius per frame. If its higher than that, the ball skips collision detection and may get stuck into other ball(s).

Since this is not a full fledged application this solution will do fine for now.

I used the procedure in this link

\$\endgroup\$
2
  • 1
    \$\begingroup\$ ad 2. you may want to implement continuous collision detection. For two (nonaccelerating) balls it involves solving a quadratic equation (try deriving it yourself, it's a good exersise), and the case with the walls can be done very simply if they are axis-aligned. \$\endgroup\$
    – Sopel
    Commented Mar 2, 2017 at 9:33
  • 1
    \$\begingroup\$ Also you should implement the collision resolving without trigonometric functions, rely only on vectors. It will most likely be faster and more accurate. \$\endgroup\$
    – Sopel
    Commented Mar 2, 2017 at 9:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .