TGLTLSBFSSP: Strings

Strings

Strings are great for making realistic straps of bullets for chain guns, tails on animals, whips for torturers and bungie ropes. They are surprisingly simple to model once you understand the principle behind them.

A string is really just a whole line of points attached together with springs. The springs have a normal length of, say, one unit. If the adjacent points move futher than one unit of length apart, they experience a force towards eachother proportional to the extension of the spring that connects them. Likewise, if they move closer than one unit apart, they experience a force pushing them apart.
There are two ways to model the force on the points. With or without mass. If you are creating animations, then with mass is definately the better option. You can get the string to swing in a really realistic way. See one of the animations in the game Worms by Team17 where the worm picks up these enormous guns with swinging chains of bullets.
If you are just trying to find the optimum shape of a string hanging over a certain object, for example, then you will find it easier to work without mass.

Firstly the Without Mass option

The points on the string are moved in a rate which is proportional the the magnitude of the net force acting on it. Take each point and compare it with its two neighbours in turn. Calculate the vector to the neighbour, and its magnitude, using pythagoras of course. Calculate the extension of the spring by subtracting the normal length of the spring from the magnitude of the vector. Now the vector of the force acting on the point is:

Vector / Magnitude x Extension x (A_Small_Amount)

Sum the two vectors (one from each neighbour), add them to the co-ordinates of the point, and save it in a buffer. Do not put the new co-ordinates back into the origional information until you have worked on every point.
When you have calculated the new positions of the points, you can copy the information back over into the origional array.
Now, this small amount is quite important. It should be about .01 or so. You really want to make the string move slowly to make it more realistic. If you have a value closer to 1, then the points may move too far, and could begin oscilating violently.

Pseudo code for massless strings:

Create 4 arrays of numbers:
  String1_X (0 to 31)
  String1_Y (0 to 31)
  String2_X (0 to 31)
  String2_Y (0 to 31)

Initialise all the points in String_X() and String_Y():

  Loop i from 0 to 31
      String1_X (i) = 0
      String1_Y (i) = i
  end of loop

  Loop Forever

      Loop i from 0 to 31

          X_vector1 = String1_X(i- 1) - String1_X(i)
          Y_vector1 = String1_Y(i - 1) - String1_Y(i)
          Magnitude1 = LengthOf (X_Vector1, Y_Vector1)
          Extension1 = Magnitude1 - Normal_Length

          X_vector2 = String1_X(i + 1) - String1_X(i)
          Y_vector2 = String1_Y(i + 1) - String1_Y(i)
          Magnitude2 = LengthOf(X_Vector2, Y_Vector2)
          Extension2 = Magnitude2 - Normal_Length

          xv = (X_Vector1 / Magnitude1 * Extension1) + (X_Vector2 / Magnitude2 * Extension2)
          yv = (Y_Vector1 / Magnitude1 * Extension1) + (Y_Vector2 / Magnitude2 * Extension2) + Gravity

          String2_X(i) = String1_X(i) + (xv * .01)
          String2_Y(i) = String1_Y(i) + (yv * .01)
	  (Note you can use what ever value you like instead of .01)
	
      end of loop

      Copy all of String2_X to String1_X
      Copy all of String2_Y to String1_Y
      Draw lines between all adjacent points

end of LoopForever

Now the With Mass option

This one is very similar, but this time each point has a velocity, and the forces affect the velocity instead of the position of the point.
You will need two extra arrays of data:

and replace the lines
    .
    .
    String2_X(i) = String1_X(i) + (xv * .01)
    String2_Y(i) = String1_Y(i) + (yv * .01)
    .
    .
with
    .
    .
    Velocity_X(i) = Velocity_X(i) * Damping + (xv * .001)
    Velocity_Y(i) = Velocity_Y(i) * Damping + (yv * .001)
    String2_X(i)  = String1_X(i) + Velocity_X(i)
    String2_Y(i)  = String1_Y(i) + Velocity_Y(i)
    .
    .

Here you will probably need a much lower value of (A_Small_Amount), like .001. You wll need to make your value of Damping between about 0.95 and 0.99. Do not have it any more than 1. Damping is the energy loss from the string. If you set it to 1, then the string will never stop swinging around, and setting it to more than 1 will make the string increase its swing by itself and eventually fly off the screen.

If you make a string like this, you will notice that it is extremely flexible. Infinitely so infact. To make it stiffer, you can compare each point with its 4 or even 6 closest neighbours, instead of 2.
You could possibly make a whip kind of thing, by decreasing the string's flexibility and mass from one end to the other.