I'm using a modified version of the beachBalls example, with no friction, no air friction, and restitution of 1. When I let it run in the demo window, the balls eventually stop bouncing and come to a stop. I would expect them to keep bouncing indefinitely.
(function() {
var World = Matter.World,
Bodies = Matter.Bodies,
Composites = Matter.Composites;
Example.frictionlessBeachBalls = function(demo) {
var engine = demo.engine,
world = engine.world;
// need random initialization
var stack = Composites.stack(0, 100, 3, 1, 20, 0, function(x, y) {
return Bodies.circle(x, y, 75, { restitution: 1, friction: 0, frictionAir: 0, frictionStatic: 0 });
});
World.add(world, stack);
};
})();
I also tried setting the restitution of the world boundaries to 1 (the code below is modified from the Demo.reset, and that did not help.
World.add(world, [
Bodies.rectangle(400, -offset, 800.5 + 2 * offset, 50.5, { isStatic: true, restitution: 1 }),
Bodies.rectangle(400, 600 + offset, 800.5 + 2 * offset, 50.5, { isStatic: true, restitution: 1 }),
Bodies.rectangle(800 + offset, 300, 50.5, 600.5 + 2 * offset, { isStatic: true, restitution: 1 }),
Bodies.rectangle(-offset, 300, 50.5, 600.5 + 2 * offset, { isStatic: true, restitution: 1 })
]);
I thought this might be an approximation issue when computing the effects of collisions and set high numbers for positionIterations, velocityIterations, and constraintIterations.
demo.engine.positionIterations = 1000
demo.engine.velocityIterations = 1000
demo.engine.constraintIterations = 1000
This did not help either.
Is this loss of energy due to numerical approximation errors, or can this energy loss be explicitly controlled? At the moment beyond adjusting restitution and friction I am unable to find ways to make energy conservation perfect.
See #21. Basically the linear momentum is being converted to angular momentum on collision (because circles are approximated at the moment).
Hopefully my last post helped you resolve your issue, so closing this. Feel free to reply if you need more help.
I was trying something similar to the original poster. Just a ball bouncing on a static body.
var ball = Bodies.circle(100, 250, 50, { inertia: Infinity, restitution: 1, friction: 0, frictionAir: 0, frictionStatic: 0});
Even with inertia set to Infinity, the ball loses energy and bounces closer and closer to the ground, although interestingly never fully stopping. It seemingly bounces forever very close to the ground. Am I missing something?
How quickly does it lose energy? I realise conservation isn't exactly perfect at the moment, which is a bit of a problem, but hopefully it takes a while? Can you show a jsfiddle?
It loses it noticeably quick.
Thanks for the example. It's pretty quick indeed, I will investigate this. I expect it may be due to floating point errors but it does seem a little quick even for that.
Take a look at this jsfiddle:
https://jsfiddle.net/vd7d25pu/10/
Notice that the ball does appear to bounce forever here. The only difference is that the 'ground' rectangle's height is set to 1. I stumbled upon this accidentally.
I have the same problem with many balls (gravity turned off)
Here is my jsfiddle example: https://jsfiddle.net/vd7d25pu/11/
I considered @wmike1987 's comment above and set 1 height to borders. However balls are still losing the force and not moving forever, they stop moving after some time. Probably an energy loss is after ball collisions.
One thing I noticed: if I increase mass of the balls (and force proportionally) then it lasts longer but still not infinite.
Thanks for the test case. My guess is that at least some of the loss is due to floating point errors (it seems that even box2d has the same issue). There's an article on energy drift which suggests the same.
My suggestion is to artificially add energy (through velocity or forces) back in over time, which you may be able to do yourself using collision or tick events. But a generic solution for any situation might be difficult.
Any idea why this is happening?
https://jsfiddle.net/vd7d25pu/7/ - loses energy
https://jsfiddle.net/vd7d25pu/10/ - appears to not lose energy
Hardly any difference in the code, just the size of one of the objects.
After some testing, it seems like the radius of the circle (in my case) had an influence on how long it bounced. This is related to the mass, which I suspect is the deciding factor. My temporary workaround is to set a restitution of 1.01.
Interesting. Maybe try using Bodies.polygon with a high number of sides (like 50) to see if that helps.
I am facing the same issues. I want a very slow body (ball or rectangle does not change what I get) that bounces forever with no friction. I get a body that stops at a wall, if the initial force is very low. I've used {
inertia: Infinity,
inverseInertia: 0,
restitution: 1,
frictionStatic: 1,
frictionAir: 0,
friction: 0
}
Any suggestion?
in beforeUpdate event:
if(ball.speed != 0){
let speedMultiplier = 11.241098900509593/ball.speed // 11.241098900509593 == initial (starting) ball speed
Body.setVelocity(
ball,
{ x: ball.velocity.x*speedMultiplier, y: ball.velocity.y*speedMultiplier }
);
}
in beforeUpdate event:
if(ball.speed != 0){ let speedMultiplier = 11.241098900509593/ball.speed // 11.241098900509593 == initial (starting) ball speed Body.setVelocity( ball, { x: ball.velocity.x*speedMultiplier, y: ball.velocity.y*speedMultiplier } ); }
or afterCollision
Hi! Sorry for gravedigging.
This still seems to be an issue. I put multiple balls in a box (no friction, infinite inertia) and calculate the total kinetic energy over time. I initialize all of them by applyForce.
There are 3 major problems. 1. Energy loss over time, 2. Sticky walls, 3. reflection angle on walls not always correct (tendency towards the wall). If the E-loss would just be a small loss per collision it would be fine, but it seems to distort the collision angle as well.
In case a wall is sticky, I checked on the body.velocity x/y ratio and it was still the same (ignoring that one component was 0 since it stuck in the wall).
With the Workaround of @Menowa1709 the energy is conserved, walls are not sticky and the angle looks fine.
Here is a fiddle where the fix can be switched on/off on line 77
https://jsfiddle.net/dediggefedde/3n6whja5/22/
The problem of the workaround is ignoring inertia and friction if it is switched on.
also momentum transfer based on mass is not working.
(In my code I made a small error setting all speeds to the first ones, but even splitting them does not fix this. One would need to calculate the e-transfer by hand)
This looks like it's still an issue, so I'm posting up what I found.
The momentum loss is quite significant. I can't just increase the bounce above 1, because then it will eventually gain too much energy. (Without CCD, the bouncing element will just fly out of the scene.)
Based on previous conversations, I tried two things to fix this problem.
You should check the
slopproperty.
https://github.com/liabru/matter-js/issues/862#issuecomment-635012278
I didn't even know that setting existed. 😄
The initial value is 0.05. I set it to 0. I didn't notice a difference.
Setting the Inertia to Infinity was another suggestion.
Here there's also energy being converted to torque, so try also setting the ball's
inertiatoinfinityso the ball can not rotate, for me it then bounces for much longer - is this what you need?
https://github.com/liabru/matter-js/issues/21#issuecomment-42775549
This didn't solve the problem, but it did change the results. The bouncing element will still lose momentum quickly, but not totally. When the distance between the two colliding elements is really close, the bouncing element no longer seems to lose momentum. That's not much new information, but that seemed like really strange behavior to me. Maybe that helps to track down this problem.

Here's some HTML to quickly test this problem...
(It's a slightly modified version of the "Getting Started" Tutorial.)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bounce Test</title>
<script src="matter.min.js"></script>
</head>
<body>
<div style="width:100%; height: 100%;">
</div>
<script>
// module aliases
var Engine = Matter.Engine,
Render = Matter.Render,
World = Matter.World,
Bodies = Matter.Bodies;
// create an engine
var engine = Engine.create();
// create a renderer
var render = Render.create({
element: document.body,
engine: engine
});
// create two boxes and a ground
var circle = Bodies.circle(400, 200, 80, { restitution: 1, friction: 0, frictionAir: 0, frictionStatic: 0 });
var square = Bodies.rectangle(200, 200, 40, 40, { restitution: 1, friction: 0, frictionAir: 0, frictionStatic: 0 });
var polygon = Bodies.polygon(600, 200, 1000, 80, { restitution: 1, friction: 0, frictionAir: 0, frictionStatic: 0 })
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true, restitution: 1, friction: 0, frictionAir: 0, frictionStatic: 0 });
// add all of the bodies to the world
World.add(engine.world, [circle, square, polygon, ground]);
// run the engine
Engine.run(engine);
// run the renderer
Render.run(render);
</script>
</body>
</html>
I saw the 0.15.0 update, and I thought that I saw this issue listed as closed, so I decided to test this issue once again. It seems that the problem still exists.
Through some experimentation, I realized that squares don't bounce indefinitely. They don't bounce very well at all actually. Also, liabru made an interesting suggestion...
Maybe try using Bodies.polygon with a high number of sides (like 50) to see if that helps.
That's why I looked more closely at the circle body.

It doesn't look like a circle. It looks like a 26-sided polygon. So, I added a 1000 sided polygon next to the circle. Surprisingly, the 1000-sided polygon bounces similarly. I thought it might be better at preserving energy. It is, but only towards the end. While the circle eventually stops, the polygon keeps bouncing — in a similar manner to the previous animated GIF.