Strings / Ropes, Etc.

Blitz3D Forums/Blitz3D Programming/Strings / Ropes, Etc.

I haven't looked at your code at length but you're probably better using verlet integration for this kind of thing. Weibo of Thrust Extreme fame posted some code a while back which could prove useful. Basically, you assign specific weight to pointmasses which then determines their influence during the constraint phase.

Found it ...

; quick thrust game, by Wiebo de Wit
; Using verlet integration for movement and stick constraints for the ball and chain =]
; green line is your ship. I'm sorry but i didn't have the strength to include my new
; vector object engine. a and s to rotate, r-shift to thrust

Const TIMESTEP# = 0.05
Const GRAVITYANGLE = 0			; 0 = straight down, 90 = right, etc
Const GRAVITYFORCE# = 10
Const DRAG# = 0.995
Const THRUST# = 40
Const NUM_PARTICLES = 5
Const RESTLENGTH# = 20

Type Particle
	Field x#, y#
	Field old_x#, old_y#
	Field a_x#, a_y#
	Field mass#
	Field nxt.particle
End Type

Type Player
	Field angle#
	Field thrust#
	Field point.particle
End Type

Global player.player, p.particle

Graphics 640,480
SetBuffer BackBuffer()

; create player
player.player = New player

; player is a particle too, but you can control it
player\point = New particle
p.particle = player\point
p\x = 200 : p\y = 200
p\old_x = 200 : p\old_y = 200
p\a_x = 0 : p\a_y = 0

; make ship heavy
p\mass =1

For count = 1 To NUM_PARTICLES

	p\nxt = New particle
	p = p\nxt

	p\x = 200 : p\y = 200
	p\old_x = Rand(200,205) 
	p\old_y = Rand(200,205)
	p\a_x = 0 : p\a_y = 0
	p\mass = 60
Next

; last particle is ball. make heavy
p\mass = 1

; loop
While KeyHit( 1 ) = False

	GetInput()
	ApplyPhysics()
	Verlet()
	ConstrainParticlesMass()
	DrawParticles()
	Flip
	Cls

Wend

; ------------------------------------------------------------

Function GetInput()

	If KeyDown( 203 )
		;rotate
		player\angle = player\angle + 5
	EndIf

	If KeyDown( 205 )
		;rotate
		player\angle = player\angle - 5
	EndIf

	If KeyDown( 200 )
		;thrust, adjust player particle acceleration
		p.particle = player\point
		p\a_x = p\a_x - Sin( player\angle ) * THRUST
		p\a_y = p\a_y - Cos( player\angle ) * THRUST
	EndIf

End Function


Function ApplyPhysics()

	; apply gravity to particles
	For p.particle = Each particle
		p\a_x = p\a_x + Sin( GRAVITYANGLE ) * GRAVITYFORCE / p\mass
		p\a_y = p\a_y + Cos( GRAVITYANGLE ) * GRAVITYFORCE / p\mass
	Next

End Function


Function ConstrainParticlesMass()

	p.particle = player\point

	While p\nxt <> Null
		dx# = p\nxt\x - p\x
		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
		p = p\nxt
		p\x = p\x - -p\mass * dx * diff
		p\y = p\y - -p\mass * dy * diff
	Wend

End Function


Function DrawParticles()

	p.particle = player\point

	; draw player, green line

	Color 0,255,0
	dx# = Sin( player\angle) 
	dy# = Cos( player\angle)
	Line p\x-dx*20, p\y-dy*20 , p\x + dy*5, p\y - dx*5
	Line p\x-dx*20, p\y-dy*20 , p\x - dy*5, p\y + dx*5
	Line p\x + dy*5, p\y - dx*5, p\x - dy*5, p\y + dx*5

	; draw line
	Color 255,0,0
	While p\nxt <> Null
		Line p\x, p\y, p\nxt\x, p\nxt\y
		p = p\nxt
	Wend

	; draw ball at end
	Color 255,255,0
	Oval p\x -14, p\y-14, 28,28, 0

	; white dots, for clarity
	Color 255,255,255
	For p.particle =Each particle
		Plot p\x, p\y
	Next

End Function


Function Verlet()

	; eg: move particles, introducing drag

	For p.particle = Each particle

		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