Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Calin Leafshade on Fri 08/01/2010 00:37:16

Title: [Mathematics.. again] Catenary & Rope Slack.
Post by: Calin Leafshade on Fri 08/01/2010 00:37:16
Ah another maths problem. Lucky you.

When a rope is anchored in two places it falls in a particular type of curve called a caternary (its a derivitive of a cosh curve)

If both anchor points at the same height its very easy to calculate the path of the caternary since the lowest point of the rope (the origin) will be equi-distant between the anchor points.

However if the anchor points are at different heights the origin is NOT equi-distant between the points and so its not possible to calculate the curve without first identifying where the origin is.

Any maths gurus care to help me plot that curve for the purposes of a basic rope simulator in AGS?

Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Snarky on Fri 08/01/2010 02:04:42
My advice: cheat and use a parabola.
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Joe on Fri 08/01/2010 03:13:27
If you want what I'm thinking even using parabolas it would be really difficult. What's exactly what you want? What are the known variables? and what are the unknown?

Because if the known variables are the anchor points, the problem has no clue, since you should also know another parameter like the lenght of the rope or the function which defines the rope.
Knowing the length it would be very impossible to do it since the Lenght equation is:
L=(a/2)*(e^(c/a)+e^(-c/a)-e^(b/a)-e^(-b/a))
Where a is the lowest point, b and c are the anchor points and L is the lenght. But in that equation it's impossible to work out the value of a...
And the lenght equation of the parabola is also really complicated... so I really don't know how to help you with this...
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Kweepa on Fri 08/01/2010 03:24:10
If you're doing a rope simulation, why not, err, simulate it?
You can approximate the initial position and run the simulation for a second to allow it to settle.
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Jim Reed on Fri 08/01/2010 05:17:09
I'm not very good at math, but looking at it from a logical perspective it seems simple.
The origin goes left or right from te middle distance of the poles in direct ratio of their height difference.
The height of the origin goes up and down in direct ratio of the poles distance considering the rope lenght.

Or maybe I'm wrong?
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Kweepa on Fri 08/01/2010 06:20:04
Here's an AGS 3.2 demo using verlet integration:
http://www.kweepa.com/step/ags/tech/RopeTest.zip
Included is my dev directory with a compiled game folder.
(http://www.kweepa.com/step/ags/tech/RopeTest.png)
The core is:

function noloopcheck __Rope::Update()
{
  float dt = 1.0/IntToFloat(GetGameSpeed());
 
  // verlet step
  int i = 1;
  while (i < NSEG)
  {
    float x = rps[i].x;
    float y = rps[i].y;
    rps[i].x = ((2.0 - damping)*x - (1.0 - damping)*rps[i].ox);
    // gravity
    rps[i].y = ((2.0 - damping)*y - (1.0 - damping)*rps[i].oy) + gravity*dt*dt;
    rps[i].ox = x;
    rps[i].oy = y;
    i++;
  }
 
  // satisfy constraints
  int it = 0;
  while (it < 2)
  {
    i = 0;
    while (i < NSEG)
    {
      float dx = rps[i+1].x - rps[i].x;
      float dy = rps[i+1].y - rps[i].y;
      float dlen = Maths.Sqrt(dx*dx + dy*dy);
      float df = (dlen - elen)/dlen;
      rps[i].x = rps[i].x + 0.5*df*dx;
      rps[i+1].x = rps[i+1].x - 0.5*df*dx;
      rps[i].y = rps[i].y + 0.5*df*dy;
      rps[i+1].y = rps[i+1].y - 0.5*df*dy;
      i++;
    }
    it++;
  }
 
  // snap end points
  rps[0].x = x1;
  rps[0].y = y1;
  rps[NSEG].x = x2;
  rps[NSEG].y = y2;
}


Hope this helps!
Steve
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Gilbert on Fri 08/01/2010 06:31:19
Heh neat! :D

I added the following line to the beginning of the room's rep. exec. for some nice moments:

Rope.SetStartPoint(IntToFloat(mouse.x), IntToFloat(mouse.y));


Edit:
For extra fun add also:
Rope.SetEndPoint(IntToFloat(player.x), IntToFloat(player.y));
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Kweepa on Fri 08/01/2010 06:40:08
Ah yes, I forgot to mention the rope parameters can be changed on the fly :=
This code could easily be extended to produce other loosely jointed stuff like rope ladders or rag dolls, but I leave that as an exercise for the reader.
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Igor Hardy on Fri 08/01/2010 11:04:10
This is excellent. I needed something like this for my game too. Thanks, Steve.
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Calin Leafshade on Fri 08/01/2010 12:10:27
wow, nicely done Mr McCrea.

Now you just need to add weighted points and we have full rope sim :p

Then just add another dimension and you have cloth :p

Heh AGS is awesome.
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Kweepa on Fri 08/01/2010 14:06:12
Quote from: Calin Leafshade on Fri 08/01/2010 12:10:27
Heh AGS is awesome.
It's close to ideal for prototyping a lot of things (aside from its speed and lack of dynamic containers).
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Joe on Fri 08/01/2010 15:29:07
Steve you're a machine! I'd never have managed to create that physics code. It's awseome :D
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Vince Twelve on Fri 08/01/2010 17:51:54
That's awesome Steve!  I programmed something like this for an underwater towing feature in a certain upcoming game designed by a certain red head, but yours is far more realistic!  Nice!
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Kweepa on Fri 08/01/2010 18:57:49
Quote from: Vince Twelve on Fri 08/01/2010 17:51:54
but yours is far more realistic!
And to think I contributed to your project on Kickstarter. :'(
You're welcome to take the guts of this and put them in Puzzle Bots.
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Calin Leafshade on Fri 08/01/2010 22:44:15
So now we have a fantastic rope sim I think someone should come up with an anti aliasing filter for it.

Since its a single line that should be within the realms of possibility. We can track the line and use an algorithm to choose points for pixels of varying tranparencies, thus antialiasing the line.

perhaps we could check if the rope has draw a pixel to the side and below the pixel we are checking and draw a semi transparent pixel there??

thoughts?
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: ddq on Fri 08/01/2010 23:23:45
Quote from: Calin Leafshade on Fri 08/01/2010 22:44:15thoughts?
Damn.

Seriously, you're putting a lot of thought into something and I can't wait to see what comes of it.
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Calin Leafshade on Fri 08/01/2010 23:26:08
Dude, its going to be epic... and absolutly nothing to do with rope physics

but its always good to improve your understanding of stuff like this.

I plan to capture SteveMcCrea and keep him in a cupboard for later use.
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: tzachs on Fri 08/01/2010 23:33:10
Quote from: Calin Leafshade on Fri 08/01/2010 23:26:08
I plan to capture SteveMcCrea and keep him in a cupboard for later use.
With a rope, perhaps?
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Kweepa on Fri 08/01/2010 23:36:57
My thoughts are to use standard line-antialiasing methods while drawing the line.
I'd get the bounds of the rope and create a new dynamic sprite, then go from there.
Bresenham line drawing includes enough secondary info (the fractional part of the dy) to determine the transparency of the main pixel and the neighbouring pixel.
Aha, here's some pseudo-code:
http://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
As you say, this should run at a decent speed, even for a rope that stretches across the screen.
It might be good to just convert this to a module which draws an a-a line on a drawing surface.

Oh, and thanks for the offer, but this basement is plenty comfortable.
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: oren on Sat 09/01/2010 12:22:47
you can also use the exact analytic solution of the problem:
y(x) = c3 + 1 / c1 * cosh( c1 * x + c2)

where the parameters c1, c2 and c3 are found using the rope length constraint:
L = \int\sqrt{1+y'(x)}dx
and its endpoints:
y(x1)=y1
y(x2)=y2

assuming x1=0 and y1=0, then c3=-1/c1*cosh(c2) and we ends up with the following two equations:
y2 = 1 / c1 * ( - cosh( c2 ) + cosh( c1 * x2 + x2 ) )
L = 1 / c1 * ( - sinh( c2 ) + sinh( c1 * x2 + x2 ) )
which can be solved numerically for c1 and c2 (in matlab or octave):

m-file for solving the equations set, called rope.m:

function f=rope(c,x2,y2,L)
f(1) = L  + 1 / c(1) * ( - sinh( x2 * c(1) + c(2) ) + sinh( c(2) ) );
f(2) = y2 + 1 / c(1) * ( - cosh( x2 * c(1) + c(2) ) + cosh( c(2) ) );


running the solver

% boundary and length
x2 = 1; y2 = 1; L = 5;

% initial guess
c0 = [1; 1];

% solver
c = fsolve(@(x) rope(x, x2, y2, L),c0)



now a lookup table can be calculated for all the desired x2, y2 and L values. for example:
x2 = 1.00, y2 = 1.00, L = 1.50 | c1 = 1.65, c2 = -0.022565
x2 = 1.00, y2 = 1.00, L = 2.00 | c1 = 3.83, c2 = -1.364008
x2 = 1.00, y2 = 1.00, L = 2.50 | c1 = 4.82, c2 = -1.986330
x2 = 1.00, y2 = 1.00, L = 3.00 | c1 = 5.50, c2 = -2.401198
x2 = 1.00, y2 = 1.00, L = 3.50 | c1 = 6.01, c2 = -2.712692
x2 = 1.00, y2 = 1.00, L = 4.00 | c1 = 6.43, c2 = -2.961918
x2 = 1.00, y2 = 1.00, L = 4.50 | c1 = 6.79, c2 = -3.169477
x2 = 1.00, y2 = 1.00, L = 5.00 | c1 = 7.10, c2 = -3.347194

plotting y(x) = - 1 / c1 * cosh( c2 ) + 1 / c1 * cosh( c1 * x + c2 ):

(http://www.2dadventure.com/ags/rope_plot.png)




Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Kweepa on Sat 09/01/2010 19:18:50
Wow, awesome!
Thanks for signing up to share! :D
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: TheMagician on Sun 10/01/2010 11:47:29
Wow, Steve this is unbelievable. I tried to do something like that for one of my last projects but I didn't know where to start ;)

And I have to agree: AGS is great for so many kinds of programs and games. However, speed is the big problem. Especially the DrawingSurface functions are so slow :(

But thanks again. Great piece of code!
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Kweepa on Tue 12/01/2010 08:45:06
New version of the demo with antialiased rope.
See the AntialiasedLine module thread for details.
Now can you let me out, Calin?
Title: Re: [Mathematics.. again] Catenary & Rope Slack.
Post by: Calin Leafshade on Tue 12/01/2010 23:36:11
Dude, just wait until i think of something else which entirely pointless but looks awesome.

You have truly excelled yourself this time.