Mandelbrot Fractal Code

Blitz3D Forums/Blitz3D Programming/Mandelbrot Fractal Code

Filax(Posted 2002) [#1]
Hi ! how i can zoom in the mandelbrot fractal ? i don't understand ? with XSide# and YSide# ?



The Code :
---------
Screen_Width=800
Screen_Height=600

Graphics Screen_Width,Screen_Height,16,2
SetBuffer BackBuffer()



; ------------------------
; Boucle principale
; ------------------------

maxcolor=255

leftside#=-2
top#=1.25

xside#=2.5
yside#=-2.5


xmax=640
ymax=480

xscale#=xside#/xmax
yscale#=yside#/ymax

For y=1 To ymax
For x=1 To xmax
cx#=x*xscale#+leftside#
cy#=y*yscale#+top#
zx#=0
zy#=0
colorcounter=0

While (zx#*zx#+zy#*zy#<4 And colorcounter<maxcolor)
tempx#=zx#*zx#-zy#*zy#+cx#
zy#=2*zx#*zy#+cy#
zx#=tempx#
colorcounter=colorcounter+1
Wend

Color 0,0,50+(colorcounter*4)

Plot x,y

Next
Flip
Next


WaitKey


Chevron(Posted 2002) [#2]
As far as I remember its just a case of changing yside, xside,leftside/top variables. If you wish to scale with the mouse correlate the x,y coord to between -2.5 and +2.5 e.t.c and load the variables and redraw.


Filax(Posted 2002) [#3]
Year !! :) thx ! but if you have time, can you put an example code ??


Filax(Posted 2002) [#4]
Another code with zoom (mouse) and moving with keyboard :
Post improvement !!!! plzzz




Screen_Width=640
Screen_Height=480

Graphics Screen_Width,Screen_Height,16,0
SetBuffer BackBuffer()



; ------------------------
; Boucle principale
; ------------------------

maxcolor=55
leftside#=-2
top#=1.25

xside#=2.5
yside#=-2.5


xmax=300
ymax=300

While Not KeyHit(1)

If MouseDown(1)
xside#=xside#-0.02
yside#=yside#+0.02

leftside#=leftside#+0.01
top#=top#-0.01
EndIf

If KeyDown(203) Then
leftside#=leftside#+0.01
EndIf

If KeyDown(205) Then
leftside#=leftside#-0.01
EndIf

If KeyDown(200) Then
top#=top#-0.01
EndIf

If KeyDown(208) Then
top#=top#+0.01
EndIf


xscale#=xside#/xmax
yscale#=yside#/ymax


For y=1 To ymax
For x=1 To xmax
cx#=x*xscale#+leftside#
cy#=y*yscale#+top#
zx#=0
zy#=0
colorcounter=0

While (zx#*zx#+zy#*zy#<4 And colorcounter<maxcolor)
tempx#=zx#*zx#-zy#*zy#+cx#
zy#=2*zx#*zy#+cy#
zx#=tempx#
colorcounter=colorcounter+1
Wend

Color 0,0,50+(colorcounter*2)

Plot x,y

Next

Next

Flip

Wend

WaitKey


fredborg(Posted 2002) [#5]
You can do it like this:


Screen_Width=640 
Screen_Height=480 

Graphics Screen_Width,Screen_Height,16,2 
SetBuffer BackBuffer() 



; ------------------------ 
; Boucle principale 
; ------------------------ 

maxcolor=255 

leftside#=-2 
top#=1.25 

xside#=2.5 
yside#=-2.5 

.again
xmax#=640 
ymax#=480 

xscale#=xside#/Float(xmax)
yscale#=yside#/Float(ymax)

For y=1 To ymax
	LockBuffer BackBuffer()
	For x=1 To xmax
		cx#=x*xscale#+leftside# 
		cy#=y*yscale#+top# 
		zx#=0 
		zy#=0 
		colorcounter=0 

		While (zx#*zx#+zy#*zy#<4 And colorcounter<maxcolor) 
			tempx#=zx#*zx#-zy#*zy#+cx# 
			zy#=2*zx#*zy#+cy# 
			zx#=tempx# 
			colorcounter=colorcounter+1 
		Wend 

		WritePixelFast x,y,50+(colorcounter*4),BackBuffer()
		
	Next 
	UnlockBuffer BackBuffer()
	Flip 
Next 

mandel=CreateImage(640,480)
CopyRect 0,0,640,480,0,0,BackBuffer(),ImageBuffer(mandel)

SetBuffer BackBuffer()
Color 255,255,255
mousepress = False
selection = False
MouseHit(1)

Repeat
	DrawImage mandel,0,0

	If Not mousepress
		If MouseHit(1)
			sx = MouseX()
			sy = MouseY()
			mousepress = True
		End If
	Else
		If MouseDown(1)
			ex = MouseX()
			ey = MouseY()
			
			If sx>ex
				startx 	= ex
				endx 	= sx
			Else
				startx 	= sx
				endx	= ex
			End If

			If sy>ey
				starty 	= ey
				endy 	= sy
			Else
				starty 	= sy
				endy	= ey
			End If
			
			Rect startx,starty,endx-startx,endy-starty,False
		Else
			selection = True
		End If
	End If
	
	Flip
Until selection 

FreeImage mandel

newxside#	 = xside#*Float((endx-startx)/Float(xmax))
newyside# 	 = yside#*Float((endy-starty)/Float(ymax))
newleftside# = leftside#+(xside#*Float(startx/Float(xmax)))
newtop#		 = top#+(yside#*Float(starty/Float(ymax)))

leftside#=newleftside 
top#=newtop

xside#=newxside
yside#=newyside

Goto again


There is a limit to how far you can zoom though (because of floating point precision), you could remove this limit by multiplying xside,yside,top, and leftside with a large number...

See ya,
Fredborg


Filax(Posted 2002) [#6]
Great code !!!!!!!!!!!!!!!!

Thanks for this example ;) See Ya !


Chevron(Posted 2002) [#7]
Yep thats it fredborg, nice code, although with a couple of small modifications it runs a lot faster, try this.


Screen_Width=640 
Screen_Height=480 

Graphics Screen_Width,Screen_Height,16,2 
SetBuffer BackBuffer() 



; ------------------------ 
; Boucle principale 
; ------------------------ 

maxcolor=255

leftside#=-2 
top#=1.25 

xside#=2.5 
yside#=-2.5 

.again
xmax#=640 
ymax#=480 

xscale#=xside#/Float(xmax)
yscale#=yside#/Float(ymax)
LockBuffer BackBuffer()

For y=1 To ymax
	
	For x=1 To xmax
		cx#=x*xscale#+leftside# 
		cy#=y*yscale#+top# 
		zx#=0 
		zy#=0 
		colorcounter=0 

		While (zx#*zx#+zy#*zy#<4 And colorcounter<maxcolor) 
			tempx#=zx#*zx#-zy#*zy#+cx# 
			zy#=2*zx#*zy#+cy# 
			zx#=tempx# 
			colorcounter=colorcounter+1 
		Wend 

		WritePixelFast x,y,50+(colorcounter*4),BackBuffer()
		
	Next 
	
	 
Next 

UnlockBuffer BackBuffer()
Flip
mandel=CreateImage(640,480)
CopyRect 0,0,640,480,0,0,BackBuffer(),ImageBuffer(mandel)

SetBuffer BackBuffer()
Color 255,255,255
mousepress = False
selection = False
MouseHit(1)

Repeat
	DrawImage mandel,0,0

	If Not mousepress
		If MouseHit(1)
			sx = MouseX()
			sy = MouseY()
			mousepress = True
		End If
	Else
		If MouseDown(1)
			ex = MouseX()
			ey = MouseY()
			
			If sx>ex
				startx 	= ex
				endx 	= sx
			Else
				startx 	= sx
				endx	= ex
			End If

			If sy>ey
				starty 	= ey
				endy 	= sy
			Else
				starty 	= sy
				endy	= ey
			End If
			
			Rect startx,starty,endx-startx,endy-starty,False
		Else
			selection = True
		End If
	End If
	
	Flip
Until selection 

FreeImage mandel

newxside#	 = xside#*Float((endx-startx)/Float(xmax))
newyside# 	 = yside#*Float((endy-starty)/Float(ymax))
newleftside# = leftside#+(xside#*Float(startx/Float(xmax)))
newtop#		 = top#+(yside#*Float(starty/Float(ymax)))

leftside#=newleftside 
top#=newtop

xside#=newxside
yside#=newyside

Goto again



Filax(Posted 2002) [#8]
Nice ;) But i don't understand where multiplying xside,yside,top, and leftside with a large number ??? After draw rectangular box ? or before ?


Chevron(Posted 2002) [#9]
To maintian the detail you also need to link the number of iliterations to the zoom factor, maxcolor in you case needs to be increased by a factor relevant to the zoom factor, this slows down he render, and is why some fractal explore's take weeks to generate a really deep fractal.


Filax(Posted 2002) [#10]
Ok ! i have another question with writepixelfast command ... How i can define Red Green Blue ?? because this commmand need an argb number ??? how i can generate it ? blithelp is little light about this...


BlitzSupport(Posted 2002) [#11]
Here ya go, Filax:


Print
Print "RGB..."
Print

r = 255
g = 0
b = 255

Print r
Print g
Print b

Print

; Turn R, G, B into argb...

argb = ((r Shl 16) + (g Shl 8) + b)

Print "Combined: " + argb

; Reset so we can prove they get recreated properly...

r = 0
g = 0
b = 0

Print
Print "Back to RGB..."
Print

; Turn argb back to R, G, B...

r = argb Shr 16 And %11111111
g = argb Shr 8 And %11111111
b = argb And %11111111

Print r
Print g
Print b




Filax(Posted 2002) [#12]
Thx :)


Here is the mandelbrot improvement : new palette
if anybody have idea for big zooming post it ;)






Screen_Width=800
Screen_Height=600

Graphics Screen_Width,Screen_Height,16,2
SetBuffer BackBuffer()

; ------------------
; Make palette
; ------------------

Procedure_DrawGradientBlock(0,0,255,5,50,0,255,0,0,0,0)

Dim col(256)

For i = 0 To 255
col(i)=ReadPixel(i,2) * 8
Next


; ------------
; Redraw
; ------------

maxcolor=255

leftside#=-2.0
top#=1.2

xside#=2.5
yside#=-2.5

.again
xmax#=Screen_Width
ymax#=Screen_Height

xscale#=xside#/Float(xmax)
yscale#=yside#/Float(ymax)

For y=0 To ymax

For x=0 To xmax
cx#=x*xscale#+leftside#
cy#=y*yscale#+top#
zx#=0
zy#=0
colorcounter=0

While (zx#*zx#+zy#*zy#<4 And colorcounter<maxcolor)
tempx#=zx#*zx#-zy#*zy#+cx#
zy#=2*zx#*zy#+cy#
zx#=tempx#
colorcounter=colorcounter+1
Wend

WritePixel x,y,Col(colorcounter)


Next
Flip
Next


; ----------------------------------------------------
; Wait for rectangular selection for zoom
; ----------------------------------------------------
mandel=CreateImage(640,480)
CopyRect 0,0,640,480,0,0,BackBuffer(),ImageBuffer(mandel)

SetBuffer BackBuffer()
Color 255,255,255
mousepress = False
selection = False
MouseHit(1)

Repeat
DrawImage mandel,0,0

If Not mousepress
If MouseHit(1)
sx = MouseX()
sy = MouseY()
mousepress = True
End If
Else
If MouseDown(1)
ex = MouseX()
ey = MouseY()

If sx>ex
startx = ex
endx = sx
Else
startx = sx
endx = ex
End If

If sy>ey
starty = ey
endy = sy
Else
starty = sy
endy = ey
End If

Rect startx,starty,endx-startx,endy-starty,False
Else
selection = True
End If
End If

Flip
Until selection

FreeImage mandel

newxside# = xside#*Float((endx-startx)/Float(xmax))
newyside# = yside#*Float((endy-starty)/Float(ymax))
newleftside# = leftside#+(xside#*Float(startx/Float(xmax)))
newtop# = top#+(yside#*Float(starty/Float(ymax)))

leftside#=newleftside
top#=newtop

xside#=newxside
yside#=newyside

Goto again

; ----------------------------
; Draw Gradient block
; ----------------------------
Function Procedure_DrawGradientBlock(Px,Py,Tx,Ty,StartRed#,StartGreen#,StartBlue#,EndRed#,EndGreen#,EndBlue#,Dir=0)
If Dir=0
Direction=Tx
Temp_X=Px
Temp_Y=Tx
Else
Direction=Ty
Temp_X=Py
Temp_Y=Ty
EndIf

GradientRed#=(EndRed-StartRed)/Direction
GradientGreen#=(EndGreen-StartGreen)/Direction
GradientBlue#=(EndBlue-StartBlue)/Direction

For Grad=Temp_X To Temp_X+Temp_Y
Color StartRed,StartGreen,StartBlue

If Dir=0
Line Grad,Py,Grad,Py+Ty
Else
Line Px,Grad,Px+Tx,Grad
EndIf

StartRed=StartRed+GradientRed
StartGreen=StartGreen+GradientGreen
StartBlue=StartBlue+GradientBlue
Next
End Function


Tri|Ga|De(Posted 2002) [#13]
Now all we need now is to cycle the colors
Just like the old Mandelbrot program on C64!


Filax(Posted 2002) [#14]
Before Cycling i need a good sample code for generate palette ;)


Filax(Posted 2003) [#15]
how i can do a nice color palet ?


mrjh(Posted 2006) [#16]
I am realy confused on how to make it so you can zoom in as many times as you want. It would be way cool if someone could post some code for that! Please!


Filax(Posted 2006) [#17]
you can't infinite zoom, because blitz is limited with float value !


Damien Sturdy(Posted 2006) [#18]
Woah, Back from the dead! :D


mrjh(Posted 2006) [#19]
Sorry for bringing it back after so long, but I am realy interested in this area and would like to have a good working example of this to show my math class.

Even if you can't infinite zoom, is there any way to zoom any farther?

Also, in many examples that I have seen, the colors change dynamically. How might I go about doing that?


Braincell(Posted 2006) [#20]
You could in theory make up your own data type known as "VERRRRRRRRRRRRRRRY LONNNNNNNNG integer" such as by using arrays. But you'd have to make the math operations for such long numbers by yourself. That's a math challenge. I started doing it once, a long time ago, to convert PI to a 60-symbol number system.


markcw(Posted 2006) [#21]
> Even if you can't infinite zoom, is there any way to zoom any farther?

it sounds like you haven't noticed there already is a zoom tool in the code. you have to leftclick and drag to see the rectangle.

I decided to neaten the code up a bit, so try this instead. I added zoom out on rightclick and an Esc key.

edit: oops, just noticed a mistake. the rectangle was a square but should have been a rectangle same dimensions as the screen, so zoom was distorting the image. I've updated the code below now.




mrjh(Posted 2006) [#22]
fredborg says
There is a limit to how far you can zoom though (because of floating point precision), you could remove this limit by multiplying xside,yside,top, and leftside with a large number...


What does he mean? I understand the part about the limit, but where in the code is he saying to multiply xside, yside, top, and leftside with a large number? How would that fix the problem?


markcw(Posted 2006) [#23]
> where in the code is he saying to multiply xside, yside, top, and leftside with a large number?

he didn't say where.


mrjh(Posted 2006) [#24]
muk, sorry for the misunderstanding, I already knew that there was a zoom tool in the code, I was wondering how to zoom more times before you can see the inacuracies of the blitz roundoff factor. Even if you cant zoom infinite times, it seems like you could be able to edit this code to zoom more times, doesen't it? I thought so, but I might be completely wrong.

Any thoughts on this subject would be welcome.


mrjh(Posted 2006) [#25]
> where in the code is he saying to multiply xside, yside, top, and leftside with a large number?

he didn't say where.


I know that he didn't say where, but do you understand what he means enough to tell me where?


markcw(Posted 2006) [#26]
well, as far as i can tell he meant you could zoom in a bit more if you multiply those values to get a higher degree of accuracy. however, the range of floats in blitz limits what depth you can get to with the algorithm. So even though you can zoom in a little bit more, you won't notice much (if any) difference. Here is what I came up with, I think this is what he meant.

edit: darn it. ok updated code.




mrjh(Posted 2006) [#27]
Thanks! If anyone else has any ideas to improve this, PLEASE post.


markcw(Posted 2006) [#28]
hehe, i tried working out how much you can zoom in by repeatedly dragging the mouse over 1/4 of the screen area which is 4 times more each time, correct? I could do 17 of these before the fractal started to get blocky. So I tried working what the zoom factor was on my calculator and it gave an error when I got to 17. :)

So i think unless you can change the algorithm (which i can't) or use a float with a higher degree of precision like Lenn suggested, then i'm afraid you're stuck with this limit.


mrjh(Posted 2006) [#29]
What did you type into your calculator?


mrjh(Posted 2006) [#30]
Also, for anybody else, I am suposed to present this program in math class tomarow and explain to them in detail how it works.

Any ideas of how to explain this in very simple terms so that anybody could understand?

Please post any advice that you might have soon!