# Pulling chain/rope up and updating the path of the chain

I am trying to update the path of a chain (currently being stored in my code as a array of points) by moving one end of it up. I need the start of the chain to remain fixed in its location and the end up will be moving upwards.

The chain is a series of links that are rigid and have roughly 20-30 degrees of available bend/movement between each link. The array of points is ordered so that the first entry is the point that will be moving up, and the last point is fixed.

I started by creating the chain in its default state:

I've created a method moveUp that takes in the points, how high to move the last point up to and a step for how much movement per iteration of the loop defined in the method. My logic for the method is basically:

1. Loop until the first point has reached the correct height
2. If it's the very first point, just move it up by step
3. If the distance between the previous point and next point is step then I break the loop.
4. If the distance between the previous point and the next point is greater than step*2 then I move the point to be a distance of step from the previous point
5. If the distance between the previous and next is less than step*2 then I create a circle on previous and next with a radius of step and use the intersection of these circles to find where to move the point to. (since there can be 2 intersects, I just pick the one that is closer to the original point). Once this step has ran I tell the loop to break after updating the point, since everything after that should not need to move.

Until the chain uncoils a bit on the right side, everything works: But once I go much more then this, the chain starts to "pull away" from the fixed point on the left:

How can I update my logic/method to make it so this won't pull away from the fixed point and give me a decent looking path for my chain? Here is the code below for the moveUp method (note this uses a custom programming language, so if something is not clear in the below snippet, let me know I can clarify):

private point2D[] moveUp( point2D[] original, double height, double step=0.75inch ) {
if ( original.any() ) {
int count = 0;
while( height - original.first.y >= step ) {
count++;
if ( count > 100 ) {
pln("Too many iterations...");
break;
}
bool shouldStop = false;
for( p in original, index=i ) {
point2D old = p;

if ( i=0 ) {
p = p + (0,step);
} else {
if ( !last ) {
point2D prev = original[i-1];
point2D next = original[i+1];

line2D l( prev, next );

if ( l.length() == step ) {
break;
} else if ( l.length() > step*2 ) {
l.extendP0(-step);
p = l.p0;
} else {
circle prevC( prev, 0.75inch );
circle nextC( next, 0.75inch );

var intersect = this.ins(prevC,nextC);

if ( intersect.count == 0 ) {
pln("No intersection found...".eAngry);
} else {
point2D choice = intersect.p0;
if ( intersect.count > 1 ) {
double distP0 = p.distance(choice);
double distP1 = p.distance(intersect.p1);
if ( distP1 < distP0 ) {
choice = intersect.p1;
}
}

p = choice;
shouldStop = true;
}
}
}
}

original[i] = p;
if ( shouldStop ) { break; }
}
}
}

return original;
}


If the distance between the previous point and the next point is greater than step*2 then I move the point to be a distance of step from the previous point
To fix this, don't assign to the points in original — only read positions from it, and use a separate array to return the new positions. Thus, the order in which you compute the points' updates doesn't affect the result.