Verlet physics

BlitzMax Forums/BlitzMax Beginners Area/Verlet physics

Hi I have the demo of blitz max and wanted to try out all of the features before I bought it. I was seeing how fast and easy to use it was when I came upon a problem. I program in B3d and I can easily make a type within a type. I know Bmax can do this but how?? Here is my code so far and I wanted to know how to make two verlet types inside of each constraint type.

in b3d I do it like this
Type Constraint							;Constraints constrain the verlets to certain distances from eachother
	Field v1.verlet						;First verlet in constraint
	Field v2.verlet						;Second verlet in constraint
	Field length#						;Length of the constraint
End Type



In bmax I can't figure it out I already tried this and it doesn't work

Type TConstraint
	Field V1:TVerlet
	Field V2:TVerlet
	Field length#  ;etc...


PLEASE be more descriptive than "it doesn't work." Provide all the code of whatever "isn't working" and describe the problem you're experiencing if you want help.

It patently does work, so it's hard to identify your problem without symptoms or more code.

Type TConstraint
	Field V1:TVerlet
	Field V2:TVerlet
	Field length#
End Type

Type TVerlet
	
End Type

C:TConstraint=New TConstraint
C.V1=New TVerlet
C.V2=New TVerlet
C.Length=4


I fixed my old problem but now I have a new problem
It doesn't recognize addlast
here is my code

Graphics 640,480,0,2

Global Gravity# = .1
VerletList = CreateList()
ConstraintList = CreateList()

Type Tverlet
	Field x#,y#
	Field dx#,dy#
	Field ox#,oy#
	Field ID
	Field VID
	Field active
	Field mass#
	Field collided
	
	Method Update()
	
		If active = True Then
			tx# = x#-ox#
			ty# = y#-oy#
	
			ox# = tx#
			oy# = ty#
			
			x# = x# + tx#
			y# = y# + ty# - Gravity#
			
			If y# > 640 Then
				collided = True
				y# = 640
			EndIf
			
		EndIf
	
	End Method
	Function CreateVerlet(x#,y#,ID,active = True)

		V:Tverlet = New Tverlet
		V.x# = x#
		V.y# = y#
		V.ID = ID
		V.Active = active
		V.AddLast VerletList

	End Function

	
End Type





Type TConstraint
	Field V1:TVerlet
	Field V2:TVerlet
	Field length#
	
	Method Update()
	
		tx# = V1.x#-V2.x#
		ty# = V1.y#-V2.y#
		
		dist# = Sqr(tx#*tx#+ty#*ty#)
		
		tx# = tx# / 2
		ty# = ty# / 2
		
		If dist# <> 0 Then
			diff# = (dist# - Length#) / dist#
		EndIf
		
		V1.x# = V1.x# - diff# * tx#
		V1.y# = V1.y# - diff# * ty#

		V2.x# = V2.x# + diff# * tx#
		V2.y# = V2.y# + diff# * ty#
	
	End Method
	
End Type


V isn't a TList.

Ok I fixed all of my previous problems but have a new one. I'm not sure what it is so here is my code

Graphics 640,480,0,2

Global Gravity# = .1
Global VerletList = New TList
Global ConstraintList = New TList





Type Tverlet
	Field x#,y#
	Field dx#,dy#
	Field ox#,oy#
	Field ID
	Field VID
	Field active
	Field mass#
	Field collided
	
	Method Update()
	
		If active = True Then
			tx# = x#-ox#
			ty# = y#-oy#
	
			ox# = tx#
			oy# = ty#
			
			x# = x# + tx#
			y# = y# + ty# - Gravity#
			
			If y# > 640 Then
				collided = True
				y# = 640
			EndIf
			
		EndIf
	
	End Method
	Method Draw()
	
	SetScale 1,1
	SetColor 255,255,255
	SetRotation 0
	
	DrawOval x# - 10 , y# - 10 , 20 , 20
	
	End Method
	
	
	Method AddLast( list:TList )
		link=list.AddLast( Self )
	End Method
	
End Type


Function CreateVerlet(x#,y#,ID,active = True)

		V:Tverlet = New Tverlet
		V.x# = x#
		V.y# = y#
		V.ID = ID
		V.Active = active
		V.AddLast VerletList
End Function



Type TConstraint
	Field V1:TVerlet
	Field V2:TVerlet
	Field length#
	
	Method Update()
	
		tx# = V1.x#-V2.x#
		ty# = V1.y#-V2.y#
		
		dist# = Sqr(tx#*tx#+ty#*ty#)
		
		tx# = tx# / 2
		ty# = ty# / 2
		
		If dist# <> 0 Then
			diff# = (dist# - Length#) / dist#
		EndIf
		
		V1.x# = V1.x# - diff# * tx#
		V1.y# = V1.y# - diff# * ty#

		V2.x# = V2.x# + diff# * tx#
		V2.y# = V2.y# + diff# * ty#
	
	End Method
	
	Method AddLast( list:TList )
		link=list.AddLast( Self )
	End Method
	
	Function ConstrainVerlets( V1:TVerlet , V2:TVerlet )
	
		C:TConstraint = New TConstraint
		C.V1:TVerlet = V1:TVerlet
		C.V2:TVerlet = V2:TVerlet
		C.Length# = Sqr((C.V1.x#-C.V2.x#)^2 + (C.V1.y#-C.V2.y#)^2)
		C.AddLast ConstraintList
			
	End Function
End Type




Function UpdatePhysics()

For V:TVerlet = EachIn VerletList:TList
	V.Update
Next

For V:TVerlet = EachIn VerletList:TList
	V.draw
Next

End Function


Jesus, man. At least tell us what the error is.

People aren't going to mess about sifting through all your code to find out where and what the problem is.

Terribly Sorry I don't know much at all about bmax
I think it is something to do with the Function UpdatePhysics at the very bottom although I am not really sure

Jesus, man. At least tell us what the error is.



I've only had the demo for a day so I am very sorry But this is the Beginners area

Still, without saying what the problem is people can't do very much.

I think it is something to do with the Function UpdatePhysics at the very bottom although I am not really sure

Does it crash?
Does it not compile?
Does it simply not do what you expect it to?
etc

It says Identifier type doesn't match declared type sorry I didn't know Exactly what you wanted

could someone just copy and paste into bmax and run it so they would know what the problem was exactly I would think that would be the first thing to do.

You should add Strict or SuperStrict to the top of the app.

You should declare each variable with its Type.

eg.

Global VerletList = New TList

would become

Global VerletList:TList = New TList


It'll help you with all these niggly issues.

Thank you Bruce :) just what I was looking for I will use strict from now on thank you again

Sorry to come with more problems I actually got it working but Sadly it runs very slow. I just wanted to know if it ran slow on anyone else's computer or if it was just mine.

I am very sorry but this time I have no Idea why it does this

Graphics 640,480,0,2

Global Gravity# = 1
Global VerletList:TList = New TList
Global ConstraintList:TList = New TList

CreateVerlet(100,100,1)

While Not AppTerminate()
Cls

UpdatePhysics()

Flip
Wend

End
Type Tverlet
	Field x#,y#
	Field dx#,dy#
	Field ox#,oy#
	Field ID
	Field VID
	Field active
	Field mass#
	Field collided
	
	Method Update()
	
		If active = True Then
			dx# = x#-ox#
			dy# = y#-oy#
	
			ox# = x#
			oy# = y#
			
			x# = x# + dx#
			y# = y# + dy# + Gravity#
			
			If y# > 640 Then
				collided = True
				y# = 640
			EndIf
			
		EndIf
	
	End Method
	Method Draw()
	
	'SetScale 1,1
	'SetColor 255,255,255
	'SetRotation 0
	
		DrawOval x# - 10 , y# - 10 , 20 , 20
	
	End Method
	
	
	Method AddLast( list:TList )
		link=list.AddLast( Self )
	End Method
	
End Type


Function CreateVerlet(x#,y#,ID,active = True)

		V:Tverlet = New Tverlet
		V.x# = x#
		V.y# = y#
		V.ID = ID
		V.ox# = x#
		V.oy# = y#
		V.Active = active
		V.AddLast VerletList
End Function



Type TConstraint
	Field V1:TVerlet
	Field V2:TVerlet
	Field length#
	
	Method Update()
	
		tx# = V1.x#-V2.x#
		ty# = V1.y#-V2.y#
		
		dist# = Sqr(tx#*tx#+ty#*ty#)
		
		tx# = tx# / 2
		ty# = ty# / 2
		
		If dist# <> 0 Then
			diff# = (dist# - Length#) / dist#
		EndIf
		
		V1.x# = V1.x# - diff# * tx#
		V1.y# = V1.y# - diff# * ty#

		V2.x# = V2.x# + diff# * tx#
		V2.y# = V2.y# + diff# * ty#
	
	End Method
	
	Method AddLast( list:TList )
		link=list.AddLast( Self )
	End Method
	
	Function ConstrainVerlets( V1:TVerlet , V2:TVerlet )
	
		C:TConstraint = New TConstraint
		C.V1:TVerlet = V1:TVerlet
		C.V2:TVerlet = V2:TVerlet
		C.Length# = Sqr((C.V1.x#-C.V2.x#)^2 + (C.V1.y#-C.V2.y#)^2)
		C.AddLast ConstraintList
			
	End Function
End Type




Function UpdatePhysics()

For V:TVerlet = EachIn VerletList:TList
	V.Update
Next

For V:TVerlet = EachIn VerletList:TList
	V.draw
Next

End Function


Because your Graphics command calls for a two frame per second update!

That one doesn't compile here.

Does here -- oooooh controversy!

My fault... I added Strict at the top... silly of me, I know.

Yep. Like what Sledge says about the 2 frames/sec thing.

oooooh controversy!

lol :-P

oops Silly me I am used to B3d where graphics 640,480,0,2 means windowed mode LOL I am truly a beginner at bmax

Everyone does it -- the orientation guide is worth a scan if you haven't already given it a squiz.

Ok I finished the basics of the physics engine and it works well Thanks for the advice sledge and to everyone that answered my questions which I know were not very good.

click the mouse to make it bounce around. :)

Graphics 640,480

Global Gravity# = .1
Global VerletList:TList = New TList
Global ConstraintList:TList = New TList

V1:Tverlet = TVerlet.CreateVerlet(100,100,1)
V2:Tverlet = TVerlet.CreateVerlet(150,50,1)
V3:Tverlet = Tverlet.CreateVerlet(100,50,1)
V4:TVerlet = TVerlet.CreateVerlet(150,100,1)
Tconstraint.ConstrainVerlets(V1:Tverlet,V2:TVerlet)
Tconstraint.ConstrainVerlets(V1:TVerlet,V3:TVerlet)
Tconstraint.ConstrainVerlets(V2:TVerlet,V3:TVerlet)
Tconstraint.ConstrainVerlets(V1:Tverlet,V4:TVerlet)
Tconstraint.ConstrainVerlets(V2:Tverlet,V4:TVerlet)
Tconstraint.ConstrainVerlets(V3:Tverlet,V4:TVerlet)

While Not AppTerminate()
Cls

If MouseDown(1) Then
	V1.y# = V1.y# - 1
EndIf
UpdatePhysics()

Flip
Wend

End
Type Tverlet
	Field x#,y#
	Field dx#,dy#
	Field ox#,oy#
	Field ID
	Field VID
	Field active
	Field mass#
	Field collided
	
	Method Update()
	
		If active = True Then
			If collided = True Then
				fric# = .8
			Else
				fric# = 1
			EndIf
			collided = False
			dx# = (x#-ox#)*fric
			dy# = (y#-oy#)*fric
	
			ox# = x#
			oy# = y#
			
			x# = x# + dx#
			y# = y# + dy# + Gravity#
			
			If y# > 480 Then
				collided = True
				y# = 480
				oy# = 480+(dy#/3)
			EndIf
			
		EndIf
	
	End Method
	Method Draw()
	
	'SetScale 1,1
	'SetColor 255,255,255
	'SetRotation 0
		DrawOval x# - 10 , y# - 10 , 20 , 20
	
	End Method
	
	
	Method AddLast( list:TList )
		link=list.AddLast( Self )
	End Method
	
	Function CreateVerlet:TVerlet(x#,y#,ID,active = True)

		V:Tverlet = New Tverlet
		V.x# = x#
		V.y# = y#
		V.ID = ID
		V.ox# = x#
		V.oy# = y#
		V.Active = active
		V.AddLast VerletList
		Return V
	
	End Function


End Type




Type TConstraint
	Field V1:TVerlet
	Field V2:TVerlet
	Field length#
	
	Method Update()
	
		tx# = V1.x#-V2.x#
		ty# = V1.y#-V2.y#
		
		dist# = Sqr(tx#*tx#+ty#*ty#)
		
		tx# = tx# / 2
		ty# = ty# / 2
		
		If dist# <> 0 Then
			diff# = (dist# - Length#) / dist#
		EndIf
		
		V1.x# = V1.x# - diff# * tx#
		V1.y# = V1.y# - diff# * ty#

		V2.x# = V2.x# + diff# * tx#
		V2.y# = V2.y# + diff# * ty#
		
		SetColor 255,255,255
		DrawLine V1.x#,v1.y#,v2.x#,v2.y#
	End Method
	
	Method AddLast( list:TList )
		link=list.AddLast( Self )
	End Method
	
	Function ConstrainVerlets( V1:TVerlet , V2:TVerlet )
	
		C:TConstraint = New TConstraint
		C.V1:TVerlet = V1:TVerlet
		C.V2:TVerlet = V2:TVerlet
		C.Length# = Sqr((C.V1.x#-C.V2.x#)^2 + (C.V1.y#-C.V2.y#)^2)
		C.AddLast ConstraintList
			
	End Function
End Type




Function UpdatePhysics()

For V:TVerlet = EachIn VerletList:TList
	V.Update
Next

For C:TConstraint = EachIn ConstraintList:TList
	C.Update
Next

'For V:TVerlet = EachIn VerletList:TList
'	V.draw
'Next

End Function


you can put the lists into the types, which makes it easier to integrate into another code

Graphics 640,480

Global Gravity# = .1

Local BoxStack:Tbox[] = New TBox[50]

For Local i:Int = 0 To 49

	BoxStack[i] = New TBox
	
	BoxStack[i].V1 = TVerlet.CreateVerlet( 0+i*5, 50+i*1, i)
	BoxStack[i].V2 = TVerlet.CreateVerlet(50+i*5,  0+i*1, i)
	BoxStack[i].V3 = Tverlet.CreateVerlet( 0+i*5,  0+i*1, i)
	BoxStack[i].V4 = TVerlet.CreateVerlet(50+i*5, 50+i*1, i)
	
	Tconstraint.ConstrainVerlets(BoxStack[i].V1, BoxStack[i].V2)
	Tconstraint.ConstrainVerlets(BoxStack[i].V1, BoxStack[i].V3)
	Tconstraint.ConstrainVerlets(BoxStack[i].V2, BoxStack[i].V3)
	Tconstraint.ConstrainVerlets(BoxStack[i].V1, BoxStack[i].V4)
	Tconstraint.ConstrainVerlets(BoxStack[i].V2, BoxStack[i].V4)
	Tconstraint.ConstrainVerlets(BoxStack[i].V3, BoxStack[i].V4)
	
Next

Local oldtime:Int

While Not AppTerminate()
	Cls
	If MouseDown(1) Then
		For i = 0 To 49
			BoxStack[i].V1.y = BoxStack[i].V1.y - 1
		Next
	EndIf
	
	oldtime = MilliSecs()
	
	TVerlet.UpdateAll()
	TConstraint.UpdateAll()
	
	DrawText "Calculation Time "+String(MilliSecs()-oldtime)+" ms", 10, 10
	
	Flip
Wend

End

Type TBox
	
	Field V1:Tverlet
	Field V2:Tverlet
	Field V3:Tverlet
	Field V4:Tverlet
	
EndType

Type Tverlet
	
	Global VerletList:TList = New TList

	Field x#,y#
	Field dx#,dy#
	Field ox#,oy#
	Field ID
	Field VID
	Field active
	Field mass#
	Field collided
	
	Method Update()
	
		If active = True Then
			If collided = True Then
				fric# = .8
			Else
				fric# = 1
			EndIf
			collided = False
			dx# = (x#-ox#)*fric
			dy# = (y#-oy#)*fric
	
			ox# = x#
			oy# = y#
			
			x# = x# + dx#
			y# = y# + dy# + Gravity#
			
			If y# > 480 Then
				collided = True
				y# = 480
				oy# = 480+(dy#/3)
			EndIf
			
			If x < 0 Or x > 640
				If x<0   
					x = 0
					ox = 0 + (dx/3)
				Else
					x = 640
					ox = 640 - (dx/3)
				EndIf
			EndIf
			
		EndIf
	
	End Method
	
	
	Function CreateVerlet:TVerlet(x#,y#,ID,active = True)

		V:Tverlet = New Tverlet
		V.x   = x
		V.y   = y
		V.ID  = ID
		V.ox   = x
		V.oy   = y
		V.Active = active
		ListAddLast(VerletList, V)
		Return V
	
	End Function
	
	Function UpdateAll()
		For V:Tverlet = EachIn VerletList:TList
			V.Update()
		Next		
	EndFunction


End Type




Type TConstraint
	
	Global ConstraintList:TList = New TList
	
	Field V1:TVerlet
	Field V2:TVerlet
	Field length#
	
	Method Update()
		
		tx# = V1.x#-V2.x#
		ty# = V1.y#-V2.y#
		
		dist# = Sqr(tx#*tx#+ty#*ty#)
		
		tx# = tx# / 2
		ty# = ty# / 2
		
		If dist# <> 0 Then
			diff# = (dist# - Length#) / dist#
		EndIf
		
		V1.x# = V1.x# - diff# * tx#
		V1.y# = V1.y# - diff# * ty#

		V2.x# = V2.x# + diff# * tx#
		V2.y# = V2.y# + diff# * ty#
		
		SetColor 255,255,255
		DrawLine V1.x#,v1.y#,v2.x#,v2.y#
		
		
	End Method
	
	Function ConstrainVerlets:TConstraint( V1:TVerlet , V2:TVerlet )
	
		C:TConstraint = New TConstraint
		C.V1     = V1:TVerlet
		C.V2     = V2:TVerlet
		C.Length = Sqr((C.V1.x#-C.V2.x#)^2 + (C.V1.y#-C.V2.y#)^2)
		ListAddLast(ConstraintList, C)
		Return C
		
	End Function
	
	Function UpdateAll()
		For C:TConstraint = EachIn ConstraintList:TList
			C.Update()
		Next
	EndFunction
	
End Type