June 19, 2019, 02:00:55 pm

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


The Julia Set

Started by GWS, March 28, 2012, 04:03:30 am

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

GWS

March 28, 2012, 04:03:30 am Last Edit: March 28, 2012, 05:11:35 am by GWS
Hi,

Here's another type of fractal based on the Mandelbrot set.

Whereas the Mandelbrot set has only one shape, the Julia set has an infinite number of shapes.

The controlling factor is a complex number that is chosen to be added at each iteration. 
You get a different pattern depending on the real and imaginary values that you choose.

Code Select

' Julia Set - GWS March 2012
' Click on the fractal to enlarge the pattern at that point.
' Click ReSet to return to the standard Mandlebrot display.

autodefine "OFF"

window w
int i,y,px,wstyle,run
int Width,Height
int mx,my,clickcount
float Z_re2,Z_im2,Z_re,Z_im,c_re,c_im
float x1,x2,y1,y2,j_re,j_im
float Rfac,Ifac,scale,Re,Im
pointer sprite1

int col[255]

for i = 0 to 63
col[0+i] = rgb(4*i,65-i,256-3*i)
col[64+i] = rgb(3*i,2*i,255-3*i)
col[128+i] = rgb(4*i,0,20*i)
col[192+i] = rgb(255-3*i,2*i-1,4*i)
next i

Width=1024
Height=768
run = 1

wstyle = @minbox|@noautodraw
openwindow w,-Width,0,Width,Height,wstyle,0,"Mandlebrot",&handler
setwindowcolor w,rgb(0,0,30)
' create a DirectX screen (no allowance is made for the user not having DirectX - just go for it) ...
attachscreen(w,Width,Height,0)

frontpen backBuffer,RGB(255,255,255)
setfont backbuffer,"Arial",10,500
drawmode backBuffer,@TRANSPARENT

control backbuffer,@BUTTON,"Reset",Width*0.1,Height*0.85,70,25,0, 1
control backbuffer,@BUTTON,"Exit",Width*0.8,Height*0.85,70,25,0, 2

' working sprite to draw on - and to refresh from if the window needs re-painting ..
sprite1 = CREATESPRITE(Width,Height,1,1)

flip
centerwindow w

scale = 1.0
clickcount = 0

' set a selected Julia complex number .. (you can choose any values between +/- 2.0)
j_re = -0.54
j_im = 0.2

' define the corners for two complex numbers (x1+iy1) and (x2+iy2) ..
x1 = -2
y1 = -1.5
x2 = 2
y2 = 1.5

' calculate factors to match screen pixels to corresponding complex values ..
Rfac = (x2 - x1)/(Width - 1)
Ifac = (y2 - y1)/(Height - 1)

gosub NewPattern
gosub redraw

waituntil run = 0
freesprite sprite1
closescreen
closewindow w
end

sub handler(),int
select @MESSAGE
case @idclosewindow
    run = 0
case @idcontrol
select @controlid
case 1
' set to display normal fractal ..
clickcount = 0
Scale = 1.0
x1 = -2
y1 = -1.5
x2 = 2
y2 = 1.5

' restore the original Julia real and imaginary values ..
j_re = -0.54
j_im = 0.2

setfocus w
gosub Redraw

case 2
run = 0
endselect

case @idkeydown
select @wparam
case 0x25 :'left arrow key (reduce j_re)
if (j_re > -1.99) then j_re = j_re - 0.01
case 0x27 :'right arrow key (increase j_re)
if (j_re < 1.99) then j_re = j_re + 0.01
case 0x26 :'up arrow key (increase j_im)
if (j_im < 1.99) then j_im = j_im + 0.01
case 0x28 :'down arrow key (decrease j_im)
if (j_im > -1.99) then j_im = j_im - 0.01
endselect

case @idkeyup
if (@wparam = 0x25|@wparam = 0x26|@wparam = 0x27|@wparam = 0x28)
' redo the display ..
gosub Redraw
endif

case @IDLBUTTONDN
' where was the mouse button clicked ..
mx = @MOUSEX
my = @MOUSEY
clickcount = clickcount + 1

' magnify by 20 at each click ..
Scale = clickcount * 20

' calculate the Real and Imaginary values corresponding to the point clicked ..
Re = x1 + @mousex * Rfac
Im = y2 - @mousey * Ifac

' plot from the selected Re +/- 1.5 , and from Im -/+ 1.2
x1 = Re - 1.5 / Scale
x2 = Re + 1.5 / Scale
y1 = Im - 1.2 / Scale
y2 = Im + 1.2 / Scale

' recalculate the Re and Im factors for the current scale ..
gosub Redraw

case @IDPAINT
drawspritexy sprite1,0,0
flip
endselect
return(0)

endsub


sub NewPattern
int NIter,clr,xm
' routine to generate a Julia set pattern ..
NIter = 50

SpriteToBuffer(sprite1)
Fillscreen RGB(0,0,20), SpriteBuffer
LOCKBUFFER SpriteBuffer

for y = 0 to Height - 1
c_im = y2 - y * Ifac

for px = 0 to (Width - 1)
c_re = x1 + px * Rfac
Z_re = c_re
Z_im = c_im

for i = 1 to NIter
xm = 3*(i%255) :' colour multiplier

Z_re2 = Z_re * Z_re
Z_im2 = Z_im * Z_im

if (Z_re2 + Z_im2 > 4)

if xm = NIter
clr = 0
else
clr = col[xm]
endif

WritePixelFast px,y,clr,SpriteBuffer

goto breaknext

endif

Z_im = 2 * Z_re * Z_im + j_re
Z_re = Z_re2 - Z_im2 + j_im

next i

label breaknext

next px
next y

UNLOCKBUFFER SpriteBuffer

flip
endsub


sub Redraw
' redraw the pattern after a change ..
Rfac = (x2 - x1)/(Width - 1)
Ifac = (y2 - y1)/(Height - 1)

gosub NewPattern

drawsprite sprite1

move backBuffer,20,20
print backBuffer,"Click on the Fractal to enlarge a section."
move backBuffer,20,40
print backBuffer,"Use Arrow keys to change the fractal"
move backBuffer,20,60
print backBuffer,"Keep key down for rapid changes"

move backbuffer,20,600
print backbuffer,"Real = ",j_re

move backbuffer,20,620
print backbuffer,"Imag = ",j_im

flip
endsub


The colouring method seems reasonable, but could probably be improved upon to smooth out the colours based on an HSV colouring scheme - just haven't figured out how to do it yet ..  ::)

Click anywhere on a pattern to zoom in.

Use the arrow keys to 'move around' in the Julia patterns .. the values change only slowly - if you want quicker changes, just hold the keys down longer.

best wishes, :)

Graham

Tomorrow may be too late ..

GWS

There's a cute pattern at: Real - 0.57,  Imag: 0.20 ..  ;D

You never know what you find as you move around this thing ..

all the best, :)

Graham
Tomorrow may be too late ..