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.

## Computer programming

### Course: Computer programming>Unit 5

Lesson 7: Oscillations

# Oscillation with angular velocity

An understanding of the concepts of oscillation, amplitude, and frequency/period is often required in the course of simulating real-world behaviors. However, there is a slightly easier way to rewrite the above example with the same result. Let’s take one more look at our oscillation formula:
``var x = amplitude * sin(TWO_PI * frameCount / period);``
And let’s rewrite it a slightly different way:
``var x = amplitude * sin(some value that increments slowly);``
If we care about precisely defining the period of oscillation in terms of frames of animation, we might need the formula the way we first wrote it, but we can just as easily rewrite our example using the concept of angular velocity (and acceleration) from the Angular Motion lesson. Assuming:
``````var angle = 0;
var aVelocity = 0.03;``````
...in `draw()`, we can simply say:
``````angle += aVelocity;
var x = amplitude * sin(angle);``````
...where `angle` is our “some value that increments slowly.”
Here's our modified program:
Just because we’re not referencing it directly doesn’t mean that we’ve eliminated the concept of period. After all, the greater the angular velocity, the faster the circle will oscillate (therefore lowering the period). In fact, the number of times it takes to add up the angular velocity to get to `TWO_PI` is the period or:
period = TWO_PI / angular velocity
Let’s expand this example a bit more and create an `Oscillator` object. And let’s assume we want the oscillation to happen along both the x-axis (as above) and the y-axis. To do this, we’ll need two angles, two angular velocities, and two amplitudes (one for each axis). Another perfect opportunity for `PVector`!
Read through the code in the program below:

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?

• The third step of "Challenge: Spaceship ride" says:
"Spin the ships!
Okay, now let's really give them a ride - calculate the angular acceleration based on how far away each ship is from the center, and rotate just the ship based on that. That means that your ship will need to keep track of its angular velocity and current angle, and each call to oscillate() will add to those values based on the angular acceleration that you calculate."

Can I get a bigger hint about what that angular acceleration formula is supposed to look like? • On Step 3 of the next challenge, where do you put the constrain function? Here is my code so far:

var Spaceship = function() {
this.angle = new PVector();
this.velocity = new PVector(random(-0.02, 0.22), random(-0.04, 0.13));
this.amplitude = new PVector(random(20, width/2), random(20, width/2));
this.position = new PVector(0, 0);
this.aAccel = 0;
this.aVel = 0;
};

Spaceship.prototype.oscillate = function() {
this.position.set(
sin(this.angle.x) * this.amplitude.x,
sin(this.angle.y) * this.amplitude.y
);
// Calculate the angular acceleration, based on distance
var acceleration = dist(this.position.x, this.position.y, 0, 0);
var acceleration = constrain(this.aVel, 0.5, 1.5);
// to a realistic amount
this.aAccel += acceleration / 10000;
this.aVel += this.aAccel;
};

Spaceship.prototype.display = function() {
pushMatrix();
translate(width/2, height/2);
stroke(181, 63, 0);
strokeWeight(9);
line(0, 0, this.position.x, this.position.y);
imageMode(CENTER);
translate(this.position.x, this.position.y);
rotate(this.aVel);
image(getImage("space/octopus"),
0, 0, 80, 100);
popMatrix();

};

var ships = [];
for (var i = 0; i < 10; i++) {
ships.push(new Spaceship());
}

draw = function() {
background(174, 218, 232);
for (var i = 0; i < ships.length; i++) {
ships[i].oscillate();
ships[i].display();
}
}; • Here's a code dump for final code:

var Spaceship = function() {
this.angle = new PVector();
this.velocity = new PVector(random(-0.02, 0.02), random(-0.02, 0.02));
this.amplitude = new PVector(random(20, width/2), random(20, width/2));
this.position = new PVector(0, 0);
this.aAngle = 0;
this.aVelocity = 0;

};

Spaceship.prototype.oscillate = function() {
this.position.set(
sin(this.angle.x) * this.amplitude.x,
sin(this.angle.y) * this.amplitude.y);
var s = dist(this.position.x, this.position.y, 0, 0);

this.aAngle += s /10000;
this.aAngle = constrain(this.aAngle, -0.1, 0.1);
this.aVelocity += this.aAngle;

};

Spaceship.prototype.display = function() {
pushMatrix();
translate(width/2, height/2);
stroke(181, 63, 0);
strokeWeight(9);
line(0, 0, this.position.x, this.position.y);
translate(this.position.x, this.position.y);
imageMode(CENTER);

rotate(this.aVelocity);
image(getImage("space/octopus"),
0, 0,
80, 100);
popMatrix();
};

var ships = [];
for (var i = 0; i < 10; i++) {
ships.push(new Spaceship());
}

draw = function() {
background(174, 218, 232);
for (var i = 0; i < ships.length; i++) {
ships[i].oscillate();
ships[i].display();
}
};

//Note that my aAngle, and aVelocity might be mixed around or not, I got kindve confused on this one. but I hope I can help people pass the constrain part. • Why does KA get us to do challenges yet they haven't taught us how to do it yet? • In the step 3 of next challenge, I didn't get why it should be `dist(this.position.x, this.position.y, 0, 0)` instead of `dist(this.position.x, this.position.y, width/2, height/2)` as distance should be measured from the center? • I've always wondered this but never got the answer: What in programs is " this. " ?
Like for example: this.angle • The "Challenge: Spaceship Ride" has me stumped. My code lets the ships rotate, but the grader won't let me pass. I've seen lots of people say, "Use dist(this.position.x, this.position.y, 0, 0)/10000;" but if I do that, the orange words say, "Can you divide it by a bigger number to make it more realistic?" and won't go away until I change the second 0 in dist(); to a 1. Adding "/10000" makes no difference. Here's my code:

var Spaceship = function() {
this.angle = new PVector();
this.velocity = new PVector(random(-0.02, 0.22), random(-0.04, 0.13));
this.amplitude = new PVector(random(20, width/2), random(20, width/2));
this.position = new PVector(0, 0);
this.ro = 0;
this.rot = 0;
};

Spaceship.prototype.oscillate = function() {
this.position.set(
sin(this.angle.x) * this.amplitude.x,
sin(this.angle.y) * this.amplitude.y);
// Calculate the angular acceleration, based on distance
var acceleration = dist(this.position.x, this.position.y, 1, 0);
// to a realistic amount
this.ro += acceleration / 3;
this.rot += this.ro;
};

Spaceship.prototype.display = function() {
pushMatrix();
translate(width/2, height/2);
stroke(181, 63, 0);
strokeWeight(9);
line(0, 0, this.position.x, this.position.y);
imageMode(CENTER);
translate(this.position.x, this.position.y);
//(I placed "this.rot" inside rotate();--before, there was "PI")
rotate(this.rot);
image(getImage("space/octopus"),
0, 0, 80, 100);

popMatrix();

};

var ships = [];
for (var i = 0; i < 10; i++) {
ships.push(new Spaceship());
}

draw = function() {
background(174, 218, 232);
for (var i = 0; i < ships.length; i++) {
ships[i].oscillate();
ships[i].display();
}
}; • I noticed in the above code this line
`this.angle = new PVector();`
What does not adding any parameters to `PVector` do?  `Spaceship.prototype.display = function() { pushMatrix(); translate(width/2, height/2); stroke(181, 63, 0); strokeWeight(9); line(0, 0, this.position.x, this.position.y); imageMode(CENTER); translate(this.position.x, this.position.y); rotate(PI); image(getImage("space/octopus"), this.position.x, this.position.y, 80, 100); popMatrix();};` 