Distance constraints are really nice, how about angle constraints?
That would make it possible to remove those two "diagonal constraints" from this example: http://jsbin.com/risahi/4/edit
This is definitely on my list, I'll keep this thread updated, thanks!
+1
+1
+1
+1
What are/were your thoughts on the best way to implement this @liabru? I really need this and would be willing to help.
+1
+1111111111
+1
+1
@liabru Is there any progress on this one? I need this for my project so much that I'm looking into hacking it in myself. But, I'm concerned I might not figure out how to do it in a way that conserves momentum, etc.
FWIW, here's how I implemented angular constraints for another verlet lib: https://github.com/softfab/tshirt/blob/master/src/verlet-constraint-angle-2d.js
I will bury a timecapsule with instructions for my great grandchildren on how to complete my project when angle constraints are finally added to this library in 2050
Anyone wanna help @liabru out? It's an open source library, not a paid service ;)
+1
I've come up with a solution for this that seems like a good workaround until this is implemented. For my project I wanted to limit the extended and contracted angle between the upper arm and lower arm of a character to mimic normal elbow behavior. You can check it out below in action...

In general, I think this might be a good approach and can be adapted for other scenarios.
This is the constraint setup
let testConstraint = Constraint.create({
bodyA: upperArm,
pointA: { x: 120, y: 0 },
bodyB: lowerArm,
pointB: { x: 120, y: 0 },
stiffness : 0,
length: 100
});
This gets the distance between the attachment points
let uX = 120; // This is the x offset of the constraint for the upper arm
let uY = 0; // This is the y offset of the constraint for the upper arm
let uA = upperArm.angle;
let upperX = upperArm.position.x + uX * Math.cos(uA) - uY * Math.sin(uA);
let upperY = upperArm.position.y + uX * Math.sin(uA) + uY * Math.cos(uA);
let lX = 120; // This is the x offset of the constraint for the lower arm
let lY = 0; // This is the x offset of the constraint for the lower arm
let lA = lowerArm.angle;
let lowerX = lowerArm.position.x + lX * Math.cos(lA) - lY * Math.sin(lA);
let lowerY = lowerArm.position.y + lX * Math.sin(lA) + lY * Math.cos(lA);
var xDelta = upperX - lowerX;
var yDelta = upperY - lowerY;
var distance = Math.sqrt( xDelta * xDelta + yDelta * yDelta );
if (distance > 120){
testConstraint.length = 120;
testConstraint.stiffness = 1;
} else {
testConstraint.stiffness = 0;
}
cc @AndrewBrownK @Twosies @joel-simon @davearel in case this still matter to you haha.
My use case was to implement a servo arm. What I ended up doing was to add two revolute constraints; one for the pivot point (like flukeout) and one farther out (unlike in flukeout's example, this is also a revolute constraint!). The constraint can be modified at runtime to change to which angle the dependent element should go.
const anchor = Matter.Bodies.rectangle(200, 350, 50, 50, {
density: 1,
frictionAir: 0.4,
});
const arm = Matter.Bodies.rectangle(200, 200, 10, 200, {
// in this example I don't want the anchor to rotate too much when the arm moves
density: 0.01,
frictionAir: 0.1,
});
// this constraint remains constant
const pivot = Matter.Constraint.create({
bodyA: anchor,
pointA: { x: 0, y: -50 },
bodyB: arm,
pointB: { x: 0, y: 100 },
});
const control = Matter.Constraint.create({
bodyA: anchor,
// the pointA is modified to change the point to which the arm should be fixed
pointA: { x: 0, y: -100 },
bodyB: arm,
pointB: { x: 0, y: 50 },
});
Matter.World.add(this.simulation.world, [anchor, arm, pivot, control]);
setTimeout(() => {
// change the control point later
// should use sine and cosine, this is fine for the demo
control.pointA = { x: 20, y: -100 };
}, 1000);
I think by making the pivot constraint stiffer than the control constraint, you can ensure that the rotation point is at/closer to the pivot, and by adjusting the distance between pivot and control, you can control the "angular stiffness".
I've opened PR #837 which adds angle constraints, those interested please take a look, try them out and let me know if you spot any issues or just if they work nicely for your use case.
Thanks for holding on here everyone!
(@AndrewBrownK get ready to dig up that time capsule)
Most helpful comment
This is definitely on my list, I'll keep this thread updated, thanks!