Verlet rope wraping around a point help

E1bddb31000e459fb3ee5593fe067486
0
paul0n0n 101 Jul 09, 2009 at 12:48

I have a rope/rubber band and I want to make it drape over a point, well multiple points actually. Now this is all in 2d for simplicity and speed in what I’m trying to achieve. Essentially I don’t know were to start in draping. Thank you in advance.

3 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jul 09, 2009 at 14:42

If you are doing Verlet integration as the title suggests, this should be pretty easy. First of all, collision detection: in your update loop, for each segment of the rope, check if it crossed any drape-points during the previous frame (point was on left side of segment before and is on right side now or vice versa). Then response: if a segment crossed a drape-point, move it back so it’s just touching the point on the original side. One advantage of Verlet is that you can enforce constraints by just modifying the current state, and the simulation will adjust automatically (I assume you’re already doing this to keep the rope from stretching).

I would also suggest, for stability reasons, using small circles as the drape points rather than actual points. Otherwise you’ll likely have problems with resting contact; the rope will tend to fall through the points. With a circle you can exclude the rope from the forbidden zone as well as testing whether it’s crossed from one side to the other.

E1bddb31000e459fb3ee5593fe067486
0
paul0n0n 101 Jul 10, 2009 at 11:48

well the rope does stretch, but it goes back to its original rest length,

Function Verlet()

    ; eg: move particles, introducing drag

    For p.particle = Each particle
        p\tx# = p\x#
        p\ty# = p\y#
        x# = p\x
        y# = p\y

        tempx# = p\x
        tempy# = p\y

        oldx# = p\old_x
        oldy# = p\old_y

        p\x = p\x + drag * x - drag * oldx + p\a_x * TIMESTEP * TIMESTEP
        p\y = p\y + drag * y - drag * oldy + p\a_y * TIMESTEP * TIMESTEP

        p\old_x = tempx
        p\old_y = tempy

        ; reset acceleration after moving particle
        p\a_x = 0 : p\a_y = 0
    Next

End Function


Function ConstrainParticlesMass()

    p.particle = First particle

    While p\nxt <> Null
        dx# = p\nxt\x - p\x     ;subtract next particles x position from this position.
        dy# = p\nxt\y - p\y

        deltalength# = Sqr( dx*dx + dy*dy )
        diff# = ( deltalength - RESTLENGTH ) / (deltalength * ( -p\mass + -p\nxt\mass ) )

        p\x = p\x + -p\mass * dx * diff
        p\y = p\y + -p\mass * dy * diff
        If p\x > GraphicsWidth()-50 Then p\x = GraphicsWidth()-50
        If p\x < 50 Then p\x = 50
        If p\y > GraphicsHeight() - 50 Then p\y = GraphicsHeight()-50
        If p\y < 50 Then p\y = 50
        ;Test collision
        p\rep = 0
        For c.city = Each city
            If lineToCircle(p\x,p\y,p\nxt\x,p\nxt\y,c\x,c\y,c\r*2) Then p\rep = 1:p\x = p\tx: p\y = p\ty
        Next
        p = p\nxt       
        p\x = p\x - -p\mass * dx * diff
        p\y = p\y - -p\mass * dy * diff
        If p\x > GraphicsWidth()-50 Then p\x = GraphicsWidth()-50
        If p\x < 50 Then p\x = 50
        If p\y > GraphicsHeight() - 50 Then p\y = GraphicsHeight()-50
        If p\y < 50 Then p\y = 50
        ;Test collision
                For c.city = Each city
            If p\nxt <> Null Then 
                If lineToCircle(p\x,p\y,p\nxt\x,p\nxt\y,c\x,c\y,c\r) Then p\rep = 1:p\x = p\tx: p\y = p\ty
            EndIf
        Next
    Wend

End Function
E1bddb31000e459fb3ee5593fe067486
0
paul0n0n 101 Jul 10, 2009 at 12:49

well I can’t quite figure out how to drape the string correctly, but in trying to do so I made a cool screensaver.