mjanisz1
mjanisz1

Reputation: 1516

Particles "run away" from mouse

Im creating a simple particle experiment on canvas. Now i want them to "run away" from mouse coursor over canvas. detecting the distance from the mouse is not a problem, but how to code their behaviour?

each particle is created as following:

    var particle = {
        x: Math.floor(Math.random() * width),
        y: Math.floor(Math.random() * height),
        xVel: Math.random() * 10 - 5,
        yVel: Math.random() * 10 - 5,
    }

so i assume i should also save the direction somehow, and if the distance from pointer is < x, reverse the direction? maybe also save old speed, and decrease it slowly while moving away?

how to detect the direction?

Upvotes: 1

Views: 2609

Answers (2)

Alex Wayne
Alex Wayne

Reputation: 187222

Velocity (xVel, yVel, together) is a 2D vector. And so is the distance between the mouse and the particles. A vector contains both direction and magnitude. So you want a vector that is the difference between the mouse position and the particle position.

var posRelativeToMouse = {
  x: particle.x - mousPosX,
  y: particle.y - mousPosY
};

So small numbers of x and y mean the the particle is close to the mouse, and big mean it's far away.

Next we need to figure out how these numbers should affect the velocity of the particle. So we need 2 things.

What direction do we push them in?

We already have this, mostly. posRelativeToMouse is a vector that has the direction we want. We just normalize it, which means to set the length of the vector to 1. To do that, we divide each component by the current length of the vector. The length of this vector is always the distance to from the particle to the mouse.

var distance = Math.sqrt(
  posRelativeToMouse.x * posRelativeToMouse.x +
  posRelativeToMouse.y * posRelativeToMouse.y
);
var forceDirection = {
  x: posRelativeToMouse.x / distance,
  y: posRelativeToMouse.y / distance,
};

How hard do we push the particles?

This is an inverse of the distance. Close means a big push, far means a little push. So lets reuse our distance we calculated above.

// distance past which the force is zero
var maxDistance = 1000;

// convert (0...maxDistance) range into a (1...0).
// Close is near 1, far is near 0
// for example:
//   250 => 0.75
//   100 => 0.9
//   10  => 0.99
var force = (maxDistance - distance) / maxDistance;

// if we went below zero, set it to zero.
if (force < 0) force = 0;

Ok we have a direction, and we have the force. All that's left is to apply this to the particle velocity.

particle.xVel += forceDirection.x * force * timeElapsedSinceLastFrame;
particle.yVel += forceDirection.y * force * timeElapsedSinceLastFrame;

And assuming you are animating your position each frame by that xVel/yVel, you should now have particles being pushed away by the mouse.

Upvotes: 2

Dmytro
Dmytro

Reputation: 5213

you can obtain a vector v by subtracting the position of particle from position of mouse,

then you can find the magnitude of this vector my taking sqrt(x^2 + y^2)

by dividing v by magnitude, you obtain a unit vector in the direction you want your particles to go.

for instance.

suppose I have 10 particles in a list U, each has an x and y field.

I can obtain it's vector from each particle v by setting v = (xpart - mousepart, ypart - mousepart)

then you need to find the magnitude vmag by taking sqrt(vx^2 + vy^2)

then you obtain vunit = (vx / vmag, vy / vmag)

This is the vector "away from the mouse".

the rest can be left to detemining speed you want to move at, and ensuring you bounce of walls and such.

I have a similar project at github open source: https://github.com/dmitrymakhnin/JavaParticleSystem/blob/master/Main.java

Upvotes: 1

Related Questions