Search code examples
javascripthtmlsyntaxgravityparticles

Mysterious NaN in console.log. Attempting a short physics experiment


So I have pinpointed what I believe to be the problem here. Though, I am having a hard time understanding why exactly the console.log(particles[index].x); call outputs "NaN". It should be a number. So, why isn't it? Not sure why this is down-vote worthy, can someone explain this to me?

<html>
<head>
</head>
<body>
<canvas id='c'></canvas>
<script type="text/javascript">
var width = window.innerWidth,
height = window.innerHeight,
c = document.getElementById('c'),
ctx = c.getContext('2d');
c.width = width;
c.height = height;
var center = {x:width/2, y:height/2};


var particles = [];
var totalParticles = width/50;
var size = 20;

function init(){
    for (var i = 0; i < totalParticles; i++) {
        addParticle(i);
    }
    drawParticle(center.x, center.y, 20, particles[1].c);

    setInterval(update, 40);
}

function update(){

    for (var i = 0; i < particles.length; i++) {
        applyForce(i);
    }
}

function applyForce(index){

    console.log(particles[index].x);
    var rx = Math.abs(particles[index].x - center.x);
    var ry = Math.abs(particles[index].y - center.y);

    var sign = {x:1, y:1};
    if (particles[index].x > center.x) {
        sign.x = -sign.x;
    } else {
        sign.x = sign.x;
    }

    if (particles[index].y > center.y) {
        sign.y = -sign.y;
    } else {
        sign.y = sign.y;
    }   

    //just use size for mass, center has mass 1
    var force = {
        x:(sign.x*particles[index].s)/Math.pow(rx, 2),
        y:(sign.y*particles[index].s)/Math.pow(ry, 2)
    };



    addForce(index, force);

}

function addForce(index, force){

    particles[index].v.x += force.x;
    particles[index].v.y += force.y;

    particles[index].x = particles[index].x + particles[index].v.x;
    particles[index].y = particles[index].y + particles[index].v.y;

    drawParticle(particles[index].x, particles[index].y, particles[index].s, particles[index].c);

}

function drawParticle(x,y,size,color){

    ctx.beginPath();
    ctx.arc(x, y, size, 0, Math.PI*2, true);
    ctx.closePath();
    ctx.fillStyle=color;
    ctx.fill();
}

function addParticle(index){

        size = Math.random() * size + 10;
        var y = Math.random() * height;
        var x = width - 10;
        if (index%2) {
            x = 10;
            console.log("even");
        }

        particles.push({s:size, 
                        x:x, 
                        y:y, 
                        v:(Math.random() * 2) + 4, 
                        c:'#' + (Math.random() * 0x313131 + 0xaaaaaa | 0).toString(16)});

        return;

}

init();

</script>
</body>
</html>

Solution

  • It seems that particles[index].v.x and particles[index].v.y are always undefined. So, when you sum these undefined values:

    particles[index].x = particles[index].x + particles[index].v.x;
    particles[index].y = particles[index].y + particles[index].v.y;
    

    particles[index].x and particles[index].y also become undefined.