Code: (Select All)
' Program based off of "The Coding Train" Video
' "Coding Challenge #13: Reaction Diffusion Algorithm in p5.js"
' https://www.youtube.com/watch?v=BV9ny785UNc
' Ported to QB64 by justsomeguy
OPTION _EXPLICIT
CONST cSIZEX = 100
CONST cSIZEY = 100
CONST cZOOM = 8
'Some base values to start off with
'dA = 1
'dB = .5
'feed = .055 , white border .45 . no border .65
'k = .062
CONST cREACTDIFF_dA = 1
CONST cREACTDIFF_dB = 0.45
CONST cREACTDIFF_feed = 0.055
CONST cREACTDIFF_k = .062
CONST cRESTARTTIME = 45 ' Timer to restart simulation
TYPE tCELL
a AS SINGLE
b AS SINGLE
END TYPE
DIM grid(cSIZEX, cSIZEY) AS tCELL
DIM nextGrid(cSIZEX, cSIZEY) AS tCELL
DIM tmr AS LONG
RANDOMIZE TIMER
_TITLE "Reaction Diffusion"
SCREEN _NEWIMAGE(cSIZEX * cZOOM, cSIZEY * cZOOM, 32)
reactDiffSetup grid(), nextGrid()
tmr = TIMER
DO
reactDiff grid(), nextGrid()
reactDiffRender grid(), nextGrid()
IF TIMER - tmr > cRESTARTTIME THEN
tmr = TIMER
reactDiffSetup grid(), nextGrid()
END IF
_DISPLAY
_LIMIT 250
LOOP UNTIL _KEYHIT = 27
SYSTEM
SUB reactDiff (grid() AS tCELL, nextGrid() AS tCELL)
DIM AS INTEGER x, y
DIM AS SINGLE a, b
FOR x = 1 TO cSIZEX - 1
FOR y = 1 TO cSIZEY - 1
a = grid(x, y).a
b = grid(x, y).b
nextGrid(x, y).a = a + cREACTDIFF_dA * reactDiffLaplaceA##(grid(), x, y) - a * b * b + cREACTDIFF_feed * (1 - a)
nextGrid(x, y).b = b + cREACTDIFF_dB * reactDiffLaplaceB##(grid(), x, y) + a * b * b - (cREACTDIFF_k + cREACTDIFF_feed) * b
nextGrid(x, y).a = constrain(nextGrid(x, y).a, 0, 1)
nextGrid(x, y).b = constrain(nextGrid(x, y).b, 0, 1)
NEXT
NEXT
END SUB
SUB reactDiffRender (grid() AS tCELL, nextgrid() AS tCELL)
DIM AS INTEGER i, j
DIM AS SINGLE a, b, c
FOR i = 0 TO cSIZEX
FOR j = 0 TO cSIZEY
a = grid(i, j).a
b = grid(i, j).b
c = INT((a - b) * 255)
c = constrain(c, 0, 255)
' IF c > 127 THEN c = 255 ELSE c = 0
LINE (i * cZOOM, j * cZOOM)-(i * cZOOM + cZOOM, j * cZOOM + cZOOM), _RGB32(c, c, c), BF
NEXT
NEXT
reactDiffSwap grid(), nextgrid()
END SUB
SUB reactDiffSetup (grid() AS tCELL, nextGrid() AS tCELL)
DIM AS INTEGER i, j, iter, iterCount, rsx, rsy, rszx, rszy
' Reset Map to all chemical A
FOR i = 0 TO cSIZEX
FOR j = 0 TO cSIZEY
grid(i, j).a = 1
grid(i, j).b = 0
nextGrid(i, j).a = 1
nextGrid(i, j).b = 0
NEXT
NEXT
iterCount = INT(RND * 20) + 10
FOR iter = 1 TO iterCount
'Make a random blob a chemical B
rsx = RND * (cSIZEX * .50) + (cSIZEX * .25)
rsy = RND * (cSIZEY * .50) + (cSIZEY * .25)
rszx = RND * (cSIZEX * .10)
rszy = RND * (cSIZEY * .10)
FOR i = rsx TO rsx + rszx
FOR j = rsy TO rsy + rszy
grid(i, j).b = 1
NEXT
NEXT
NEXT
END SUB
FUNCTION reactDiffLaplaceA## (grid() AS tCELL, x AS INTEGER, y AS INTEGER)
DIM AS SINGLE sumA: sumA = 0
sumA = sumA + grid(x, y).a * -1
sumA = sumA + grid(x - 1, y).a * 0.2
sumA = sumA + grid(x + 1, y).a * 0.2
sumA = sumA + grid(x, y + 1).a * 0.2
sumA = sumA + grid(x, y - 1).a * 0.2
sumA = sumA + grid(x - 1, y - 1).a * 0.05
sumA = sumA + grid(x + 1, y - 1).a * 0.05
sumA = sumA + grid(x + 1, y + 1).a * 0.05
sumA = sumA + grid(x - 1, y + 1).a * 0.05
reactDiffLaplaceA## = sumA
END FUNCTION
FUNCTION reactDiffLaplaceB## (grid() AS tCELL, x AS INTEGER, y AS INTEGER)
DIM AS SINGLE sumB: sumB = 0
sumB = sumB + grid(x, y).b * -1
sumB = sumB + grid(x - 1, y).b * 0.2
sumB = sumB + grid(x + 1, y).b * 0.2
sumB = sumB + grid(x, y + 1).b * 0.2
sumB = sumB + grid(x, y - 1).b * 0.2
sumB = sumB + grid(x - 1, y - 1).b * 0.05
sumB = sumB + grid(x + 1, y - 1).b * 0.05
sumB = sumB + grid(x + 1, y + 1).b * 0.05
sumB = sumB + grid(x - 1, y + 1).b * 0.05
reactDiffLaplaceB## = sumB
END FUNCTION
SUB reactDiffSwap (grid() AS tCELL, nextGrid() AS tCELL)
DIM AS INTEGER i, j
FOR i = 0 TO cSIZEX
FOR j = 0 TO cSIZEY
SWAP grid(i, j), nextGrid(i, j)
NEXT
NEXT
END SUB
FUNCTION constrain (n AS SINGLE, low AS SINGLE, high AS SINGLE)
DIM o AS SINGLE
o = n
IF o < low THEN o = low
IF o > high THEN o = high
constrain = o
END FUNCTION