Author Topic: Lemon explorer  (Read 7032 times)

0 Members and 1 Guest are viewing this topic.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Lemon explorer
« on: March 19, 2018, 07:01:44 am »
Implementation of http://paulbourke.net/fractals/lemon/

Code: QB64: [Select]
  1. defint a-z
  2.  
  3. const sw = 640
  4. const sh = 480
  5.  
  6. dim shared mx,my,mbl,mbr,mw
  7.  
  8. dim uuu as double, vvv as double
  9. z = 0.01
  10. zz = 0.1
  11.  
  12. p1 = _newimage(sw, sh, 32)
  13. screen _newimage(sw, sh, 32)
  14.  
  15. redraw = -1
  16. iter = 100
  17.  
  18.         mw = 0
  19.         getMouse
  20.  
  21.         if redraw then
  22.                 line(0,0)-(sw,sh),_rgb(0,0,0),bf
  23.                 for y = 0 to sh-1
  24.                 for x = 0 to sw-1
  25.  
  26.                         xx = (x - sw/2)*z + x0
  27.                         yy = (y - sh/2)*z + y0
  28.                         u = yy
  29.                         v = xx
  30.                         j=0
  31.                         for i = 0 to iter
  32.                                 cmul uuu,vvv,u,v,u,v
  33.                                 cmul uu,vv,uuu,vvv,yy,xx
  34.                                 cmul uu,vv,uu,vv,uuu+1,vvv
  35.                                 uuu=uuu-1
  36.                                 cmul uuu,vvv,uuu,vvv,uuu,vvv
  37.                                 cdiv uu,vv,uu,vv,uuu,vvv
  38.  
  39.                                 if uu*uu + vv*vv > 10^10 then
  40.                                         i = iter
  41.                                         exit for
  42.                                 end if
  43.                                 if abs(u-uu)<0.00001 and abs(v-vv)<0.00001 then
  44.                                         j = j + 1
  45.                                 else
  46.                                         j = 0
  47.                                 end if
  48.                                 if j > 4 then exit for
  49.  
  50.                                 u = uu
  51.                                 v = vv
  52.                         next
  53.                         if i < iter then
  54.                                 c = 255-10*i
  55.                                 pset(x, y), _rgb(c,c,c)
  56.                         end if
  57.                 next
  58.                 next
  59.  
  60.                 'locate 1,1
  61.                 'print "iter =";iter
  62.  
  63.                 _dest p1
  64.                 _putimage , 0
  65.                 _dest 0
  66.  
  67.                 _putimage , p1
  68.                 _autodisplay
  69.  
  70.                 redraw = 0
  71.         end if
  72.  
  73.         if mw < 0 then
  74.                 zz = zz + 0.01
  75.         elseif mw > 0 then
  76.                 if zz > 0.01 then zz = zz - 0.01
  77.         end if
  78.  
  79.         'draw box
  80.         if omx <> mx or omy <> my or mw <> 0 then
  81.                 _putimage , p1
  82.                 line (mx - (sw*zz/2), my - (sh*zz/2))-step(sw*zz,sh*zz),_rgb(255,255,255),b
  83.                 _autodisplay
  84.  
  85.                 omx = mx
  86.                 omy = my
  87.         end if
  88.  
  89.         if mbl then
  90.                 do
  91.                         getMouse
  92.                 loop while mbl
  93.  
  94.                 x0 = x0 + (mx - sw/2)*z
  95.                 y0 = y0 - (sh/2 - my)*z
  96.                 z = z*zz
  97.                 redraw = -1
  98.         elseif mbr then
  99.                 do
  100.                         getMouse
  101.                 loop while mbr
  102.  
  103.                 x0 = x0 + (mx - sw/2)*z
  104.                 y0 = y0 - (sh/2 - my)*z
  105.                 z = z/zz
  106.                 redraw = -1
  107.         end if
  108.  
  109.         k = _keyhit
  110.         if k = 43 then
  111.                 iter = iter + 50
  112.                 redraw = -1
  113.         elseif k = 45 then
  114.                 if iter > 50 then iter = iter - 50
  115.                 redraw = -1
  116.         end if
  117.  
  118. loop until k = 27
  119.  
  120. sub getMouse ()
  121.         do
  122.                 mx = _mousex
  123.                 my = _mousey
  124.                 mbl = _mousebutton(1)
  125.                 mbr = _mousebutton(2)
  126.                 mw = mw + _mousewheel
  127.         loop while _mouseinput
  128.  
  129. sub cmul (u as double, v as double, x as double, y as double, a as double, b as double)
  130.         uu# = x*a - y*b
  131.         vv# = x*b + y*a
  132.         u = uu#
  133.         v = vv#
  134.  
  135. sub cdiv (u as double, v as double, x as double, y as double, a as double, b as double)
  136.         d# = a*a + b*b
  137.         uu# = (x*a + y*b)/d#
  138.         vv# = (y*a - x*b)/d#
  139.         u = uu#
  140.         v = vv#
  141.  
« Last Edit: March 19, 2018, 07:04:29 am by v »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Lemon explorer
« Reply #1 on: March 19, 2018, 07:04:33 am »
This is amazing! Good work Vince!
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 Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Lemon explorer
« Reply #2 on: March 19, 2018, 07:09:28 am »
Hi. I made some changes in your code to look colorful.
Code: QB64: [Select]
  1. 'originally by Vince
  2. 'Edited by Ashish
  3.  
  4. DEFINT A-Z
  5.  
  6. CONST sw = 640
  7. CONST sh = 480
  8.  
  9. DIM SHARED mx, my, mbl, mbr, mw
  10.  
  11. DIM uuu AS DOUBLE, vvv AS DOUBLE
  12. z = 0.01
  13. zz = 0.1
  14.  
  15. p1 = _NEWIMAGE(sw, sh, 32)
  16. SCREEN _NEWIMAGE(sw, sh, 32)
  17.  
  18. redraw = -1
  19. iter = 100
  20.  
  21.     mw = 0
  22.     getMouse
  23.  
  24.     IF redraw THEN
  25.         LINE (0, 0)-(sw, sh), _RGB(0, 0, 0), BF
  26.         FOR y = 0 TO sh - 1
  27.             FOR x = 0 TO sw - 1
  28.  
  29.                 xx = (x - sw / 2) * z + x0
  30.                 yy = (y - sh / 2) * z + y0
  31.                 u = yy
  32.                 v = xx
  33.                 j = 0
  34.                 FOR i = 0 TO iter
  35.                     cmul uuu, vvv, u, v, u, v
  36.                     cmul uu, vv, uuu, vvv, yy, xx
  37.                     cmul uu, vv, uu, vv, uuu + 1, vvv
  38.                     uuu = uuu - 1
  39.                     cmul uuu, vvv, uuu, vvv, uuu, vvv
  40.                     cdiv uu, vv, uu, vv, uuu, vvv
  41.  
  42.                     IF uu * uu + vv * vv > 10 ^ 10 THEN
  43.                         i = iter
  44.                         EXIT FOR
  45.                     END IF
  46.                     IF ABS(u - uu) < 0.00001 AND ABS(v - vv) < 0.00001 THEN
  47.                         j = j + 1
  48.                     ELSE
  49.                         j = 0
  50.                     END IF
  51.                     IF j > 4 THEN EXIT FOR
  52.  
  53.                     u = uu
  54.                     v = vv
  55.                 NEXT
  56.                 IF i < iter THEN
  57.                     c = 360 - 10 * i
  58.                     PSET (x, y), hsb(c, 200, 128, 255)
  59.                 END IF
  60.             NEXT
  61.         NEXT
  62.  
  63.         'locate 1,1
  64.         'print "iter =";iter
  65.  
  66.         _DEST p1
  67.         _PUTIMAGE , 0
  68.         _DEST 0
  69.  
  70.         _PUTIMAGE , p1
  71.         _AUTODISPLAY
  72.  
  73.         redraw = 0
  74.     END IF
  75.  
  76.     IF mw < 0 THEN
  77.         zz = zz + 0.01
  78.     ELSEIF mw > 0 THEN
  79.         IF zz > 0.01 THEN zz = zz - 0.01
  80.     END IF
  81.  
  82.     'draw box
  83.     IF omx <> mx OR omy <> my OR mw <> 0 THEN
  84.         _PUTIMAGE , p1
  85.         LINE (mx - (sw * zz / 2), my - (sh * zz / 2))-STEP(sw * zz, sh * zz), _RGB(255, 255, 255), B
  86.         _AUTODISPLAY
  87.  
  88.         omx = mx
  89.         omy = my
  90.     END IF
  91.  
  92.     IF mbl THEN
  93.         DO
  94.             getMouse
  95.         LOOP WHILE mbl
  96.  
  97.         x0 = x0 + (mx - sw / 2) * z
  98.         y0 = y0 - (sh / 2 - my) * z
  99.         z = z * zz
  100.         redraw = -1
  101.     ELSEIF mbr THEN
  102.         DO
  103.             getMouse
  104.         LOOP WHILE mbr
  105.  
  106.         x0 = x0 + (mx - sw / 2) * z
  107.         y0 = y0 - (sh / 2 - my) * z
  108.         z = z / zz
  109.         redraw = -1
  110.     END IF
  111.  
  112.     k = _KEYHIT
  113.     IF k = 43 THEN
  114.         iter = iter + 50
  115.         redraw = -1
  116.     ELSEIF k = 45 THEN
  117.         IF iter > 50 THEN iter = iter - 50
  118.         redraw = -1
  119.     END IF
  120.  
  121. LOOP UNTIL k = 27
  122.  
  123. SUB getMouse ()
  124.     DO
  125.         mx = _MOUSEX
  126.         my = _MOUSEY
  127.         mbl = _MOUSEBUTTON(1)
  128.         mbr = _MOUSEBUTTON(2)
  129.         mw = mw + _MOUSEWHEEL
  130.  
  131. SUB cmul (u AS DOUBLE, v AS DOUBLE, x AS DOUBLE, y AS DOUBLE, a AS DOUBLE, b AS DOUBLE)
  132.     uu# = x * a - y * b
  133.     vv# = x * b + y * a
  134.     u = uu#
  135.     v = vv#
  136.  
  137. SUB cdiv (u AS DOUBLE, v AS DOUBLE, x AS DOUBLE, y AS DOUBLE, a AS DOUBLE, b AS DOUBLE)
  138.     d# = a * a + b * b
  139.     uu# = (x * a + y * b) / d#
  140.     vv# = (y * a - x * b) / d#
  141.     u = uu#
  142.     v = vv#
  143.  
  144.  
  145. 'from p5js.bas
  146. FUNCTION hsb~& (__H AS _FLOAT, __S AS _FLOAT, __B AS _FLOAT, A AS _FLOAT)
  147.     DIM H AS _FLOAT, S AS _FLOAT, B AS _FLOAT
  148.  
  149.     H = map(__H, 0, 255, 0, 360)
  150.     S = map(__S, 0, 255, 0, 1)
  151.     B = map(__B, 0, 255, 0, 1)
  152.  
  153.     IF S = 0 THEN
  154.         hsb~& = _RGBA32(B * 255, B * 255, B * 255, A)
  155.         EXIT FUNCTION
  156.     END IF
  157.  
  158.     DIM fmx AS _FLOAT, fmn AS _FLOAT
  159.     DIM fmd AS _FLOAT, iSextant AS INTEGER
  160.     DIM imx AS INTEGER, imd AS INTEGER, imn AS INTEGER
  161.  
  162.     IF B > .5 THEN
  163.         fmx = B - (B * S) + S
  164.         fmn = B + (B * S) - S
  165.     ELSE
  166.         fmx = B + (B * S)
  167.         fmn = B - (B * S)
  168.     END IF
  169.  
  170.     iSextant = INT(H / 60)
  171.  
  172.     IF H >= 300 THEN
  173.         H = H - 360
  174.     END IF
  175.  
  176.     H = H / 60
  177.     H = H - (2 * INT(((iSextant + 1) MOD 6) / 2))
  178.  
  179.     IF iSextant MOD 2 = 0 THEN
  180.         fmd = (H * (fmx - fmn)) + fmn
  181.     ELSE
  182.         fmd = fmn - (H * (fmx - fmn))
  183.     END IF
  184.  
  185.     imx = _ROUND(fmx * 255)
  186.     imd = _ROUND(fmd * 255)
  187.     imn = _ROUND(fmn * 255)
  188.  
  189.     SELECT CASE INT(iSextant)
  190.         CASE 1
  191.             hsb~& = _RGBA32(imd, imx, imn, A)
  192.         CASE 2
  193.             hsb~& = _RGBA32(imn, imx, imd, A)
  194.         CASE 3
  195.             hsb~& = _RGBA32(imn, imd, imx, A)
  196.         CASE 4
  197.             hsb~& = _RGBA32(imd, imn, imx, A)
  198.         CASE 5
  199.             hsb~& = _RGBA32(imx, imn, imd, A)
  200.         CASE ELSE
  201.             hsb~& = _RGBA32(imx, imd, imn, A)
  202.     END SELECT
  203.  
  204.  
  205. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  206.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  207.  
  208.  
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 Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Lemon explorer
« Reply #3 on: March 19, 2018, 06:47:18 pm »
It's both very nice. I imagined the picture turned 90 degrees :-D and what then reminds it? :-D

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Lemon explorer
« Reply #4 on: March 20, 2018, 06:48:06 am »
Yeah I think he's ^ right. Turn my head 90 degrees and suddenly my middle school nickname emerges: the Cherry Explorer
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Lemon explorer
« Reply #5 on: March 20, 2018, 09:15:41 am »
There should be a way to preserve detail as focus in more and more (but I am thinking Mandelbrot).

I will look into it. ;)
« Last Edit: March 20, 2018, 09:19:17 am by bplus »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Lemon explorer
« Reply #6 on: March 20, 2018, 11:36:29 am »
It's both very nice. I imagined the picture turned 90 degrees :-D and what then reminds it? :-D
What does it reminds?
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: Lemon explorer
« Reply #7 on: March 20, 2018, 01:18:18 pm »
Hi Ashish, It reminds me of "Paradise by the Dashboard Light" when I am remembering my adolescent days.

Here is a link to the discussion about keeping up with the detail of Mandelbrot when exploring:
There is nice formula for number of iterations needed:
http://retrogamecoding.org/board/index.php?topic=433.0

Ha! just past the 2nd anniversary of my Mandelbrot Explorer.

Next study to see if this still applies to this explorer.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Lemon explorer
« Reply #8 on: March 20, 2018, 08:53:08 pm »
Here is a link to the discussion about keeping up with the detail of Mandelbrot when exploring:
There is nice formula for number of iterations needed:
http://retrogamecoding.org/board/index.php?topic=433.0

Increasing the number of iterations, defined by variable iter in the code, will expose more detail in the previously black regions.  The number of iterations required to increase the detail depends on the location in the fractal and I don't think that it's a simple function of zoom level.  Eventually you might run out of DOUBLE precision and will have to implement your own higher precision routines (or use an existing library like gmplib).  There are methods to reduce the number of larger precision calculations, this technique is described in the following paper particularly for the mandelbrot set: http://superfractalthing.co.nf/sft_maths.pdf.  You could use the same method for other variants but it might be quite tricky for this case.