0

In the famo.us physics engine, is it possible to set the magnitude of a particle's velocity without changing the x/y components? I want to be able to set the speed of a ball object independently of its interactions with other objects, in a manner akin to

ball.particle.setVelocity([1,1,0]);

but affecting magnitude of the velocity only.

I guess a more general version of the question is, can vectors be manipulated in terms of magnitude and angle, rather than in terms of x and y coordinates?

  • I'm not sure I understand your question. The velocity of a particle is a vector comprised of three components. If you want to increase/decrease the velocity without changing the angle, just multiple all components of the vector with an equal amount. – IjzerenHein Nov 02 '14 at 22:30
  • I would like to set magnitude directly to a constant value. – Dave Thomas Nov 02 '14 at 22:39
  • @ljzerenHein is correct in stating how to increase or decrease the speed on a vector, because the multiplication will increase the magnitude. It is a little more involved to maintain that constant magnitude as you can see from my answer below. – talves Nov 07 '14 at 20:17

2 Answers2

0

The angle and magnitude of a vector is calculated from the x and y and z coordinates in Famo.us.

Understanding Magnitude will help you here. Magnitude is a measure derivative of the vector calculated by using the coordinates. Magnitude is the length of the vector. You can learn about magnitude in Kahn academy. There is no way to know a vector values based just on knowing the Magnitude.

Back to what you want to accomplish using Famo.us.

Basic Explanations of Particle

A particle in Famo.us is based on it's velocity, position and force. So, we have to know the vector of the angle to set a velocity of the particle in Famo.us. There currently is not a method to be able to pass the angle and have the velocity set.

Creating an example of having a constant Magnitude in Famo.us

Working Example Code on jsBin

Setup up the original Vector

  var impulse = 0.01;
  var vector = new Vector(1,1,0);
  // Setup our maximum Magnitude to the magnitude of our vector
  var maxMagnitude = vector.norm();

Set the force to be an impulse on the particle to keep it in motion. Set our velocity to the maximum magnitude to control our constant speed.

Note: Magnitude in a Particle in Famo.us is particle.norm(). Not sure why they did not call it magnitude.

  function setForce() {
    // Apply an impulse to the current vector keep it in motion
    this.applyImpulse(this.velocity.cap(impulse));
    // set the velocity speed to be a max in units
    this.setVelocity(this.velocity.cap(maxMagnitude));
    // Return the particles transform value
    return this.getTransform();
  }

Transform from the Particle Transform

var physicsEngine = new PhysicsEngine();

var particle = new Particle({
  mass: 1,
  position: [100, 100, 0]
});

var modifier = new Modifier();
modifier.transformFrom(setForce.bind(particle));

var surface = new new ImageSurface({
  content: 'http://code.famo.us/assets/famous_logo.svg',
  size: [radius * 2, radius * 2],
  properties: {
    borderRadius: (radius * 2) + 'px'
  }
});

physicsEngine.addBody(particle);

context.add(modifier).add(surface);

//Start the particle in motion
particle.setVelocity([vector.x, vector.y, 0]);
talves
  • 13,993
  • 5
  • 40
  • 63
0

This will allow an arbitrary setting of magnitude & direction (in degrees with standard orientation).

function setMagAndDir(particle, magnitude, angle) {
  angle = angle * (Math.PI / 180);
  var xComp = magnitude * Math.cos(angle);
  var yComp = -1 * magnitude * Math.sin(angle);
  particle.setVelocity([xComp,yComp,0]);
};

The only drawback is that both have to be set at the same time. To set individually, pass one of the getters below.

function readMagnitude(particle) {
  return Math.sqrt( ((particle.getVelocity()[0]) * (particle.getVelocity()[0])) + ((particle.getVelocity()[1]) * (particle.getVelocity()[1])) );
};

function readDirection(particle) {
  var direction = Math.atan2((-1 * particle.getVelocity()[1]),particle.getVelocity()[0]);
  direction = direction * (180 / Math.PI);
  if (particle.getVelocity()[1] > 0) {
    direction = direction + 360;
  }
  return direction;
};