I'm using this article for reference. I understand handling the collision aspect, but I can't figure out how to calculate the new velocity once the ball collides with the ramp. Without it the ball just slides down the slope and stops at the bottom, with no horizontal velocity generated from the descent.

The equation mentioned is

tangentialVelocity = velocity – (velocity * normal)normal

Which I've tried as

        ball.velocityX = _magnitude - (_magnitude * _normalX) * _normalX;
        ball.velocityY = _magnitude - (_magnitude * _normalY) * _normalY;

to no avail.

Here is what I've done so far, which finds how far the ball is intersecting in the ramp and moves it outside.

        var _distance:int = FP.distance(circleWorld.x, circleWorld.y, ball.x, ball.y);
        var _penetration:int = _distance + ball.radius - worldRadius;

        if (_penetration > 0)
            var _componentX:int = circleWorld.x - ball.x;
            var _componentY:int = circleWorld.y - ball.y;

            var _normalX:Number = _componentX / _distance;
            var _normalY:Number = _componentY / _distance;

            ball.x += _normalX * _penetration;
            ball.y += _normalY * _penetration;
  • \$\begingroup\$ It doesn't seem like your link made it into your post, please fix that. \$\endgroup\$ Jan 14 '13 at 18:05
  • \$\begingroup\$ Whenever I go to edit the post things dissapear, sorry about that. wildbunny.co.uk/blog/2012/04/02/the-physics-of-rolling \$\endgroup\$
    – Ember
    Jan 14 '13 at 23:00
  • \$\begingroup\$ Are using the LibGDX engine library and a physics engine library attached to your program for the rolling ball? \$\endgroup\$ Mar 8 '13 at 5:10

It doesn't look like your code is actually tracking the ball's rotation. The rotational inertia of the ball will have a very great effect on how quickly it descends the ramp, and how long it'll keep moving after it exits the ramp.

Some ideas for further thought here: http://physics.bu.edu/~duffy/sc527_notes06/race.html

Edited to clarify: Your current simulation is modeling the ball sliding down a frictionless ramp. A real ball on a real ramp will likely not move at all without turning. You can calculate the forces on the ball using equations like those in the web page I linked to above. Once you know the torque on the ball, you can calculate how quickly it turns.

It'll roll down the ramp at approximately the same speed that it's rotating at, which is to say the distance travelled along the ramp in a given time will approximately equal the arc length that the perimeter rotates in the same time (some slippage will occur in a realistic situation).

  • 1
    \$\begingroup\$ Good answer. However, it would be helpful if you extracted some relevant content from the link and edited it in here. GameDev is a resource in itself, not just a collection of useful links. \$\endgroup\$
    – Anko
    Jan 14 '13 at 3:02
  • \$\begingroup\$ Well, I would have, but Physics 101 was so long ago...I vaguely remember calculating whether a ring or a disk of the same size would reach the bottom of an incline faster. \$\endgroup\$ Jan 14 '13 at 3:41
  • \$\begingroup\$ This is an interesting point. I obviously need to read up on some physics texts as I was under the impression that c was the speed of light, not center of mass or whatever it's representing on the mentioned page. \$\endgroup\$
    – Ember
    Jan 14 '13 at 23:36
  • \$\begingroup\$ @Ember c is just a letter, and there ain't enough of them to give every single physical and mathematical property its own, so it depends on context, in general a text shouldn't introduce a variable without explaining its purpose. As for simulating 3D rotation like this answer suggest, I think that is beyond your level, sliding physics can work just fine for a game. \$\endgroup\$ Jan 15 '13 at 15:44

tangentialVelocity = velocity – (velocity * normal)normal

That is vector maths, the * in this case means dot product, both velocity and normal are vectors.

A dot product is calculated like so:

dotp = vector1.x * vector2.x + vector1.y * vector2.y

So your code should as best I can tell be this:

dotp = ball.velocityX * _normalX + ball.velocityY * _normalY
ball.velocityX -= dotp * _normalX;
ball.velocityY -= dotp * _normalY;

And for the sake of completeness _normal must of course be length 1 and pointing in the correct direction for this to work.

  • \$\begingroup\$ I ended up having to replace the last line with velocityY += dotp * normalY for whatever reason, but it's now more or less following what the example simulation has. \$\endgroup\$
    – Ember
    Jan 14 '13 at 23:28
  • \$\begingroup\$ @Ember That depends on the direction of the normal, whether it point away or towards the blocking object. If you change the sign on the last line you should also change it on the second to last line. \$\endgroup\$ Jan 15 '13 at 15:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .