function update_particle() {

        //Loops through all of the particles in the array
        for (i = 0; i < particles.length; i++) {

            //Sets this variable to the current particle so we can refer to the particle easier.
            var p = particles[i];

            //If the particle's X and Y coordinates are within the bounds of the canvas...
            if (p.x >= 0 && p.x < canvas_width && p.y >= 0 && p.y < canvas_height) {

                /*
                These lines divide the X and Y values by the size of each cell. This number is
                then parsed to a whole number to determine which grid cell the particle is above.
                */
                var col = parseInt(p.x / resolution);
                var row = parseInt(p.y / resolution);

                //Same as above, store reference to cell
                var cell_data = vec_cells[col][row];
                
                /*
                These values are percentages. They represent the percentage of the distance across
                the cell (for each axis) that the particle is positioned. To give an example, if 
                the particle is directly in the center of the cell, these values would both be "0.5"

                The modulus operator (%) is used to get the remainder from dividing the particle's 
                coordinates by the resolution value. This number can only be smaller than the 
                resolution, so we divide it by the resolution to get the percentage.
                */
                var ax = (p.x % resolution) / resolution;
                var ay = (p.y % resolution) / resolution;
                
                /*
                These lines subtract the decimal from 1 to reverse it (e.g. 100% - 75% = 25%), multiply 
                that value by the cell's velocity, and then by 0.05 to greatly reduce the overall change in velocity 
                per frame (this slows down the movement). Then they add that value to the particle's velocity
                in each axis. This is done so that the change in velocity is incrementally made as the
                particle reaches the end of it's path across the cell.
                */
                p.xv += (1 - ax) * cell_data.xv * 0.05;
                p.yv += (1 - ay) * cell_data.yv * 0.05;
                
                /*
                These next four lines are are pretty much the same, except the neighboring cell's 
                velocities are being used to affect the particle's movement. If you were to comment
                them out, the particles would begin grouping at the boundary between cells because
                the neighboring cells wouldn't be able to pull the particle into their boundaries.
                */
                p.xv += ax * cell_data.right.xv * 0.05;
                p.yv += ax * cell_data.right.yv * 0.05;
                
                p.xv += ay * cell_data.down.xv * 0.05;
                p.yv += ay * cell_data.down.yv * 0.05;
                
                //This adds the calculated velocity to the position coordinates of the particle.
                p.x += p.xv;
                p.y += p.yv;
                
                //For each axis, this gets the distance between the old position of the particle and it's new position.
                var dx = p.px - p.x;
                var dy = p.py - p.y;

                //Using the Pythagorean theorum (A^2 + B^2 = C^2), this determines the distance the particle travelled.
                var dist = Math.sqrt(dx * dx + dy * dy);
                
                //This line generates a random value between 0 and 0.5
                var limit = Math.random() * 0.5;
                
                //If the distance the particle has travelled this frame is greater than the random value...
                if (dist > limit) {
                    ctx.lineWidth = 1;
                    ctx.beginPath(); //Begin a new path on the canvas
                    ctx.moveTo(p.x, p.y); //Move the drawing cursor to the starting point
                    ctx.lineTo(p.px, p.py); //Describe a line from the particle's old coordinates to the new ones
                    ctx.stroke(); //Draw the path to the canvas
                }else{
                    //If the particle hasn't moved further than the random limit...

                    ctx.beginPath();
                    ctx.moveTo(p.x, p.y);

                    /*
                    Describe a line from the particle's current coordinates to those same coordinates 
                    plus the random value. This is what creates the shimmering effect while the particles
                    aren't moving.
                    */
                    ctx.lineTo(p.x + limit, p.y + limit);

                    ctx.stroke();
                }
                
                //This updates the previous X and Y coordinates of the particle to the new ones for the next loop.
                p.px = p.x;
                p.py = p.y;
            }
            else {
                //If the particle's X and Y coordinates are outside the bounds of the canvas...

                //Place the particle at a random location on the canvas
                p.x = p.px = Math.random() * canvas_width;
                p.y = p.py = Math.random() * canvas_height;

                //Set the particles velocity to zero.
                p.xv = 0;
                p.yv = 0;
            }
            
            //These lines divide the particle's velocity in half everytime it loops, slowing them over time.
            p.xv *= 0.5;
            p.yv *= 0.5;
        }
    }
/*
    This function updates the position of the particles according to the velocity
    of the cells underneath, and also draws them to the canvas.
    */
This function updates the position of the particles according to the velocity
of the cells underneath, and also draws them to the canvas.
This function updates the position of the particles according to the velocity of the cells underneath and also draws them to the canvas .
function update_particle() {
        for (i = 0; i < particles.length; i++) {
            var p = particles[i];
            if (p.x >= 0 && p.x < canvas_width && p.y >= 0 && p.y < canvas_height) {
                var col = parseInt(p.x / resolution);
                var row = parseInt(p.y / resolution);
                var cell_data = vec_cells[col][row];
                var ax = (p.x % resolution) / resolution;
                var ay = (p.y % resolution) / resolution;
                p.xv += (1 - ax) * cell_data.xv * 0.05;
                p.yv += (1 - ay) * cell_data.yv * 0.05;
                p.xv += ax * cell_data.right.xv * 0.05;
                p.yv += ax * cell_data.right.yv * 0.05;
                p.xv += ay * cell_data.down.xv * 0.05;
                p.yv += ay * cell_data.down.yv * 0.05;
                p.x += p.xv;
                p.y += p.yv;
                var dx = p.px - p.x;
                var dy = p.py - p.y;
                var dist = Math.sqrt(dx * dx + dy * dy);
                var limit = Math.random() * 0.5;
                if (dist > limit) {
                    ctx.lineWidth = 1;
                    ctx.beginPath(); 
                    ctx.moveTo(p.x, p.y); 
                    ctx.lineTo(p.px, p.py); 
                    ctx.stroke(); 
                }else{
                    ctx.beginPath();
                    ctx.moveTo(p.x, p.y);
                    ctx.lineTo(p.x + limit, p.y + limit);
                    ctx.stroke();
                }
                p.px = p.x;
                p.py = p.y;
            }
            else {
                p.x = p.px = Math.random() * canvas_width;
                p.y = p.py = Math.random() * canvas_height;
                p.xv = 0;
                p.yv = 0;
            }
            p.xv *= 0.5;
            p.yv *= 0.5;
        }
    }
function update_particle ( ) { for ( i = 0 ; i < particles . length ; i ++ ) { var p = particles [ i ] ; if ( p . x >= 0 && p . x < canvas_width && p . y >= 0 && p . y < canvas_height ) { var col = parseInt ( p . x / resolution ) ; var row = parseInt ( p . y / resolution ) ; var cell_data = vec_cells [ col ] [ row ] ; var ax = ( p . x % resolution ) / resolution ; var ay = ( p . y % resolution ) / resolution ; p . xv += ( 1 - ax ) * cell_data . xv * 0.05 ; p . yv += ( 1 - ay ) * cell_data . yv * 0.05 ; p . xv += ax * cell_data . right . xv * 0.05 ; p . yv += ax * cell_data . right . yv * 0.05 ; p . xv += ay * cell_data . down . xv * 0.05 ; p . yv += ay * cell_data . down . yv * 0.05 ; p . x += p . xv ; p . y += p . yv ; var dx = p . px - p . x ; var dy = p . py - p . y ; var dist = Math . sqrt ( dx * dx + dy * dy ) ; var limit = Math . random ( ) * 0.5 ; if ( dist > limit ) { ctx . lineWidth = 1 ; ctx . beginPath ( ) ; ctx . moveTo ( p . x , p . y ) ; ctx . lineTo ( p . px , p . py ) ; ctx . stroke ( ) ; } else { ctx . beginPath ( ) ; ctx . moveTo ( p . x , p . y ) ; ctx . lineTo ( p . x + limit , p . y + limit ) ; ctx . stroke ( ) ; } p . px = p . x ; p . py = p . y ; } else { p . x = p . px = Math . random ( ) * canvas_width ; p . y = p . py = Math . random ( ) * canvas_height ; p . xv = 0 ; p . yv = 0 ; } p . xv *= 0.5 ; p . yv *= 0.5 ; } }
This function updates the position of the particles according to the velocity
of the cells underneath, and also draws them to the canvas.
This function updates the position of the particles according to the velocity of the cells underneath and also draws them to the canvas .
//Loops through all of the particles in the array //Sets this variable to the current particle so we can refer to the particle easier. //If the particle's X and Y coordinates are within the bounds of the canvas... /*
                These lines divide the X and Y values by the size of each cell. This number is
                then parsed to a whole number to determine which grid cell the particle is above.
                */ //Same as above, store reference to cell /*
                These values are percentages. They represent the percentage of the distance across
                the cell (for each axis) that the particle is positioned. To give an example, if 
                the particle is directly in the center of the cell, these values would both be "0.5"

                The modulus operator (%) is used to get the remainder from dividing the particle's 
                coordinates by the resolution value. This number can only be smaller than the 
                resolution, so we divide it by the resolution to get the percentage.
                */ /*
                These lines subtract the decimal from 1 to reverse it (e.g. 100% - 75% = 25%), multiply 
                that value by the cell's velocity, and then by 0.05 to greatly reduce the overall change in velocity 
                per frame (this slows down the movement). Then they add that value to the particle's velocity
                in each axis. This is done so that the change in velocity is incrementally made as the
                particle reaches the end of it's path across the cell.
                */ /*
                These next four lines are are pretty much the same, except the neighboring cell's 
                velocities are being used to affect the particle's movement. If you were to comment
                them out, the particles would begin grouping at the boundary between cells because
                the neighboring cells wouldn't be able to pull the particle into their boundaries.
                */ //This adds the calculated velocity to the position coordinates of the particle. //For each axis, this gets the distance between the old position of the particle and it's new position. //Using the Pythagorean theorum (A^2 + B^2 = C^2), this determines the distance the particle travelled. //This line generates a random value between 0 and 0.5 //If the distance the particle has travelled this frame is greater than the random value... //Begin a new path on the canvas //Move the drawing cursor to the starting point //Describe a line from the particle's old coordinates to the new ones //Draw the path to the canvas //If the particle hasn't moved further than the random limit... /*
                    Describe a line from the particle's current coordinates to those same coordinates 
                    plus the random value. This is what creates the shimmering effect while the particles
                    aren't moving.
                    */ //This updates the previous X and Y coordinates of the particle to the new ones for the next loop. //If the particle's X and Y coordinates are outside the bounds of the canvas... //Place the particle at a random location on the canvas //Set the particles velocity to zero. //These lines divide the particle's velocity in half everytime it loops, slowing them over time.