# Implementing tension in chain/rope pulling

I'm trying to implement the movement of a chain of segments connected to each other (gravity, mass, etc. are not involved). The chain can only be dragged by its "head" segment. Each segment is represented with 2 vectors (front and back) and has fixed length. Here's my method that adjusts the position of a segment after its previous segment was moved:

public void AdjustLocation()
{
Front = PrevSegment.Back;

Vector delta = Front - Back;
float f = SegmentSize.Width / delta.Length;

Back = Front - (delta * f);
}


So it does two things:

1. Sets the front location of a segment equal to the back location of its previous segment.
2. Moves the back location towards the new front location in a straight line maintaining the fixed length.

But the result of that approach is not realistic enough. Like here: If we pull this chain down, the rear end of it (on the left side) shouldn't move at all until this "knot" straightens out, but it follows its previous segments too much:

As I understand it, when the "head" segment is moved, it just pulls the rest with it, and there's supposed to be a tension that pulls previous segments back.

How can I implement it or make it look slightly more realistic? I've read about simple constraints that just pull objects towards each other to the middle, but I don't understand how is it supposed to work when there are many constraints. Is it necessary to implement complex physics for this?

Ok, I think I figured it out.

I've changed the structure a little bit so that every segment is represented by two nodes.

Some pesudo structure:

public class Chain
{
public List<Node> Nodes;

public void Update(float dt)...
private void Simulate(float dt)...
private void ApplyConstraints()...
}

public class Node
{
public Vector Position;
public Vector PrevPosition;

public Node PrevNode;
public Node NextNode;

public void Simulate(float dt)...
}


Correcting the position of two adjacent nodes:

public void AdjustLocation()
{
if (NextNode == null)
{
return;
}

Vector delta = Position - NextNode.Position;
float distance = delta.Length;
float restDistance = SegmentSize.Width + SegmentSpacing;

if (distance > restDistance)
{
float f = (restDistance - distance) / distance;
Vector pull = delta * f * 0.5f;

// We don't want to pull the leading node back
if (PrevNode != null)
{
Position += pull;
}

NextNode.Position -= pull;
}
}


Then it's something like:

private void ApplyConstraints()
{
int iterations = 100; // the more iterations, the more accurate the result
while (iterations-- > 0)
{
foreach (var node in Nodes)
{
}
}
}


Though even with a large number of iterations the chain was stretched when moving. So I've also implemented verlet integration, which added some inertia:

public void Simulate(float dt)
{
const float friction = 0.95f;

// Velocity verlet: x(t + dt) = 2x(t) - x(t - dt) + a * dt^2
Vector velocity = (Position - PrevPosition) * friction;
PrevPosition = Position;
Position += velocity; // there is no acceleration though, can remove dt
}


In the chain class:

public void Update(float dt)
{
Simulate(dt);
ApplyConstraints();
}

private void Simulate(float dt)
{
foreach (var node in Nodes)
{
node.Simulate(dt);
}
}


And you can change the location of a node without changing its velocity like this:

node.Position = position;
node.PrevPosition = node.Position;