7

I'm using PhysicsJS to make a 2D roulette ball spinning animation.

So far, I've implemented the following:

  • used a constraint so that the ball wouldn't "fly away":
    rigidConstraints.distanceConstraint( wheel, ball, 1 );
  • used drag to slow down the ball:
    world.add(Physics.integrator('verlet', { drag: 0.9 }));
  • made the wheel attract the ball, so that it would fall towards it when the drag has slowed down the ball enough

My questions:

  1. how do I gradually slow down the ball spinning?
    I have already a very high drag value, but it doesn't look like it's doing anything
  2. how do I make attraction towards the wheel work?
    The distance constraint should keep the ball from escaping, not from getting closer to the wheel.
  3. why does angularVelocity: -0.005 not work at all on the wheel?

My code, also on JSfiddle

Physics(function (world) {
    var viewWidth = window.innerWidth
        ,viewHeight = window.innerHeight
        ,renderer
        ;

    world.add(Physics.integrator('verlet', {
        drag: 0.9
    }));

    var rigidConstraints = Physics.behavior('verlet-constraints', {
        iterations: 10
    });

    // create a renderer
    renderer = Physics.renderer('canvas', {
        el: 'viewport'
        ,width: viewWidth
        ,height: viewHeight
    });

    // add the renderer
    world.add(renderer);
    // render on each step
    world.on('step', function () {
        world.render();
    });

    // create some bodies
    var ball = Physics.body('circle', {
        x: viewWidth / 2
        ,y: viewHeight / 2 - 300
        ,vx: -0.05
        ,mass: 0.1
        ,radius: 10
        ,cof: 0.99
        ,styles: {
            fillStyle: '#cb4b16'
            ,angleIndicator: '#72240d'
        }
    })

    var wheel = Physics.body('circle', {
        x: viewWidth / 2
        ,y: viewHeight / 2
        ,angularVelocity: -0.005
        ,radius: 100
        ,mass: 100
        ,restitution: 0.35
        // ,cof: 0.99
        ,styles: {
            fillStyle: '#6c71c4'
            ,angleIndicator: '#3b3e6b'
        }
        ,treatment: "static"
    });

    world.add(ball);
    world.add(wheel);

    rigidConstraints.distanceConstraint( wheel, ball, 1 );

    world.add( rigidConstraints );

    // add things to the world
    world.add([
        Physics.behavior('interactive', { el: renderer.el })
        ,Physics.behavior('newtonian', { strength: 5 })
        ,Physics.behavior('body-impulse-response')
        ,Physics.behavior('body-collision-detection')
        ,Physics.behavior('sweep-prune')
    ]);

    // subscribe to ticker to advance the simulation
    Physics.util.ticker.on(function( time ) {
        world.step( time );
    });

    // start the ticker
    Physics.util.ticker.start();
});
Razor
  • 27,418
  • 8
  • 53
  • 76
  • 1
    This question appears to be off-topic because it is about physics. – duffymo Jun 27 '14 at 16:28
  • 3
    @duffymo It's about programming physics, using a well known JS library. Game makers do this all the time and there are many SO questions for it. – mikemaccana Jun 29 '14 at 19:15
  • 1
    @mikemaccana before my edit, it could have perhaps been mistaken for a physics question. The wording should be clearer now. – Razor Jun 29 '14 at 19:20
  • you can misuse a well known JS library b/c you don't understand the physics. i think this is one of those cases. – duffymo Jun 29 '14 at 22:03
  • @duffymo If you check my code, you will see for example that an angular velocity is given as option but is ignored. I am not sure why you would link that, or the other issues, to a lack of understanding of the physics - this is very obviously a code issue. – Razor Jun 29 '14 at 22:19
  • like i said, i consider it a serious lack of understanding of physics. i see nothing to convince me otherwise. – duffymo Jun 29 '14 at 23:01

1 Answers1

4
  1. Drag has a bug in that version of PhysicsJS, try using the most updated version from github. https://github.com/wellcaffeinated/PhysicsJS/issues/94

  2. Unfortunately the distance constraint imposes a fixed distance. So to prevent the ball's escape in that way, you'd need to implement your own behavior. (more below)

  3. You'll have to change behavior: "static" to be behavior: "kinematic". Static bodies don't ever move on their own.

To create a custom behavior check out the documentation here: https://github.com/wellcaffeinated/PhysicsJS/wiki/Behaviors#creating-a-custom-behavior

In order to get the functionality you're describing, you'll need to do something like this:

// in the behave method
// calculate the displacement of the ball from the wheel... something like....
disp.clone( wheel.state.pos ).vsub( ball.state.pos );
// if it's greater than max distance, then move it back inside the max radius
if ( disp.norm() > maxDist ){
    var moveBy = disp.norm() - maxDist;
    disp.normalize(); // unit vector towards the wheel
    disp.mult( moveBy );
    ball.state.pos.vadd( disp ); // move it back inside the max radius
}

Of course, this is a "just get it done" way of doing this but it should work.

Jasper
  • 1,193
  • 1
  • 9
  • 14
  • This answers 90% of my question - the only thing missing is `disp`, which should be something like `var disp = Physics.vector();` (or a scratch). Thanks for the answer and the library! – Razor Jul 02 '14 at 10:16
  • Exactly. You can either create a vector (and reuse) or use the scratchpad functionality – Jasper Jul 08 '14 at 18:54