Matter-js: Revolute constraint

Created on 21 Aug 2015  路  20Comments  路  Source: liabru/matter-js

It would be nice to have a way to anchor bodies at a certain point. Basically allowing objects to only rotate around a certain point and not move in any other way. I know this can partially be achieved through constraints, but those still allow the body to move in all directions.

For an example, look at the triangle in the Box2D demo on this page: http://box2d-js.sourceforge.net/index2.html

feature-request release-candidate

Most helpful comment

Yeah it does work with the mouse constraint too, I'll show an example of that!

All 20 comments

+1

+1

+1 pivot constraint

An alpha build that supports revolute constraints is now in the constraint-fixes branch:

https://github.com/liabru/matter-js/tree/constraint-fixes/build

To create a revolute (or pin constraint) just create a Matter.Constraint with length: 0 (and stiffness: 1 which is default). See the catapult example. As a bonus, this branch also completely upgrades the constraint resolver so it's far more accurate and stable than before. Note that the improvements have naturally made constraints stiffer so for soft constraints you may need to set a stiffness value roughly half of what it originally might have been.

Anyone who is interested please try it out on your use case!

I think i found a bug when using poly-decomp.js with the new constraint. When i try to join an object to a body made from poly-decomp, the constraint doesnt appear to attach at the correct location and both objects will be pulled randomly around each other.

An example of the behaviour i want with poly-decomp disabled: https://codepen.io/Bugin10/pen/YVLXrB
An example with poly-decomp: https://codepen.io/Bugin10/pen/wdjBZb
You might need to refresh a few times to see the sporadic behaviour of the poly-decomp version

Edit: seems to only occur on specific vertices, 0 and 4 in my example

Thanks for the test case, looks like maybe there's a problem with the new constraints on compound bodies. I'll look into it.

@Bugin10 it seems that the solution is to set the axel stiffness to 0.7 or less. You should also remove the density: 0.1 as this creates a huge mass difference which also breaks stability.

I think I might need to set the default for revolute constraints to be 0.7, which seems to work just fine anyway.

Is there a way to achieve this behaviour with a mouse constraint? Make an object pivot where you are clicking? So you can drag an object and it's affected by gravity?

Yeah it does work with the mouse constraint too, I'll show an example of that!

@liabru I'm using randomly generated geometry in my application with poly-decomp where I've found i need to use a lower value of 0.3 to significantly reduce the problem. With a value of 0.7 i usually get 2-3 of my 20 generated objects with issues. The new system is a massive improvement though. Even with a value of 0.3 my cars no longer act like they have suspension made from jelly :)

Pin constraints are implemented of 0.13.0, you can see how they're used in the constraints example. You can see how to apply it to the mouse constraint on these lines.

Is it just me, or is there still some give in the pin constraint, making it act like a very stiff spring? :/

@gabbah do you mean when interacting with the constrained body using a MouseConstraint? Or when other bodies are colliding with the constrained body?

@liabru Yes, when using the mouse constraint on a body.
In you chain example, the rightmost chain has the following constraints:
Composites.chain(ropeC, 0.3, 0, -0.3, 0, { stiffness: 1, length: 0 }); Composite.add(ropeC, Constraint.create({ bodyB: ropeC.bodies[0], pointB: { x: -20, y: 0 }, pointA: { x: ropeC.bodies[0].position.x, y: ropeC.bodies[0].position.y }, stiffness: 0.5 }));
So the Composites.chain should connect all the bodies with stiff constraints with length zero, meaning a pin constraint with no give at all, right? But still, if I pull at the chain using the mouse constraint, the chain seems to be connected by springs that have less than 1 in stiffness.

Another example. In my own code, I copied the example code, and instead of using stiffness 0.5 for the first body in the chain (than "hangs it up"), I used stiffness 1. What happens then?
Well, if I pull on the first body with the mouse, it works as it should, and there's no give. It actually works as a pin constraint then. BUT, if I instead pull on the middle of the chain say, then the FIRST bodies constraint suddenly is not stiff anymore! That seems like a bug to me?

There's generally room for improvement with the pin constraints, but there's a bigger issue that by using the mouse constraint like this you're creating an unsolvable system - somewhere, something has to give. So I think there likely needs to be some sort of priority system where the mouse constraint has some extra 'give' such that it will be the one to fail before pin constraints do. Do you think that will help?

It makes total sense and I thought about this as well - if all constraints are have stiffness 1, then that's unsolvable. However, as soon as one of them is not 1, then that's the one that should give in, right? Currently that's not the case. Even though my mouse constraint is lower than 1, a constraint that is 1 (between the links in the chain) give in instead. That is just a bug for the user.

The docs should just state that if you set all constraint to 1 in a system, then either the outcome is undefined, or there will be some priority given according to some rule. In general, the user should avoid doing that I think.

But in my case, of course the mouse constraint is the one that should give in.

It was also quite strange that the stiff constraint started acting like a soft spring if I pull from the middle of the chain instead. :P

I've opened an issue regarding this #623 please +1, thanks.

Great!
Does this issue solve the last point I made?
Pulling the middle of the chain, turns the first constraint (where the chain is hanging from) into a soft spring (even though stiffness is 1)?

I had these issues of springy pin joints when building a rope out of a chain of rectangles with a large object on the end.

For future reference, it is worth noting that when building chains, the bodies in your chain must have proper density set in order for the constraints holding those chains together to behave as expected. In my case, I increased the density of each rope segment (rectangle body) from the default to 0.01. It takes a very high-density mass at the end of the rope to pull the constraints apart.

Hope this helps someone else! Here's a demo.

Thanks, yes they can take some tweaking when they are under a lot of strain, see this post for some things to try if you're having these types of problem.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

TimuJiang picture TimuJiang  路  4Comments

Zhaopengyang picture Zhaopengyang  路  3Comments

jack-guy picture jack-guy  路  3Comments

maximilianberndt picture maximilianberndt  路  4Comments

ShadewEnder picture ShadewEnder  路  3Comments