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:
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