I've been playing a bit with verlets lately, thanks to the simple code posted by Bot Builder in this thread: http://www.blitzbasic.com/Community/posts.php?topic=43242
I've picked at that code and altered variables so that I could better understand what was happening, Also removed some optimizations for the same reason... I think I finally am starting to get it, but I'm a bit stumped on adding collisions. edit: i've added code that properly detects collisions between verlets in different groups, but I need help on taking the proper action.
I'd like to see some really simple examples of how you would do this. I'd rather see simple examples than highly optimized at this point, since I am simply trying to understand things a bit better.
Anyways, here is where I am (again,... I take no credit for this code,... modified from Bot Builders) press space to add another box,... I'd like to have this code working with coliding boxes.
Thanks for any help.
I've picked at that code and altered variables so that I could better understand what was happening, Also removed some optimizations for the same reason... I think I finally am starting to get it, but I'm a bit stumped on adding collisions. edit: i've added code that properly detects collisions between verlets in different groups, but I need help on taking the proper action.
I'd like to see some really simple examples of how you would do this. I'd rather see simple examples than highly optimized at this point, since I am simply trying to understand things a bit better.
Anyways, here is where I am (again,... I take no credit for this code,... modified from Bot Builders) press space to add another box,... I'd like to have this code working with coliding boxes.
Thanks for any help.
Graphics 800,600,32,2 Type Verlet Field x#, y#, ox#, oy#, size,id , collide End Type Type Constraint Field Head.Verlet, Tail.Verlet, Length End Type Global circle=CreateImage (40,40) SetBuffer ImageBuffer(circle) Color 128,128,128 Oval 0,0,40,40 Color 0,255,0 Oval 0,0,40,40,0 MidHandle circle Global circlehit=CreateImage (40,40) SetBuffer ImageBuffer(circlehit) Color 255,0,0 Oval 0,0,40,40 MidHandle circlehit SetBuffer BackBuffer() definebox() ; create a verlet box with constraints While Not KeyHit(1) UpdateVerlets() Drawscreen() If MouseDown(1) Then ; use mouse to drag selected point around If selection.verlet<>Null Then selection\x=(selection\x+MouseX())/2 selection\y=(selection\y+MouseY())/2 Else For v.verlet=Each verlet If Sqr((MouseX()-v\x)*(MouseX()-v\x)+(MouseY()-v\y)*(MouseY()-v\y))<v\size Then selection=v Goto skipNull EndIf Next selection=Null .skipnull EndIf Else selection=Null EndIf Flip Cls Wend End Function UpdateVerlets() For v.Verlet=Each Verlet tx#=v\x ;tempx ty#=v\y ;tempy If v\collide = False v\x=v\x+.99*(v\x-v\ox) ;give the verlet momentum from the previous loop - decay the value v\y=v\y+.99*(v\y-v\oy) ;+ .5 ;same as above plus gravity EndIf v\collide = False If v\x>GraphicsWidth()-v\size Then v\x=GraphicsWidth()-v\size ElseIf v\x<v\size Then v\x=v\size ; constrain verlet to screen If v\y>GraphicsHeight()-v\size Then v\y=GraphicsHeight()-v\size ElseIf v\y<v\size Then v\y=v\size; v\ox=tx ; store verlet position in old slot for next loop v\oy=ty ; Next ;basic collision detection,... needs to be integrated with code above For v.verlet = Each verlet For vv.verlet = Each verlet If v<>vv And v\id<>vv\id ; don't compare verlet against itself or others in the same id ;v\collide = False ;vv\collide = False dx#= v\x - vv\x dy#= v\y - vv\y dist# = Sqr (dx*dx + dy*dy) If dist# < 40 ;Text 50,50,"collide" v\collide = True vv\collide = true EndIf EndIf Next Next For i=0 To 10 ;Iterate For c.Constraint=Each Constraint dx#=c\Tail\x - c\Head\x ;x vector distance dy#=c\Tail\y - c\Head\y ;y vector distance dl#=Sqr(dx*dx+dy*dy) ;vector length d#=(dl - c\length) / Float(dl) ; vector length - constraint / vector length dx#=dx/2 ; half distance dy#=dy/2 ;half distance c\Head\x=c\Head\x+d*dx c\Head\y=c\Head\y+d*dy c\Tail\x=c\Tail\x-d*dx c\Tail\y=c\Tail\y-d*dy ;Simple, optimized rigid constraint algo Next Next End Function Function DrawScreen() For v.verlet=Each verlet If v\collide = False DrawImage circle,v\x,v\y ; draw red circle if colliding Else DrawImage circlehit,v\x,v\y ; draw image,... faster than circle below EndIf ;Oval v\x-v\size,v\y-v\size,v\size Shl 1,v\size Shl 1 Next ;For c.constraint = Each constraint ; draw all the constraints ; Line c\head\x,c\head\y,c\tail\x,c\tail\y ;Next End Function Function definebox() For num = 1 To 4 ; define the shape and constraints ; eventually replace with file/data statements and calculate constraint distance from initial point placement v1.verlet=New verlet v1\x=100 + (num*100) v1\y=100 v1\ox=100+ (num*100) v1\oy=100 v1\size=20 v1\id=num v2.verlet = New verlet v2\x=150+ (num*100) v2\y=100 v2\ox=150+ (num*100) v2\oy=100 v2\size=20 v2\id=num v3.verlet = New verlet v3\x=100+ (num*100) v3\y=150 v3\ox=100+ (num*100) v3\oy=150 v3\size=20 v3\id=num v4.verlet = New verlet v4\x=150+ (num*100) v4\y=150 v4\ox=150+ (num*100) v4\oy=150 v4\size=20 v4\id=num v5.verlet = New verlet v5\x=150+ (num*100) v5\y=200 v5\ox=150+ (num*100) v5\oy=200 v5\size=20 v5\id=num v6.verlet = New verlet v6\x=150+ (num*100) v6\y=200 v6\ox=150+ (num*100) v6\oy=200 v6\size=20 v6\id=num ; now connect the verlets with constraints c.constraint=New constraint ;top c\Head=v1 c\Tail=v2 c\Length=50 c.constraint=New constraint ;right c\Head=v2 c\Tail=v4 c\Length=50 c.constraint=New constraint ;bottom c\Head=v3 c\Tail=v4 c\Length=50 c.constraint = New constraint ;left c\Head=v3 c\Tail=v1 c\Length=50 c.constraint = New constraint ; diagonal 1 c\Head=v6 c\Tail=v1 c\Length=Sqr(100*100+(50*50)) c.constraint = New constraint ; diagonal 2 c\Head=v2 c\Tail=v5 c\Length=Sqr(100*100+(50*50)) c.constraint = New constraint c\Head=v4 c\Tail=v6 c\Length=50 c.constraint=New constraint ;right c\Head=v5 c\Tail=v6 c\Length=50 c.constraint=New constraint ;bottom c\Head=v3 c\Tail=v5 c\Length=50 c.constraint = New constraint ; c\Head=v3 c\Tail=v6 c\Length=Sqr(50*50+(50*50)) c.constraint = New constraint ; c\Head=v4 c\Tail=v1 c\Length=Sqr(50*50+(50*50)) Next End Function