Elastic Rope Demo (Pure BlitzMax without Physics-SDK)

Started by Midimaster, February 01, 2022, 15:53:19

Previous topic - Next topic

Midimaster

Here is a code snipplet how you could code ropes or cables . Move their ends with LeftMouse or RightMouse
to feel the handling

Its a runable app:

Code (BlitzMax) Select
SuperStrict
Graphics 800,800

Global Cable:TCable= New TCable(300,300,300,500,400)
SetClsColor 0,100,100
Repeat
Cls
If MouseDown(1)
Cable.Move MouseX(), MouseY(), 1
ElseIf MouseDown(2)
Cable.Move MouseX(), MouseY(), 2
EndIf
SetColor 0,85,85
Cable.Draw 20,10
SetColor 180,0,0
Cable.Draw 0,0
Flip
Until AppTerminate()





Type TCable
Const LEFT_:Int=1, RIGHT_:Int=2
Global List:TList, Cosinus:Double[36000]

Field LeftX:Double, LeftY:Double, RightX:Double, RightY:Double

Field Pieces:Int, Length:Int
Field xp:Double[], yp:Double[], xg:Double[], yg:Double[]
Field ProcessNow:Int

Method New(FromX:Int, FromY:Int, TotalLength:Int, ToX:Int, ToY:Int)
If Cosinus[0]=0 PrepareCosTable
Pieces=50 'TotalLength/10
Length=10
xp = New Double[Pieces+1]
yp = New Double[Pieces+1]
xg = New Double[Pieces+1]
yg = New Double[Pieces+1]
StartUp FromX, FromY, ToX, ToY
End Method


Method StartUp(FromX:Int, FromY:Int,  ToX:Int, ToY:Int)
Local diffx:Double = Double(ToX-FromX)/ Pieces
Local diffy:Double = Double(ToY-FromY)/ Pieces
For Local i:Int=0 To Pieces
xp[i]= FromX + i*diffX
yp[i]= FromY + i*diffY
Next
ProcessNow = MilliSecs()+5000
For Local i%=0 To 39
Iterate True
Next
End Method


Method Iterate(Speed:Int=False)
If ProcessNow<MilliSecs() Return

' needs 0.15 msec
For Local w:Int = 1 To 20
For Local i:Int=0 Until Pieces
Local q:Int =i
If i Mod 2=1 Then q = Pieces-i

Local wk:Double =  (ATan2(yp[q]-yp[q+1],xp[q]-xp[q+1]))' Mod 360
'Local dx:Double = ((xp[q+1] +Cos(wk)*Length) -xp[q])/2
'Local dy:Double = ((yp[q+1] +Sin(wk)*Length) -yp[q])/2

'alternative: Faster COS and SIN  (needs 0.07msec)
Local FastCosinus:Int=Int(wk*100+36000) Mod 36000
Local FastSinus  :Int=(FastCosinus +27000) Mod 36000
Local dx:Double = ((xp[q+1] +Cosinus[FastCosinus]*Length) -xp[q])/2
Local dy:Double = ((yp[q+1] +Cosinus[FastSinus]*Length) -yp[q])/2

AddChain q+1, -dx, -dy
AddChain q  ,  dx,  dy
Next
Next
For Local q:Int=1 Until Pieces
yg[q]:+ 0.4    ' gravity
xg[q]:* 0.970  '
yg[q]:* 0.970
xp[q]:+ xg[q]
yp[q]:+ yg[q]
Next
End Method


Method AddChain(n:Int, dx:Double, dy:Double)
If n=0 Return
If n=Pieces Return 
xp[n]:+ dx
yp[n]:+ dy
xg[n]:+ dx
yg[n]:+ dy
End Method


Method Move(X:Int, Y:Int, LeftOrRight:Int)
' 1=left 2=right 3=both
If LeftOrRight & 1
xp[0]=X
yp[0]=y
EndIf
If LeftOrRight & 2
xp[Pieces]=X
yp[Pieces]=y
EndIf
ProcessNow=MilliSecs()+10000
End Method



Method Draw(X:Int, y:Int)
Iterate
SetLineWidth 5
' needs 0.08 msec
For Local i:Int=0 Until Pieces-1
DrawLine X+xp[i], Y+yp[i], X+xp[i+1], Y+yp[i+1]
Next

'alternative: Faster ???  (time needed:-??%)
'           Try To do it with DrawPolygone()
SetColor 222,222,222
DrawText "(LEFT MOUSE)", xp[0]-50, yp[0]-20
DrawText "(RIGHT MOUSE)", xp[Pieces]-50, yp[Pieces]-20
End Method



Function PrepareCosTable()
For Local i%=0 To 35999
cosinus[i] = Cos(i/100.0)
Next
End Function
End Type
...back from Egypt


Midimaster

I only want to add a gif-animation  to this post. This make more clear, what it is good for. (Nothing changed in the code) 

ElasticRopeDemo.gif
...back from Egypt