Max Distance Constraint

Posted on December 18, 2010

As a follow up post to the Distance Constraint post, we can also create a maximum distance constraint using the same solution we found in the Distance Constraint post.

The previous solution created a fixed length distance constraint which forced a pair of bodies to be a given length apart. We can simply add an if statement to make this constraint a max length constraint.

A max length constraint only specifies that the distance between the joined bodies does not exceed the given maximum. So before applying the fixed length distance constraint just check whether the bodies have separated past the maximum distance. If not, then do nothing. Simple!

1
2
3
4
5
l = (pa - pb).getMagnitude();
if (l > maxDistance) {
  // apply constraint
}
// otherwise do not apply the constraint
Found an issue with this page? suggest edit

Comments

4 responses

Programpro

Thanks a million kajillion times over!!!! I really love these constraint tutorials; so far the simplest and clearest I've seen. Very helpful, and again thank you!!


Hi William,

I would like to create a hinge joint, which restricts rotation about one arbitrary axis between two angles, which keeps rotating with the original owning body. In addition to applying a revolute joint constraint at a common point between the two bodies, I have the following:

I have tried restricting an angle joint as follows:
1) Convert the local axis of each into world coords
2) Project the difference in angle onto the axis of rotation
3) If difference is outside the angle limits, apply the constraint

AMG3DVector4 worldAxis1 = Rot1*localAxis1;
AMG3DVector4 worldAxis2 = Rot2*localAxis2;

AMG3DVector4 ta = m_pRigidBody1->orientation;
AMG3DVector4 tb = m_pRigidBody2->orientation;

AMG3DVector4 currAngleDiff = ta – tb;

AMG3DScalar dtdotaxis = currAngleDiff.dot(worldAxis1);

if(dtdotaxis>=lowerLimit && dtdotaxis<=upperLimit) {
skipConstraint = true;
return;
}

// Compute the bias factor to prevent drift
AMG3DVector4 C = ta – tb – worldAxis1*dtdotaxis;
bias = k_biasFactor / dt * C;

This however doesn't behave correctly and locks the joint when it reaches the angle limit. Has anyone implemented a hinge joint before? Any suggestions?


The key to angular limits is to use a reference angle. The reference angle should be the original angle between the two bodies when the joint is created.

refAngle = b1.angle – b2.angle;
angleDiff = b1.angle – b2.angle – joint.refAngle;

The reference angle allows the 2 body system to rotate together without it affecting the joint.

Another thing to look at is the way you represent the body angles. For example, math functions like arctan2 give an angle in the range [-pi, pi] which could cause problems at those limits (since joint will all of the sudden think its way far from being solved). Let's say your limits are 30 to 270, when the angle reaches 180 it will flip to a negative (-170 for example). This could explain the locking that you see.

William


otuliny

Pretty! This has been a really wonderful post. Many thanks for providing
these details.