PDA

View Full Version : Verlet rope wraping around a point help


paul0n0n
07-09-2009, 05:48 AM
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.

Reedbeta
07-09-2009, 07:42 AM
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.

paul0n0n
07-10-2009, 04:48 AM
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

paul0n0n
07-10-2009, 05:49 AM
well I can't quite figure out how to drape the string correctly, but in trying to do so I made a cool screensaver.