Author Topic: Buddhabrot  (Read 7411 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Buddhabrot
« on: August 12, 2018, 11:52:40 am »
Implementation of https://en.wikipedia.org/wiki/Buddhabrot in Qb64.

Here's the code -
Code: QB64: [Select]
  1. 'Buddhabrot Fractal By Ashish 12 August, 2018
  2. 'https://en.wikipedia.org/wiki/Buddhabrot
  3.  
  4.  
  5. _TITLE "Buddhabrot Fractal"
  6.  
  7. SCREEN _NEWIMAGE(600, 600, 32)
  8. DIM r_plot(_WIDTH, _HEIGHT), g_plot(_WIDTH, _HEIGHT), b_plot(_WIDTH, _HEIGHT) 'for red,green and blue channels
  9. DIM SHARED seq_x(5000), seq_y(5000)
  10.  
  11.  
  12. PRINT "Generating density plot"
  13. max_itr = 1000000
  14. t# = TIMER
  15.  
  16. 'for speed
  17. WHILE itr < max_itr
  18.     FOR b = 0 TO 10
  19.         x = RND * _WIDTH
  20.         y = RND * _HEIGHT
  21.  
  22.         xx = map(x, 0, _WIDTH, -2, 2)
  23.         yy = map(y, 0, _HEIGHT, -2, 2)
  24.  
  25.         n = num_itr(xx, yy, 170) 'only those points, which escape to infinity are useful.
  26.  
  27.         'we are now going to store density of each series of this point.
  28.         'I've used 3 arrays for color and in each array, the density is stored for different number of iterations.
  29.         IF n > 1 THEN
  30.             FOR j = 0 TO n - 2
  31.                 px = ABS(INT(map(seq_x(j), -2, 2, 1, _WIDTH - 1)))
  32.                 py = ABS(INT(map(seq_y(j), -2, 2, 1, _HEIGHT - 1)))
  33.                 IF px > 0 AND px < _WIDTH AND py > 0 AND py < _HEIGHT THEN
  34.                     r_plot(px, py) = r_plot(px, py) + 1
  35.                     IF n < 40 THEN b_plot(px, py) = b_plot(px, py) + 1
  36.                     IF n < 100 THEN g_plot(px, py) = g_plot(px, py) + 1
  37.                 END IF
  38.             NEXT
  39.         END IF
  40.     NEXT
  41.     itr = itr + 1
  42.     IF itr MOD 10000 = 0 THEN PRINT ".";
  43. tt# = TIMER - t#
  44. 'NEXT x, y
  45.  
  46. FOR y = 0 TO _HEIGHT
  47.     FOR x = 0 TO _WIDTH
  48.         PSET (y, x), _RGB(r_plot(x, y), g_plot(x, y), b_plot(x, y))
  49. NEXT x, y
  50. PRINT tt#; "s"
  51.  
  52.  
  53. FUNCTION num_itr (x_0, y_0, max_itr)
  54.     x = 0: y = 0
  55.     x_n_1 = 0: y_n_1 = 0
  56.  
  57.     FOR i = 0 TO max_itr
  58.         x_n_1 = x * x - y * y + x_0
  59.         y_n_1 = 2 * x * y + y_0
  60.         x = x_n_1
  61.         y = y_n_1
  62.         seq_x(i) = x: seq_y(i) = y
  63.         IF ABS(x * x + y * y) > 4 THEN num_itr = i: EXIT FUNCTION
  64.     NEXT
  65.  
  66. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  67.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  68.  
  69.  



5x10^10.png

 This image is generated with this code of about 50000000000 cycles.

17x10^8_itr.png

This image is also generated with this code of about 1700000000 cycles

« Last Edit: August 12, 2018, 11:54:38 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: Buddhabrot
« Reply #1 on: August 12, 2018, 12:50:36 pm »
Hi Ashish,

That is a very nice version you have made!

You might enjoy comparing to this code I found somewhere:
Code: QB64: [Select]
  1. 'Buddhabrot by Antoni Gual 6/2003 agual@eic.ictnet.esB
  2. '------------------------------------------------------------------------------
  3. 'This different rendering of the Mandelbrot Set, created by Melinda Green
  4. ' reminds the shape of the classic sculpture of the sitting Buddha.
  5. '-----------------------------------------------------------------------------
  6. 'The number of calculations needed to obtain this shape is much bigger than
  7. ' for classic mandelbrot set.The complete drawing can take hours
  8. 'Good news is you can divide time needed by 5
  9. ' if you load qb with ffix library, a patch by V1ctor for the QB slow floting
  10. ' point operations. You can find ffix in my site among many others.
  11. '    www.geocities.com/antonigual/qbasic
  12. '
  13. ' You must uncomment the two lines invokking ffix,then call qb with:
  14. '  c:\qbpath\qb budabrot.bas /lc:\qbpath\ffix
  15. '-----------------------------------------------------------------------------
  16. 'Classic Mandelbrot is drawn by plotting the points in the complex plane where
  17. 'the Mandelbrot formula leads to a convergent series.
  18. '
  19. 'The BuddhaBrot is drawing by cumulating all intermediate points of the
  20. 'diverting Mandelbrot series.
  21. '----------------------------------------------------------------------------
  22. 'Two sites about Mandelbrot and its variants:
  23. 'http://mandelbrot.dazibao.free.fr/                     'Mandelbrot Set in QB
  24. 'http://www.superliminal.com/fractals/bbrot/bbrot.htm   'Melinda Green's site
  25. '
  26. 'Have Fun!...E-mail me yor improvements on this program..
  27. '------------------------------------------------------------------------------
  28. 'If you are using ffix, uncomment the next two lines to boost speed x 5
  29. ''DECLARE SUB ffix
  30. ''ffix
  31.  
  32.  
  33. 'set palette made of shades of green
  34. OUT &H3C8, 0
  35. FOR c = 0 TO 254
  36.     temp = c / 4
  37.     OUT &H3C9, 0
  38.     OUT &H3C9, temp
  39.     OUT &H3C9, 0
  40.  
  41. 'plus awhite color for the time display
  42. OUT &H3C9, 63
  43. OUT &H3C9, 63
  44. OUT &H3C9, 63
  45. COLOR 255
  46.  
  47.  
  48. 'If you increase niter you will have a crisper but slower rendering
  49. CONST niter = 300
  50.  
  51. 'set up arrays to save intermediate points
  52. DIM real(niter)
  53. DIM imag(niter)
  54. t! = TIMER
  55.  
  56.     'seed the mandelbrot series with random points of complex plane
  57.     x = 4 * RND - 2
  58.     y = 4 * RND - 2
  59.     im = 0: re = 0: re2 = 0: im2 = 0
  60.     diverts% = 0
  61.     'iterate the mandelbrot formula
  62.     FOR iter% = 0 TO niter
  63.         im = 2 * re * im + x
  64.         re = re2 - im2 + y
  65.         'Save the intermediate points of the series to arrays
  66.         'IF re > 1E+21 THEN EXIT FOR
  67.         'IF im > 1E+21 THEN EXIT FOR
  68.         real(iter%) = re
  69.         imag(iter%) = im
  70.         im2 = im * im
  71.         re2 = re * re
  72.         'If the seed point leads to a diverting series, we are interested
  73.         IF re2 + im2 > 4 THEN diverts% = 1: EXIT FOR
  74.     NEXT
  75.  
  76.     'Plot to screen the points of the DIVERGENT series
  77.     IF diverts% THEN
  78.         FOR it% = 0 TO iter%
  79.             xs% = CINT(imag(it%) * 80) + 160
  80.             ys% = CINT(real(it%) * 80) + 120
  81.  
  82.             pp% = POINT(xs%, ys%)
  83.             IF pp% < 255 THEN PSET (xs%, ys%), pp% + 1
  84.         NEXT
  85.         'To display rendering time, not really needed
  86.         np% = (np% + 1) AND &HFF
  87.         IF np% = 0 THEN LOCATE , 1: PRINT USING "####.#"; TIMER - t!;
  88.     END IF
  89.  

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Buddhabrot
« Reply #2 on: August 12, 2018, 02:29:39 pm »
neat

FellippeHeitor

  • Guest
Re: Buddhabrot
« Reply #3 on: August 12, 2018, 06:39:12 pm »
Math is a thing of beauty, right?

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Buddhabrot
« Reply #4 on: August 13, 2018, 10:08:52 am »
Thank you Bplus, Vincent and Fellippe!
@bplus
That code is quite good. I like the way it renders in real time. Following this, I edited my code so that it can also
render the fractal in real time. Now, you are also allowed to enter you own number of iteration per pixel.

Code: QB64: [Select]
  1. 'Buddhabrot Fractal By Ashish 12 August, 2018
  2. 'https://en.wikipedia.org/wiki/Buddhabrot
  3. 'EDITED : 13 August, 2018
  4. 'Now renders in real time, as well as allow you to choose number of iterations per pixel.
  5.  
  6.  
  7. _TITLE "Buddhabrot Fractal"
  8.  
  9. SCREEN _NEWIMAGE(600,600, 32)
  10. DIM r_plot(_WIDTH, _HEIGHT), g_plot(_WIDTH, _HEIGHT), b_plot(_WIDTH, _HEIGHT) 'for red,green and blue channels
  11.  
  12.  
  13. PRINT "Enter the maximum iteration for each pixel : "
  14. INPUT temp
  15. DIM SHARED seq_x(temp), seq_y(temp)
  16.  
  17. rf! = RND: gf! = RND: bf! = RND
  18.  
  19.  
  20. max_itr = 1000000
  21. t# = TIMER
  22.  
  23. 'for speed
  24. WHILE itr < max_itr
  25.     FOR b = 0 TO 15
  26.         x = RND * _WIDTH
  27.         y = RND * _HEIGHT
  28.  
  29.         xx = map(x, 0, _WIDTH, -2, 2)
  30.         yy = map(y, 0, _HEIGHT, -2, 2)
  31.  
  32.         n = num_itr(xx, yy, temp) 'only those points, which escape to infinity are useful.
  33.  
  34.         'we are now going to store density of each series of this point.
  35.         'I've used 3 arrays for color and in each array, the density is stored for different number of iterations.
  36.         IF n > 1 THEN
  37.             FOR j = 0 TO n - 2
  38.                 px = ABS(INT(map(seq_x(j), -2, 2, 1, _WIDTH - 1)))
  39.                 py = ABS(INT(map(seq_y(j), -2, 2, 1, _HEIGHT - 1)))
  40.                 IF px > 0 AND px < _WIDTH AND py > 0 AND py < _HEIGHT THEN
  41.                     IF n < temp * rf! THEN r_plot(px, py) = r_plot(px, py) + 1
  42.                     IF n < temp * bf! THEN b_plot(px, py) = b_plot(px, py) + 1
  43.                     IF n < temp * gf! THEN g_plot(px, py) = g_plot(px, py) + 1
  44.                     PSET (py, px), _RGB(0, 0, 0)
  45.                     PSET (py, px), _RGB(r_plot(px, py), g_plot(px, py), b_plot(px, py))
  46.                 END IF
  47.             NEXT
  48.         END IF
  49.     NEXT
  50.     itr = itr + 1
  51.     IF itr MOD 10000 = 0 THEN _DISPLAY
  52.  
  53.  
  54. FUNCTION num_itr (x_0, y_0, max_itr)
  55.     x = 0: y = 0
  56.     x_n_1 = 0: y_n_1 = 0
  57.  
  58.     FOR i = 0 TO max_itr
  59.         x_n_1 = x * x - y * y + x_0
  60.         y_n_1 = 2 * x * y + y_0
  61.         x = x_n_1
  62.         y = y_n_1
  63.         seq_x(i) = x: seq_y(i) = y
  64.         IF ABS(x * x + y * y) > 4 THEN num_itr = i: EXIT FUNCTION
  65.     NEXT
  66.  
  67. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  68.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  69.  
  70.  
  71.  



20_itr_per_pixel.png

Image is generated with 20 iterations per pixel. As the number of iterations increases, the fractal
becomes more smooth and diverse.

« Last Edit: August 13, 2018, 10:11:24 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: Buddhabrot
« Reply #5 on: August 13, 2018, 12:24:52 pm »
Nice mod Ashish,

It sure beats watching dots go across screen for awhile.

I recommend CLS after input, leave checking alone specially now that it draws in real time, you don't need the speed so much because it's nice to watch image develop.

I like how there is a color change from just one increment if you pick a low iteration number, eg 20, 25, 26 so each run is unique.

There is ideal range for numbers eg 1000 runs too long after a certain whiteness is reached and 10000 just seems too slow  without anything really new or significant developing (which was when I was looking to check out but Alt+F4 did not work!).

All in all, I'd mark this you "best answer" so far.
« Last Edit: August 13, 2018, 12:26:18 pm by bplus »

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Buddhabrot
« Reply #6 on: August 13, 2018, 05:19:23 pm »
Yeah, nice mod Ashish.  Do you think you can make it so that you could zoom in and see the smaller details in this beautiful fractal?

Marked as best answer by Ashish on August 15, 2018, 09:00:43 am

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Buddhabrot
« Reply #7 on: August 14, 2018, 12:56:17 pm »
There is ideal range for numbers eg 1000 runs too long after a certain whiteness is reached and 10000 just seems too slow  without anything really new or significant developing (which was when I was looking to check out but Alt+F4 did not work!).
Buddhabrot can take hour to render. ;)
See the image on wikipedia having 20,000 and 1,000,000 iterations per pixel.



@Vincent
Now, the program support zooming feature. Zoom into the wonderful world of Buddhabrot!

Code: QB64: [Select]
  1. 'Buddhabrot Fractal By Ashish 12 August, 2018
  2. 'https://en.wikipedia.org/wiki/Buddhabrot
  3. 'EDITED : 13 August, 2018
  4. 'Now renders in real time, as well as allow you to choose number of iterations per pixel.
  5. 'EDITED : 14 Augist, 2018
  6. 'Added Zooming Feature
  7.  
  8.  
  9. _TITLE "Buddhabrot Fractal"
  10.  
  11. TYPE vec2
  12.     x AS SINGLE
  13.     y AS SINGLE
  14.  
  15. SCREEN _NEWIMAGE(500, 500, 32)
  16. DIM r_plot(_WIDTH, _HEIGHT), g_plot(_WIDTH, _HEIGHT), b_plot(_WIDTH, _HEIGHT) 'for red,green and blue channels
  17.  
  18. DIM canvas&, curr
  19. canvas& = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  20.  
  21.  
  22. PRINT "Enter the maximum iteration for each pixel : "
  23. INPUT temp
  24. DIM SHARED seq(temp) AS vec2
  25.  
  26.  
  27. rf! = RND: gf! = RND: bf! = RND
  28.  
  29.  
  30. max_itr = 1000000
  31. cx1 = -2: cy1 = -2
  32. cx2 = 2: cy2 = 2
  33. inc = 1
  34.  
  35. 'for speed
  36. '$CHECKING:OFF
  37.  
  38.     WHILE itr < max_itr
  39.         FOR b = 0 TO 15
  40.             x = RND * _WIDTH
  41.             y = RND * _HEIGHT
  42.  
  43.             xx = map(x, 0, _WIDTH, cx1, cx2)
  44.             yy = map(y, 0, _HEIGHT, cy1, cy2)
  45.  
  46.             n = num_itr(xx, yy, temp) 'only those points, which escape to infinity are useful.
  47.  
  48.             'we are now going to store density of each series of this point.
  49.             'I've used 3 arrays for color and in each array, the density is stored for different number of iterations.
  50.             IF n > 1 THEN
  51.                 FOR j = 0 TO n - 2
  52.                     px = ABS(INT(map(seq(j).x, cx1, cx2, 1, _WIDTH - 1)))
  53.                     py = ABS(INT(map(seq(j).y, cy1, cy2, 1, _HEIGHT - 1)))
  54.                     IF px > 0 AND px < _WIDTH AND py > 0 AND py < _HEIGHT THEN
  55.  
  56.                         IF n < temp * rf! THEN r_plot(px, py) = r_plot(px, py) + inc
  57.                         IF n < temp * bf! THEN b_plot(px, py) = b_plot(px, py) + inc
  58.                         IF n < temp * gf! THEN g_plot(px, py) = g_plot(px, py) + inc
  59.                         PSET (py, px), _RGB(0, 0, 0)
  60.                         PSET (py, px), _RGB(r_plot(px, py), g_plot(px, py), b_plot(px, py))
  61.                     END IF
  62.                 NEXT
  63.             END IF
  64.         NEXT
  65.         itr = itr + 1
  66.         IF itr MOD 10000 = 0 THEN _DISPLAY
  67.         rendered = 1
  68.     WEND
  69.     IF rendered = 1 THEN
  70.         _FREEIMAGE canvas&
  71.         canvas& = _COPYIMAGE(0)
  72.         rendered = 0
  73.     END IF
  74.  
  75.     CLS
  76.     _PUTIMAGE , canvas&
  77.  
  78.     bx1 = _MOUSEX - 50: by1 = _MOUSEY - 50
  79.     bx2 = _MOUSEX + 50: by2 = _MOUSEY + 50
  80.  
  81.     LINE (bx1, by1)-(bx2, by2), _RGB(255, 255, 0), B
  82.  
  83.  
  84.         itr = 0
  85.         bx1 = -2 * (bx1 / _WIDTH): bx2 = ABS(bx1)
  86.         by1 = bx1: by2 = bx2
  87.  
  88.         cx1 = bx1: cx2 = bx2: cy1 = by1: cy2 = by2
  89.         ERASE r_plot, g_plot, b_plot
  90.         DIM r_plot(_WIDTH, _HEIGHT), g_plot(_WIDTH, _HEIGHT), b_plot(_WIDTH, _HEIGHT)
  91.         CLS
  92.         inc = inc + .1
  93.     END IF
  94.  
  95.  
  96.     _DISPLAY
  97.     _LIMIT 40
  98.  
  99. FUNCTION num_itr (x_0, y_0, max_itr)
  100.     x = 0: y = 0
  101.     x_n_1 = 0: y_n_1 = 0
  102.  
  103.     FOR i = 0 TO max_itr
  104.         x_n_1 = x * x - y * y + x_0
  105.         y_n_1 = 2 * x * y + y_0
  106.         x = x_n_1
  107.         y = y_n_1
  108.         seq(i).x = x: seq(i).y = y
  109.         IF ABS(x * x + y * y) > 4 THEN num_itr = i: EXIT FUNCTION
  110.     NEXT
  111.  
  112. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  113.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  114.  
  115.  



Screenshot_1.png

Selecting the area for zooming.



 
20_itr_per_pixel.png

Zoomed Fractal
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 _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Buddhabrot
« Reply #8 on: August 14, 2018, 08:56:34 pm »
Nice job, hashish. With this fractal, unlike mandelbrot and other escape time fractals, the pixels in your current field of zoom are not the only ones contributing to it.  So you have to guess with some math tricks which pixels are contributing to the current field of vision otherwise you lose density and details.  There's a program that seems to do it well and is GPU accelerated:

https://fractalforums.org/other/55/buddhabrot-magnifier-a-realtime-buddhabrot-zoomer/384

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Buddhabrot
« Reply #9 on: August 15, 2018, 12:00:05 pm »
@Vincent
Hi. I tried to store the the pixels which are contributing to other pixel in a 3-dimensional array (which was actually cumbersome) for adding
more detail as we zoom. However, it broke, instead of working. Maybe, I will try to make a good one with Advance OpenGL and OpenCL in future
just like the GPU program you mention.
if (Me.success) {Me.improve()} else {Me.tryAgain()}


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