If you're seeing this message, it means we're having trouble loading external resources on our website.

If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.

Main content

Waves

If you’re saying to yourself, “Um, this is all great and everything, but what I really want is to draw a wave onscreen,” well, then, the time has come. The thing is, we’re about 90% there. When we oscillate a single circle up and down according to the sine function, what we are doing is looking at a single point along the x-axis of a wave pattern. With a little panache and a for loop, we can place a whole bunch of these oscillating circles next to each other.
This wavy pattern could be used in the design of the body or appendages of a creature, as well as to simulate a soft surface (such as water).
Here, we’re going to encounter the same questions of amplitude (height of pattern) and period. Instead of period referring to time, however, since we’re looking at the full wave, we can talk about period as the width (in pixels) of a full wave cycle. And just as with simple oscillation, we have the option of computing the wave pattern according to a precise period or simply following the model of angular velocity.
Let’s go with the simpler case, angular velocity. We know we need to start with an angle, an angular velocity, and an amplitude:
var angle = 0;
var angleVel = 0.2;
var amplitude = 100;
Then we’re going to loop through all of the x values where we want to draw a point of the wave. Let’s say every 24 pixels for now. In that loop, we’re going to want to do three things:
  1. Calculate y location according to amplitude and sine of the angle.
  2. Draw a circle at the (x, y) location.
  3. Increment the angle according to angular velocity.
for (var x = 0; x <= width; x += 24) {
    // Calculate y according to amplitude and sine of angle
    var y = amplitude * sin(angle);
    // Draw a circle at the (x, y) location
    ellipse(x, y+height/2, 48, 48);
    // Increment the angle according to angular velocity
    angle += angleVel;
}
Let’s look at the results with different values for angleVel:
Notice how, although we’re not precisely computing the period of the wave, the higher the angular velocity, the shorter the period. It’s also worth noting that as the period becomes shorter, it becomes more and more difficult to make out the wave itself as the distance between the individual points increases. One option we have is to use beginShape() and endShape() to connect the points with a line.
The above example is static. The wave never changes, never undulates, and that's what we've been building up to. This additional step of animating the wave is a bit tricky. Your first instinct might be to say: “Hey, no problem, we’ll just let angle be a global variable and let it increment from one cycle through draw() to another.”
While it’s a nice thought, it won't work. If you look at the statically drawn wave, the righthand edge doesn’t match the lefthand; where it ends in one cycle of draw() can’t be where it starts in the next. Instead, what we need to do is have a variable dedicated entirely to tracking what value of angle the wave should start with. This angle (which we’ll call startAngle) increments with its own angular velocity.
Here it is, with the start angle incorporated. Try changing the different numbers to see what happens to the oscillating wave.

This "Natural Simulations" course is a derivative of "The Nature of Code" by Daniel Shiffman, used under a Creative Commons Attribution-NonCommercial 3.0 Unported License.

Want to join the conversation?

  • duskpin ultimate style avatar for user michelle.ngai
    Just wondering...can you make real waves with waves?
    (6 votes)
    Default Khan Academy avatar avatar for user
  • winston default style avatar for user cathyjack
    I have a basic question.
    What is the difference between var draw = function() and draw = function()?
    I really want to know, can someone help me?
    Thanks!
    (3 votes)
    Default Khan Academy avatar avatar for user
    • spunky sam blue style avatar for user Dalendrion
      You use the var keyword when you declare a variable that doesn't exist yet.
      When you don't use the var keyword, then you're using a variable that's already declared.

      So var draw declares a new variable called "draw".
      And draw simply reuses the variable called "draw" that already exists. If it doesn't exist yet, you will get an error.

      var draw is never necessary, because ProcessingJS already declares it for you.
      ... Why create a new variable when you already have one?
      (6 votes)
  • hopper jumping style avatar for user redpandamath
    I'm stuck on step two of the Many waves challenge in putting in the var name for the new wave.
    (4 votes)
    Default Khan Academy avatar avatar for user
  • starky ultimate style avatar for user Swara Patil
    I still don't get how this works, why do we increase the angle by angleVel and how is it determined? I also don't get what "angle" they are talking about. For example, in the comments for the second program the say "// Calculate the y location according to amplitude and sine of the angle." but the angle of what?
    (2 votes)
    Default Khan Academy avatar avatar for user
  • duskpin ultimate style avatar for user Grant Brinkley
    angleMode = "radians";

    var Wave = function(amplitude, period, color) {
    this.startAngle = 0;
    this.amplitude = amplitude;
    this.period = period;
    this.color = color;
    this.angleVel = (TWO_PI / this.period) * 5;
    };

    Wave.prototype.update = function() {
    this.startAngle += TWO_PI / this.period;
    };

    Wave.prototype.draw = function() {
    background(252, 252, 252);
    var angle = this.startAngle;
    fill(this.color);
    for (var x = 0; x <= width; x += 24) {
    var y = this.amplitude * sin(angle);
    ellipse(x, y, 48, 48);
    angle += this.angleVel;
    }
    };
    var wave = new Wave(200, 175, color(255, 0, 0, 100));

    translate(0, height/2);

    draw = function() {
    background(255);
    var john = new Wave( , , );
    wave.update();
    wave.draw();
    };
    how has no one in this comment section have no idea how to do the second step in Many Waves I know thousands of people have gotten this challenge done but I can't find any that have commented here, so this may just be me rambling on about the fact that I can't complete this challenge
    (2 votes)
    Default Khan Academy avatar avatar for user
    • blobby green style avatar for user Kylie N.
      You have to create a second wave. Something like this:

      var wave = new Wave(156, 175, color(255, 0, 0, 100));
      var wave2 = new Wave(215, 93, color(38, 0, 255, 100));

      translate(0, height/2);

      draw = function() {
      background(255);
      wave.update();
      wave2.update();
      wave.draw();
      wave2.draw();
      };
      (1 vote)
  • blobby green style avatar for user Haze DiTillio
    I'm having trouble with my code for the many waves challenge: I keep getting put .update before .draw, and I am. But my waves aren't moving. Please Help.
    angleMode = "radians";

    var Wave = function(amplitude, period, color) {
    this.startAngle = 0;
    this.amplitude = amplitude;
    this.period = period;
    this.color = color;
    this.angleVel = (TWO_PI / this.period) * 5;
    color= (random(255),random(255),random(255));
    };
    Wave.prototype.update = function() {


    this.startAngle += TWO_PI / this.period;


    };
    var newWave = new Wave (this.amplitude,this.period, this.color);
    var wave= new Wave(this.amplitude+20,this.period+40, this.color+40);
    Wave.prototype.draw = function() {
    background(252, 252, 252);
    var angle = this.startAngle;
    fill(this.color);
    for (var x = 0; x <= width; x += 24) {
    var y = this.amplitude * sin(angle);
    ellipse(x, y, 48, 48);
    angle += this.angleVel;



    }
    };

    //i am calling update BEFORE draw
    draw= function() {
    newWave.update();
    wave.update();
    newWave.draw(30,30,30);
    wave.draw(40,40,40);
    };
    (1 vote)
    Default Khan Academy avatar avatar for user
  • starky ultimate style avatar for user legolover1041
    I require assistance with Step One of the next challenge. Someone please help?
    (1 vote)
    Default Khan Academy avatar avatar for user
  • starky ultimate style avatar for user legolover1041
    I need help with step two of the next challenge. I have waves, but it won't let me proceed for the same reason as everybody else. I've asked for help a great many times, and nobody has gotten back to me, so please help. What am I doing wrong?
    Here's my code:

    var Wave = function(amplitude, period, color) {
    this.startAngle = 0;
    this.amplitude = amplitude;
    this.period = period;
    this.color = color;
    this.angleVel = (TWO_PI / this.period) * 5;

    };

    Wave.prototype.update = function() {
    var newWave = new Wave (this.amplitude,this.period, this.color);
    this.startAngle += TWO_PI / this.period;


    };

    Wave.prototype.draw = function() {
    background(252, 252, 252);
    var angle = this.startAngle;
    fill(this.color);
    for (var x = 0; x <= width; x += 5) {
    var y = this.amplitude * sin(angle);
    ellipse(x, y, 15, 200);
    angle += this.angleVel;
    }
    };

    var w = new Wave(156, 337, color(0, 123, 255));




    draw = function() {

    w.update();
    w.draw();

    };
    (1 vote)
    Default Khan Academy avatar avatar for user
  • blobby green style avatar for user knightkydalt
    in the next challenge the red circles disappeared, this is my code


    var wave = new Wave(198, 175, color(255, 0, 0, 100));
    var lol = new Wave(200, 239, color(36, 25, 179, 100));

    translate(0, height/2);

    draw = function() {
    background(255);
    wave.update();
    wave.draw();
    lol.update();
    lol.draw();
    };
    please help
    (1 vote)
    Default Khan Academy avatar avatar for user
  • duskpin ultimate style avatar for user LearnCat
    how do you complete step 2 (next challenge)? Here is my code:

    angleMode = "radians";

    var Wave = function(amplitude, period, color) {
    this.startAngle = 0;
    this.amplitude = amplitude;
    this.period = period;
    this.color = color;
    this.angleVel = (TWO_PI / this.period) * 5;

    };
    Wave.prototype.update = function() {
    var newWave = new Wave (this.amplitude,this.period, this.color);
    this.startAngle += TWO_PI / this.period;


    };

    Wave.prototype.draw = function() {
    background(252, 252, 252);
    var angle = this.startAngle;
    fill(this.color);
    for (var x = 0; x <= width; x += 24) {
    var y = this.amplitude * sin(angle);
    ellipse(x, y, 48, 48);
    angle += this.angleVel;


    }
    };
    (1 vote)
    Default Khan Academy avatar avatar for user