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.

# Interactive vector motion

To finish out this section, let’s try something a bit more complex and a great deal more useful. We’ll dynamically calculate an object’s acceleration according to a rule stated in Algorithm #3 — the object accelerates towards the mouse.
Diagram of mouse acceleration vector
Anytime we want to calculate a vector based on a rule or a formula, we need to compute two things: magnitude and direction. Let’s start with direction. We know the acceleration vector should point from the object’s position towards the mouse position. Let’s say the object is located at the point `(x,y)` and the mouse at `(mouseX,mouseY)`.
Diagram of dx, dy
In that diagram, we see that we can get a vector `(dx,dy)` by subtracting the object’s position from the mouse’s position.:
• `dx = mouseX - x`
• `dy = mouseY - y`
Let’s rewrite the above using `PVector` syntax. Assuming we are in the `Mover` object definition and thus have access to the object’s `PVector` position, we then have:
``````var mouse = new PVector(mouseX, mouseY);
// Look! We’re using the static sub() because we want a completely new PVector
var dir = PVector.sub(mouse, position);``````
We now have a `PVector` that points from the mover’s position all the way to the mouse. If the object were to actually accelerate using that vector, it would appear instantaneously at the mouse position. This does not make for good animation, of course, and what we want to do now is decide how quickly that object should accelerate toward the mouse.
In order to set the magnitude (whatever it may be) of our acceleration PVector, we must first ___ that direction vector. That’s right, you said it. Normalize. If we can shrink the vector down to its unit vector (of length one) then we have a vector that tells us the direction and can easily be scaled to any value. One multiplied by anything equals anything.
``````var anything = ??;
dir.normalize();
dir.mult(anything);``````
To summarize, we take the following steps:
1. Calculate a vector that points from the object to the target position (mouse)
2. Normalize that vector (reducing its length to 1)
3. Scale that vector to an appropriate value (by multiplying it by some value)
4. Assign that vector to acceleration
Here's what the program looks like, with those steps fully implemented:
You may be wondering why the circle doesn’t stop when it reaches the target. It’s important to note that the object moving has no knowledge about trying to stop at a destination; it only knows where the destination is and tries to go there as quickly as possible. Going as quickly as possible means it will inevitably overshoot the position and have to turn around, again going as quickly as possible towards the destination, overshooting it again, and so on and so forth. Stay tuned; in later sections we’ll learn how to program an object to arrive at a position (slow down on approach).
This example is remarkably close to the concept of gravitational attraction (in which the object is attracted to the mouse position). Gravitational attraction will be covered in more detail in the next section. However, one thing missing here is that the strength of gravity (magnitude of acceleration) is inversely proportional to distance. This means that the closer the object is to the mouse, the faster it accelerates.
Let’s see what this example would look like with an array of movers (rather than just one).

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?

• how to find the biggest possible direction vector compared to the current one? • You may need to clarify your question, particularly wrt "current" and "biggest". Certainly the largest magnitude of a vector that will fit on the picture canvas is
``var maxMag = (new PVector(width-1, height-1)).mag();``
• In the mouse stalker I cant continue, I dont know how to answer it, could some one help me. • OK I think I almost got it. Thank you for your patience with me. I think that what closeness is something like this.
``var closeness = (dir.mag()-???)/maxMag;``

But I'm not sure what to subtract from dir.mag()? I'm sure it's painfully obvious but I can't see it. • The hint tells you that 0 should indicate that it is the farthest away and 1 should indicate that it's right on top.

`maxMag` is a fixed value. So, the only thing that is changing in that equation (`(maxMag - dir.mag()) / maxMag)`) is `dir.mag()`. Think about how `dir.mag()` is calculated. You created the dir vector to be a new PVector that is the difference between the mouse location and the object. The closer that the object is to the mouse location, the smaller the dir vector will be. The smaller that the direction vector is, the smaller its magnitude will be.

As the magnitude of the dir vector gets smaller and smaller, you are subtracting less and less from maxMag. Therefore, the formula will yield a result that is closer and closer to 1. Conversely, as the object is further away from the mouse, the formula will yield a result that gets closer and closer to zero (as the magnitude of the dir vector gets closer and closer to the magnitude (maxMag) of the largest direction vector (maxDir)).
• I'm stuck on the last part of challenge: mouse stalker. Here is the code:

Mover.prototype.update = function() {
var mouse = new PVector(mouseX, mouseY);
var dir = PVector.sub(mouse, this.position);
var closeness = (maxMag-dir.mag())/maxMag;
dir.normalize();
dir.mult(closeness);

this.acceleration = dir;
this.velocity.limit(5);
};

When I entered dir.mult(closeness);, the ball just went to the upper left corner. How do I fix this? • I don't know what to define maxDir as. Can someone tell me what to do and why to do it? • In the challenge Mouse Stalker, I am on Step 2 and, for some reason, I cannot continue. It says that "mouse is undefined", however it use the method after where it is defined. My code looks like this:

var Mover = function() {
this.position = new PVector(width/2, height/2);
this.velocity = new PVector(0, 0);
this.acceleration = new PVector(0, 0);
};

Mover.prototype.update = function() {
var mouse = new PVector(mouseX, mouseY);
var dir = PVector.sub(mouse, this.position);
dir.normalize();
dir.mult(0.5);

this.acceleration = dir;
this.velocity.limit(5);
};

Mover.prototype.display = function() {
stroke(0);
strokeWeight(2);
fill(127);
ellipse(this.position.x, this.position.y, 48, 48);
};

var maxDir = PVector.sub(new PVector(0, 0), new PVector (width - 1, height - 1));
var maxMag = maxDir.mag ();
var dir = PVector.sub(mouse, this.position);
var closeness = ((maxMag - dir.mag()) / maxMag);

Mover.prototype.checkEdges = function() {

if (this.position.x > width) {
this.position.x = 0;
} else if (this.position.x < 0) {
this.position.x = width;
}

if (this.position.y > height) {
this.position.y = 0;
} else if (this.position.y < 0) {
this.position.y = height;
}
};

var mover = new Mover();

var draw = function() {
background(255, 255, 255);

mover.update();
mover.checkEdges();
mover.display();
}; • In the next Challenge, what is `.mag()`? • It's the magnitude of the vector. Like every vector has a magnitude and a direction. Think of the direction as an angle, and the magnitude as the third side of a triangle. The vector's first parameter would be the first side, and the vector's second parameter would be the second side. Obvious a^2 + b^2 = c^2 so you square both components of the vector, add them, then take the square root of that to find the magnitude.
• I was on step 2 of the Mouse Stalker challenge. For some reason, it wouldn't accept this code as correct:

Mover.prototype.update = function() {
var mouse = new PVector(mouseX, mouseY);
var dir = PVector.sub(mouse, this.position);
var dirMag = dir.mag();
var maxDir = new PVector(width, height);
var maxMag = maxDir.mag();
var closeness = (maxMag-dirMag)/maxMag;

But, when I commented out my variable (dirMag), and just typed dir.mag() in the variable closeness, it was accepted.
var closeness = (maxMag-dir.mag())/maxMag;

Why is this? • With help, I managed to finish the "Mouse Stalker" challenge. However, I'm having trouble understanding how the math works to make the `Mover` go faster with more closeness to the mouse cursor. • In the Mouse stalker challenge, does the `closeness` variable make the circle accelerate faster when it's closer to the mouse?
`Mover.prototype.update = function() { var mouse = new PVector(mouseX, mouseY); var dir = PVector.sub(mouse, this.position); var maxDir = new PVector(width, height); var maxMag = maxDir.mag(); var closeness = (maxMag - dir.mag())/maxMag; dir.normalize(); dir.mult(closeness); this.acceleration = dir; this.velocity.add(this.acceleration); this.velocity.limit(5); this.position.add(this.velocity);};`
{"ft_lang_label":"__label__en","ft_lang_prob":0.86574006,"math_prob":0.9190424,"size":10178,"snap":"2023-14-2023-23","text_gpt3_token_len":2409,"char_repetition_ratio":0.15942599,"word_repetition_ratio":0.06724244,"special_character_ratio":0.24543132,"punctuation_ratio":0.17105263,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.98257667,"pos_list":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],"im_url_duplicate_count":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2023-06-02T14:55:53Z\",\"WARC-Record-ID\":\"<urn:uuid:f99e9de3-c7b8-419c-ad0c-f8d7086e4c13>\",\"Content-Length\":\"685030\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:a8d937f7-13ab-4b10-b94b-7dffe37b1e32>\",\"WARC-Concurrent-To\":\"<urn:uuid:7deb6f38-daf0-4e28-9d75-7e67b871d111>\",\"WARC-IP-Address\":\"146.75.37.42\",\"WARC-Target-URI\":\"https://www.khanacademy.org/computing/computer-programming/programming-natural-simulations/programming-vectors/a/interactive-vector-motion\",\"WARC-Payload-Digest\":\"sha1:LLV5MWTULAXVQZ5CISAUPW5XLRCPVX4C\",\"WARC-Block-Digest\":\"sha1:EYCXTFPCEGE3AL3IGKKQKBGS3NTKHXAV\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2023/CC-MAIN-2023-23/CC-MAIN-2023-23_segments_1685224648695.4_warc_CC-MAIN-20230602140602-20230602170602-00490.warc.gz\"}"}