Search code examples
javamathcollisiondot-product

Ball reflection of a wall at an angle not working


I am trying to make a ball bounce of a wall. The walls can be at any angle and the ball can hit the wall at any angle. The ball has a velocity vector. I have calculated and normalized the normal line of the wall that the ball collides with. This code below is what I use to calculate the dot product:

public float dotProduct(Vector2 v1, Vector2 v2){
    float theta1 = (float) (Math.atan(v1.getY()/v1.getX()));
    float theta2 = (float) (Math.atan(v2.getY()/v2.getX()));
    float alpha = theta1 - theta2;
    float v1Magnitude = (float) Math.sqrt(Math.pow(Math.abs(v1.getX()), 2) + Math.pow(Math.abs(v1.getY()), 2));
    float v2Magnitude = (float) Math.sqrt(Math.pow(Math.abs(v2.getX()), 2) + Math.pow(Math.abs(v2.getY()), 2));
    return (float) Math.abs((v1Magnitude * v2Magnitude * Math.cos(alpha)));
}

For some reason the ball just bounces off in some weird direction at a high speed. This is the main function that calculates the reflection velocity:

startX, startY, stopX and stopY are the co-ordinates of the wall.

   public Vector2 calculateReflection(float startX, float startY, float stopX, float stopY){
    Vector2 normal;

    normal = new Vector2(-(stopY - startY), (stopX - startX));

    normal = normalize(normal);

    float velocityDotProduct = dotProduct(velocity, normal);
    Vector2 reflectionVelocity = new Vector2(velocity.getX() - 2*velocityDotProduct*normal.getX(), 
                                             velocity.getY() - 2*velocityDotProduct*normal.getY());

    return reflectionVelocity;
}

Does anyone know what i'm doing wrong?


Solution

  • The normal vector to a wall from A(ax,ay) to E(ex,ey) should be

    -(ey - ay), ex - ax
    
    public Vector calculateReflection( Vector velocity){
        double velocityDotProduct = Vector.dotProduct(normal, velocity);
        Vector reflectionVelocity = 
           new Vector(velocity.getX() + 2*velocityDotProduct*normal.getX(),
           velocity.getY() + 2*velocityDotProduct*normal.getY());
        return reflectionVelocity;
    }
    public void normalize(){
        double d = Math.sqrt( x*x + y*y );
        x /= d;
        y /= d;
    }
    
    public static double dotProduct(Vector v1, Vector v2){
        double res = v1.getX()*v2.getX() + v1.getY()*v2.getY();
    }
    
    public class Reflect {
    private Vector normal;
    
    public Reflect(double begX, double begY, double endX, double endY ){
        normal = new Vector(-(endY - begY), endX - begX);
        normal.normalize();
        System.out.println( "normal: " + normal );
    }
    
    public Vector calculateReflection( Vector velocity){
         double velocityDotProduct = Vector.dotProduct(normal, velocity);
         Vector reflectionVelocity = 
           new Vector(velocity.getX() - 2*velocityDotProduct*normal.getX(),
               velocity.getY() - 2*velocityDotProduct*normal.getY());
         return reflectionVelocity;
    }