Author Topic: Sandpiles  (Read 4991 times)

0 Members and 1 Guest are viewing this topic.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Sandpiles
« on: March 04, 2019, 10:10:09 am »
Hi everyone! This month is going to be very serious and exhausting for me.
The below program shows a basic demo for Abelian Sandpile Model. https://en.wikipedia.org/wiki/Abelian_sandpile_model
 Please note that rendering this stuff to full size is very time consuming.
Code: QB64: [Select]
  1. '1 Grain -> Black
  2. '2 Grain -> Yellow
  3. '3 Grain -> Blue
  4. '4 Grain -> Red
  5. _TITLE "Sandpiles by Ashish"
  6. SCREEN _NEWIMAGE(200, 200, 32)
  7.  
  8. grain(_WIDTH / 2, _HEIGHT / 2) = 500000
  9. CLS , _RGB(255, 255, 255)
  10.  
  11.  
  12.     FOR i = 0 TO 500
  13.         FOR y = 1 TO _HEIGHT - 1
  14.             FOR x = 1 TO _WIDTH - 1
  15.                 IF i = 500 THEN
  16.                     IF grain(x, y) = 1 THEN
  17.                         PSET (x, y), _RGB(0, 0, 0)
  18.                     ELSEIF grain(x, y) = 2 THEN
  19.                         PSET (x, y), _RGB(255, 255, 0)
  20.                     ELSEIF grain(x, y) = 3 THEN
  21.                         PSET (x, y), _RGB(0, 0, 255)
  22.                     ELSEIF grain(x, y) = 4 THEN
  23.                         PSET (x, y), _RGB(255, 0, 0)
  24.                     END IF
  25.                 END IF
  26.                 IF y >= 1 AND x >= 1 THEN
  27.                     IF grain(x, y) > 4 THEN
  28.                         grain(x - 1, y) = grain(x - 1, y) + 1
  29.                         grain(x + 1, y) = grain(x + 1, y) + 1
  30.                         grain(x, y + 1) = grain(x, y + 1) + 1
  31.                         grain(x, y - 1) = grain(x, y - 1) + 1
  32.                         grain(x, y) = grain(x, y) - 4
  33.  
  34.                         grain_back(x - 1, y) = grain(x - 1, y)
  35.                         grain_back(x + 1, y) = grain(x + 1, y)
  36.                         grain_back(x, y - 1) = grain(x, y - 1)
  37.                         grain_back(x, y + 1) = grain(x, y + 1)
  38.                         grain_back(x, y) = grain(x, y)
  39.                     END IF
  40.                 END IF
  41.         NEXT x, y
  42.     NEXT
  43.     SWAP grain, grain_back
  44.     _DISPLAY
  45.     '_LIMIT 60
  46.  

Screenshot_1.png

The above picture took 63 minute to render.
« Last Edit: March 04, 2019, 10:11:10 am by Ashish »
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sandpiles
« Reply #1 on: March 04, 2019, 05:43:23 pm »
Hi everyone! This month is going to be very serious and exhausting for me.
The below program shows a basic demo for Abelian Sandpile Model. https://en.wikipedia.org/wiki/Abelian_sandpile_model
 Please note that rendering this stuff to full size is very time consuming.
Code: QB64: [Select]
  1. '1 Grain -> Black
  2. '2 Grain -> Yellow
  3. '3 Grain -> Blue
  4. '4 Grain -> Red
  5. _TITLE "Sandpiles by Ashish"
  6. SCREEN _NEWIMAGE(200, 200, 32)
  7.  
  8. grain(_WIDTH / 2, _HEIGHT / 2) = 500000
  9. CLS , _RGB(255, 255, 255)
  10.  
  11.  
  12.     FOR i = 0 TO 500
  13.         FOR y = 1 TO _HEIGHT - 1
  14.             FOR x = 1 TO _WIDTH - 1
  15.                 IF i = 500 THEN
  16.                     IF grain(x, y) = 1 THEN
  17.                         PSET (x, y), _RGB(0, 0, 0)
  18.                     ELSEIF grain(x, y) = 2 THEN
  19.                         PSET (x, y), _RGB(255, 255, 0)
  20.                     ELSEIF grain(x, y) = 3 THEN
  21.                         PSET (x, y), _RGB(0, 0, 255)
  22.                     ELSEIF grain(x, y) = 4 THEN
  23.                         PSET (x, y), _RGB(255, 0, 0)
  24.                     END IF
  25.                 END IF
  26.                 IF y >= 1 AND x >= 1 THEN
  27.                     IF grain(x, y) > 4 THEN
  28.                         grain(x - 1, y) = grain(x - 1, y) + 1
  29.                         grain(x + 1, y) = grain(x + 1, y) + 1
  30.                         grain(x, y + 1) = grain(x, y + 1) + 1
  31.                         grain(x, y - 1) = grain(x, y - 1) + 1
  32.                         grain(x, y) = grain(x, y) - 4
  33.  
  34.                         grain_back(x - 1, y) = grain(x - 1, y)
  35.                         grain_back(x + 1, y) = grain(x + 1, y)
  36.                         grain_back(x, y - 1) = grain(x, y - 1)
  37.                         grain_back(x, y + 1) = grain(x, y + 1)
  38.                         grain_back(x, y) = grain(x, y)
  39.                     END IF
  40.                 END IF
  41.         NEXT x, y
  42.     NEXT
  43.     SWAP grain, grain_back
  44.     _DISPLAY
  45.     '_LIMIT 60
  46.  


Hi Ashish,

I ran your code and looks like symmetry is off. Try this:
Code: QB64: [Select]
  1. _TITLE "Sandpiles by Ashish mod for symmetry and color by B+ 2019-03-04"
  2. CONST w = &HFFFFFFFF
  3. CONST y4 = &HFFFFFF00
  4. CONST y3 = &HFFAA8811
  5. CONST y2 = &HFF774444
  6. CONST y1 = &HFF332266
  7.  
  8. SCREEN _NEWIMAGE(600, 600, 32)
  9. _SCREENMOVE 300, 100
  10. DIM grain(600, 600) AS _UNSIGNED LONG
  11. DIM ng(600, 600) AS _UNSIGNED LONG 'next generation grain
  12.  
  13. grain(300, 300) = 500000
  14. CLS , _RGB(255, 255, 255)
  15.  
  16.     FOR y = 1 TO 599
  17.         FOR x = 1 TO 599
  18.  
  19.             IF grain(x, y) = 1 THEN
  20.                 PSET (x, y), y1
  21.             ELSEIF grain(x, y) = 2 THEN
  22.                 PSET (x, y), y2
  23.             ELSEIF grain(x, y) = 3 THEN
  24.                 PSET (x, y), y3
  25.             ELSEIF grain(x, y) = 4 THEN
  26.                 PSET (x, y), y4
  27.             ELSEIF grain > 4 THEN
  28.                 PSET (x, y), w
  29.             END IF
  30.  
  31.             IF grain(x, y) > 4 THEN 'update next generation array NOT this generation array
  32.                 ng(x - 1, y) = ng(x - 1, y) + 1
  33.                 ng(x + 1, y) = ng(x + 1, y) + 1
  34.                 ng(x, y + 1) = ng(x, y + 1) + 1
  35.                 ng(x, y - 1) = ng(x, y - 1) + 1
  36.                 ng(x, y) = ng(x, y) - 4
  37.  
  38.             END IF
  39.     NEXT x, y
  40.  
  41.     'copy ng() into grain()  ' AFTER UPDATING ALL OF NG()
  42.     FOR y = 0 TO 600
  43.         FOR x = 0 TO 600
  44.             grain(x, y) = ng(x, y)
  45.         NEXT
  46.     NEXT
  47. LOOP WHILE grain(300, 300) > 4
  48.  
  49.  

Update after 1 hour run:
 
sandpile for 1hour plus.PNG


After 4 hours running:
 
Sandpile after 4 hours.PNG
« Last Edit: March 04, 2019, 09:33:58 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sandpiles
« Reply #2 on: March 04, 2019, 11:47:18 pm »
Update after 6 hour run:

 
Sandpile after 6+ hours.PNG

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sandpiles
« Reply #3 on: March 05, 2019, 09:00:33 am »
Oh!!!
Code: QB64: [Select]
  1.             ELSEIF grain > 4 THEN
  2.                 PSET (x, y), w
  3.  

That's why I never saw a white pixel in the middle! Ha! no biggy but should be:
Code: QB64: [Select]
  1.             ELSEIF grain(x, y) > 4 THEN
  2.                 PSET (x, y), w
  3.  

Append: Oh it makes a big difference, you can see where grains exceed 4 for the pixel ie watch the grains spread out better.
« Last Edit: March 05, 2019, 09:07:58 am by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sandpiles
« Reply #4 on: March 05, 2019, 09:36:33 am »
Pixels that are white (inside the pile) are places where the sand grains exceed 4:
 
Sandpile white pixel fix.PNG

Offline Ed Davis

  • Newbie
  • Posts: 40
    • View Profile
Re: Sandpiles
« Reply #5 on: March 05, 2019, 09:55:42 am »
Oh!!!
Code: QB64: [Select]
  1.             ELSEIF grain > 4 THEN
  2.                 PSET (x, y), w
  3.  

Why wasn't that a syntax error?  grain is declared as:
Code: QB64: [Select]
  1. DIM grain(600, 600) AS _UNSIGNED LONG
  2.  

Shouldn't the compiler have caught that, and saved you the trouble?   Just wondering ....

FellippeHeitor

  • Guest
Re: Sandpiles
« Reply #6 on: March 05, 2019, 09:58:35 am »
If he had added OPTION _EXPLICIT to the top of his program, the compiler would have warned of an undeclared variable being used. Without OPTION _EXPLICIT you simply have an array grain(600, 600) of type unsigned long and a variable grain of type single. All valid in BASIC.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sandpiles
« Reply #7 on: March 05, 2019, 11:51:22 am »
I have modified the color system again and magnified pixels to small boxes:
Code: QB64: [Select]
  1. _TITLE "Sandpiles by Ashish, mod #2 B+ 2019-03-04 new color system and magnification"
  2. ' from "Sandpiles by Ashish mod for symmetry and color by B+ 2019-03-04"
  3.  
  4. CONST w = &HFFFFFFFF
  5. CONST y4 = &HFFFFBB00
  6. CONST y3 = &HFFBB6600
  7. CONST y2 = &HFF884400
  8. CONST y1 = &HFF5500
  9. CONST b = &HFF000000
  10.  
  11. SCREEN _NEWIMAGE(600, 600, 32)
  12. _SCREENMOVE 300, 100
  13. DIM grain(300, 300) AS _UNSIGNED LONG
  14. DIM ng(300, 300) AS _UNSIGNED LONG 'next generation grain
  15.  
  16. grain(150, 150) = 500000
  17.  
  18.     FOR y = 1 TO 299
  19.         FOR x = 1 TO 299
  20.             IF grain(x, y) = 0 THEN
  21.                 LINE (x * 2, y * 2)-STEP(1, 1), b, BF
  22.             ELSEIF grain(x, y) = 1 THEN
  23.                 'PSET (x, y), y1
  24.                 LINE (x * 2, y * 2)-STEP(1, 1), y1, BF
  25.             ELSEIF grain(x, y) = 2 THEN
  26.                 'PSET (x, y), y2
  27.                 LINE (x * 2, y * 2)-STEP(1, 1), y2, BF
  28.             ELSEIF grain(x, y) = 3 THEN
  29.                 'PSET (x, y), y3
  30.                 LINE (x * 2, y * 2)-STEP(1, 1), y3, BF
  31.             ELSEIF grain(x, y) = 4 THEN
  32.                 'PSET (x, y), y4
  33.                 LINE (x * 2, y * 2)-STEP(1, 1), y4, BF
  34.             ELSEIF grain(x, y) > 4 AND grain(x, y) < 256 THEN
  35.                 'PSET (x, y), _RGB32(255, 255, grain(x, y))
  36.                 LINE (x * 2, y * 2)-STEP(1, 1), _RGB32(255, 255, grain(x, y)), BF
  37.             ELSEIF grain(x, y) > 255 THEN
  38.                 'PSET (x, y), w
  39.                 LINE (x * 2, y * 2)-STEP(1, 1), w, BF
  40.             END IF
  41.  
  42.             IF grain(x, y) > 4 THEN 'update next generation array NOT this generation array
  43.                 ng(x - 1, y) = ng(x - 1, y) + 1
  44.                 ng(x + 1, y) = ng(x + 1, y) + 1
  45.                 ng(x, y + 1) = ng(x, y + 1) + 1
  46.                 ng(x, y - 1) = ng(x, y - 1) + 1
  47.                 ng(x, y) = ng(x, y) - 4
  48.  
  49.             END IF
  50.     NEXT x, y
  51.  
  52.     'copy ng() into grain()  ' AFTER UPDATING ALL OF NG()
  53.     FOR y = 0 TO 300
  54.         FOR x = 0 TO 300
  55.             grain(x, y) = ng(x, y)
  56.         NEXT
  57.     NEXT
  58.     _LIMIT 300
  59. LOOP WHILE grain(150, 150) > 4
  60.  
  61.  
An hour's run:
 
Sandpiles mod 2.PNG

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Sandpiles
« Reply #8 on: March 06, 2019, 01:44:37 am »
Great bplus! Thanks for adding your contribution to this.
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials