Search code examples
javascriptclassmathvectorphysics

Why am I getting NaN when executing a method within my class, but not when executing in isolation?


I am trying to follow along with an 'Autonomous Steering Behavior' lesson as presented by Daniel Shiffman from the Coding Train. See Video Tutorials Here

These lessons are presented using the P5.js library, however I want to follow along using pure JavaScript.

I have created my own vector class, as well as a vehicle class that represents an object being controlled by forces.

When I run the vector class methods in isolation the add and subtract methods work as expected. However, when I try to execute this.velocity.add(desiredVelocity) in the vehicle class, the velocity vector returns 'NaN'

The code run in isolation (working as expected) is

let v1 = new Vector(10, 10)
let v2 = new Vector(20, 30)
console.log(v1.add(v2)) // Outputs Vector(30, 40)

What have I overlooked or am not aware of that is causing this.velocity.add(desiredVelocity) to return NaN?

class Vector{
    constructor(x, y){
        this.x = x == undefined ? 0 : x, 
        this.y = y == undefined ? 0 : y
    }

    magnitude(){
        return Math.sqrt(this.x * this.x + this.y * this.y); 
    }

    setMagnitude(newMagnitude){
        this.x = this.x * newMagnitude / this.magnitude();
        this.y = this.y * newMagnitude / this.magnitude();
        return new Vector(this.x, this.y);
    }
    
    add(vector){
        this.x += vector.x;
        this.y += vector.y;
        return new Vector(this.x, this.y)
    }

    static subtract(vector1, vector2){
        return new Vector(vector1.x - vector2.x, vector1.y - vector2.y);
    }
}



class Vehicle {
    constructor(){
        this.position = new Vector();
        this.velocity = new Vector();
        this.maxSpeed = 10;
    }

    seek(target) {
        let desiredVelocity = Vector.subtract(target.position, this.position);
        desiredVelocity.setMagnitude(this.maxSpeed);
        this.velocity.add(desiredVelocity)
        console.log('new velocity', this.velocity) // Returns NaN
    }

}

class Target{
    constructor(){
        this.position = new Vector();
    }
}


const vehicle = new Vehicle();
const target = new Target()
vehicle.seek(target)


Solution

  • In Vector#setMagnitude you are dividing by the value that Vector#magnitude returns, which can be 0. And when newMagnitude is also 0 you get 0 / 0 which results in NaN.