Fluid/Path-building thingy-jig

Blitz3D Forums/Blitz3D Programming/Fluid/Path-building thingy-jig

This is something I've been messing around with for the past hour or so, it's based on something I saw on bit-101.com and I decided to give it a go myself.

Imagine a grid of signposts; when a particle reaches a signpost it turns slightly in the direction of the signpost and the signpost turns slightly to match the previous direction of the particle. The emergent behaviour is quite interesting as after a few moments "gulleys" begin to form which the particles flow down. When you see it, it'll be a little clearer!

It could do with a bit of optimisation, and being 2D in Blitz3D it'll be a little slower anyway. It's not too bad on my computer (1000 particles, 40x30 grid), your mileage may vary!

Anyway, the code:
Graphics 800, 600, 32, 1

SetBuffer BackBuffer()




Global MAXX	= GraphicsWidth()
Global MAXY	= GraphicsHeight()

Const GRIDX			= 40
Const GRIDY			= 30
Const CELL			= 20
Const MIDCELL		= 10

Const NUM_PARTICLES = 1000
Const PARTICLE_TURN = 15
Const PARTICLE_SPEED= 5
Const GRID_TURN 	= 1


Dim grid(GRIDX, GRIDY)

For y = 0 To GRIDY - 1: For x = 0 To GRIDX - 1
	grid(x, y) = Rand(360)
Next: Next


Type p_dat
	Field x#, y#
	Field ang
End Type

Global p.p_dat

For n=0 To NUM_PARTICLES - 1
	p.p_dat = New p_dat
		p\x = Rnd(MAXX)
		p\y = Rnd(MAXY)
		p\ang = Rnd(360)
Next


Repeat
	Cls

	count = MilliSecs()

	; Move particles
	For p.p_dat = Each p_dat
		gx = Int(p\x / CELL)
		gy = Int(p\y / CELL)
		
		If p\ang > grid(gx, gy) Then p\ang = p\ang - PARTICLE_TURN: grid(gx, gy) = grid(gx, gy) + GRID_TURN
		If p\ang < grid(gx, gy) Then p\ang = p\ang + PARTICLE_TURN: grid(gx, gy) = grid(gx, gy) - GRID_TURN
		
		
		If p\ang < 0 Then p\ang = p\ang + 360
		If p\ang > 359 Then p\ang = p\ang - 360

		
		h# = Sin(p\ang) * PARTICLE_SPEED
		v# = Cos(p\ang) * PARTICLE_SPEED
		
		p\x = p\x + h#
		p\y = p\y + v#
		
		If p\x < 0 Then p\x = p\x + MAXX
		If p\x > MAXX Then p\x = p\x - MAXX
		If p\y < 0 Then p\y = p\y + MAXY
		If p\y > MAXY Then p\y = p\y - MAXY
	Next

	
	If KeyHit(57) Then
		For y = 0 To GRIDY - 1: For x=0 To GRIDX - 1
			grid(x, y) = turn * 90
		Next: Next
		turn = turn + 1			
	End If

	If KeyHit(19) Then
		For y = 0 To GRIDY - 1: For x=0 To GRIDX - 1
			grid(x, y) = Rnd(360)
		Next: Next
	End If

	; Draw particles
	Color 255, 255, 255
	For p.p_dat = Each p_dat
		Plot p\x, p\y
	Next

	; Draw grid
	count = MilliSecs()

	Color 32, 32, 32
	For y = 0 To GRIDY - 1: For x = 0 To GRIDX - 1
		x1 = x * CELL + MIDCELL
		y1 = y * CELL + MIDCELL
		
		x2 = x1 + Sin(grid(x, y)) * MIDCELL
		y2 = y1 + Cos(grid(x, y)) * MIDCELL
	
		Line x1, y1, x2, y2
		
		If grid(x, y) < 0 Then grid(x, y) = grid(x, y) + 360
		If grid(x, y) > 359 Then grid(x, y) = grid(x, y) - 360
	Next: Next
	
	count = MilliSecs() - count
	
	Color 255, 255, 255
	Text 10, 10, count	
	Text 10, MAXY - 26, "R - randomise all squares; Space - Flip direction of squares NSEW; Esc - quit"
	
	Flip

Until KeyHit(1)

End