Showing posts with label JS canvas. Show all posts
Showing posts with label JS canvas. Show all posts

Friday, November 14, 2014

Orbital Simulation

Alright, let's program up some gravity!

First we'll make two objects.  The first object ({}) is velocity which will have its own x and y variables that will be applied to the particle object's x and y variables.

Since we are creating an array of this object that will have random numbers, we loop through each item and assign it a base value.  Then loop again to assign it the random values to place particles all over the screen.

Now that we're set up, we start the timer function and apply force to each particle by calculating the force, multiplying it by the velocity, and adding it to the particle coordinate.

Our center of gravity is stationary so we didn't have to really set anything up for that but setting its coordinates as a variable means that we're doing six less calculations every time the screen refreshes.  This is a very memory intensive calculation and easily gets out of control when you increase the particleIndex so anything you can do to increase efficiency is helpful in making sure the animation is smooth and ensuring that it can be rendered with older hardware.





function drawShapes() {

var particleIndex = 1, particle = {}, velocity = {}, gravityx = w / 2, gravityy = h / 2; for (z = 0; z < particleIndex; z++) { particle[z] = { x: Math.floor(Math.random() * w), y: Math.floor(Math.random() * h), color: randomColor() }; velocity[z] = { x: Math.floor((Math.random() * 5) - 5), y: Math.floor((Math.random() * 5) - 5) }; }

setInterval(function() {


clearScreen();

for (z = 0; z < particleIndex; z++) {

var distance = Math.pow((particle[z].x - gravityx), 2) + Math.pow((particle[z].y - gravityy), 2),
f = (1 / Math.sqrt(distance));

velocity[z].x += (particle[z].x - gravityx) * f;
velocity[z].y += (particle[z].y - gravityy) * f;

particle[z].x -= velocity[z].x;
particle[z].y -= velocity[z].y;

drawCircle(gravityx, gravityy, 60, "black");
drawCircle(particle[z].x, particle[z].y, 10, particle[z].color);
}

}, 50);

}

Thursday, August 7, 2014

This Is Kind of Psychadelic

I get a lot of traffic on this blog but no comments or emails.  Feedback of any kind is welcome!  And just a reminder if you haven't seen the first post, this can all be done in the browser-based environment found here.  It's a template I have set up for the code snippets highlighted near the bottom of posts.

In the function SwirlColor we use a "shortcut", the ternary operation, for something we type out a lot, the if/else statement.  Each of the following produce the same result:

1)
if      (Math.Random() > 5)  {colR     += -1;}                        
test?       -         operation       -        var    -    change depending on result
else  {colR    += 1;}                                                              
test? -  var    -   change depending on result                                               

2)                                                                       result is -  true  :   false        
colR    +=          Math.Random() > 5     ?                            -1    :    1;          
var    -   change       -           operation       -       test?    -    change depending on operation 

This isn't applicable to a lot of situations but is a fun concept to learn.  A great place to use it is on a rotating, rectangular device where we want to have a variable to be a fraction of either the height or width, depending on orientation so that the output is the same regardless of orientation.
(ex    C_C = widthInt < heightInt ? widthInt / 10 : heightInt / 10; )

New variables in this design:
  • colR/colG/colB are holders for the rgb values (ex. rgb(100,0,255) = colR,colG,colB)
  • dcMin/Max is the change(d) in color(c) Min and Max between each layer
  • SwirlRadius is each individual circle we see, starting with the largest and layering smaller circles on top in the do loop
  • SwitchColor is used to determine if we're changing R, G, or B.  It changes at the beginning of SwirlColor()






function drawShapes() {

    c.translate(w / 2, h / 2);

    speed = 500;

    swirlRadius = h / 2;
    switchColor = 1;
    i = 1;

dcMin = 1;
dcMax = 3;

    colR = 155;
    colG = 155;
    colB = 5;

    setInterval(function() {

        do {

            swirlColor();

            c.beginPath();
            c.fillStyle = "rgb(" + colR + "," + colG + "," + colB + ")";
            c.arc(0, 0, swirlRadius, 0, Math.PI * 2, true);
            c.fill();

            swirlRadius -= Math.floor((Math.random() * 10) + 5);

        } while (swirlRadius > 10);

        i++;
        swirlRadius = h / 2;

    }, speed);

}

function swirlColor() {

    if (i > 10) {
        i = 1;
        switchColor = Math.floor((Math.random() * 2) + 1);
    }

    switch (switchColor) {
    case 1:
        colR += Math.random() > 0.5 ? dcMin : dcMax;
        if (colR > 255) colR = 1;
        if (colR < 0) colR = 255;
        break;
    case 2:
        colG += Math.random() > 0.5 ? dcMin : dcMax;
        if (colG > 255) colG = 1;
        if (colG < 0) colG = 255;
        break;
    case 3:
        colB += Math.random() > 0.5 ? dcMin : dcMax;
        if (colB > 255) colB = 1;
        if (colB < 0) colB = 255;
        break;
    }

}