Recursive AI

Joints: a chain and a spring

All onephysics recipes

Connect bodies with OnePhysics joints: a five-link chain hinged to a fixed anchor, and a box hung from a spring.

C#
using RecursiveAI.OneMath;
using RecursiveAI.OnePhysics;
using RecursiveAI.OnePhysics.Physics2D;
 
var world = new PhysicsWorld2D();
var anchor = world.AddBox(new Vector2F(0.2f, 0.2f), at: new Vector2D(0, 10), type: BodyType.Static);
 
// A chain of five links, each hinged to the one before, swinging from the anchor.
Body previous = anchor;
var links = new List<Body>();
for (int i = 0; i < 5; i++)
{
    var link = world.AddCapsule(0.15f, 0.5f, at: new Vector2D(0.5 + i, 10));   // radius, half length
    world.AddHinge(previous, link, new Vector2D(i, 10));          // the hinge point, in world coordinates
    links.Add(link);
    previous = link;
}
 
// A spring holds a box under a ceiling.
var ceiling = world.AddBox(new Vector2F(2, 0.2f), at: new Vector2D(8, 10), type: BodyType.Static);
var weight = world.AddBox(new Vector2F(0.5f, 0.5f), at: new Vector2D(8, 8));
world.AddSpring(ceiling, weight, new Vector2D(8, 10), new Vector2D(8, 8), 2f, 0.3f);   // 2 Hz, damping ratio 0.3
 
for (int step = 0; step <= 180; step++)
{
    if (step % 60 == 0)
        Console.WriteLine($"t={step / 60.0:F0}s  chain end {links[^1].Position}  weight y={weight.Position.Y:F4}");
    world.Step(1f / 60);
}
Text
t=0s  chain end (4.5, 10)  weight y=8.0000
t=1s  chain end (0.715487866429612, 5.590997472172603)  weight y=7.9398
t=2s  chain end (-4.190456279087812, 9.45277669513598)  weight y=7.9390
t=3s  chain end (-1.8731370756868273, 6.337280875071883)  weight y=7.9390

The joint one-liners

One-linerDefinitionTyped viewWhat it does
AddHinge(a, b, anchor)RevoluteJointDefHingeJointRotation about one point
AddSlider(a, b, anchor, axis)PrismaticJointDefSliderJointMotion along one axis
AddFixed(a, b, anchor)WeldJointDefFixedJointNo relative motion
AddWheel(a, b, anchor, axis)WheelJointDefWheelJointA suspension along an axis
AddDistance(a, b, pA, pB)DistanceJointDefDistanceJointA rigid rod at the current distance
AddSpring(a, b, pA, pB, hertz, damping)DistanceJointDefDistanceJointA spring at the current distance

The typed view converts to Joint. Limits, motors and springs are switched on with EnableLimit, EnableMotor and EnableSpring, and every angle, limit and motor speed is in radians.

A 2 Hz spring under gravity settles about g / (2π · 2)² ≈ 0.062 m below its rest length, which is where the box ends up. The table of names is in names and conventions.