Reaction Diffusion
#1
I found this cool little program written by the guy from "The Coding Train", so I ported it to QB64. He has a lot of cool stuff on his channel and I've learned a lot from his videos.

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


Coding Challenge #13: Reaction Diffusion Algorithm in p5.js

[Image: screenshot.png]
Reply


Messages In This Thread
Reaction Diffusion - by justsomeguy - 04-21-2022, 02:07 PM
RE: Reaction Diffusion - by bplus - 04-22-2022, 12:42 AM



Users browsing this thread: 5 Guest(s)