Mandelbrot Fractal Code
Blitz3D Forums/Blitz3D Programming/Mandelbrot Fractal Code
| ||
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 |
| ||
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. |
| ||
Year !! :) thx ! but if you have time, can you put an example code ?? |
| ||
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 |
| ||
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 |
| ||
Great code !!!!!!!!!!!!!!!! Thanks for this example ;) See Ya ! |
| ||
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 |
| ||
Nice ;) But i don't understand where multiplying xside,yside,top, and leftside with a large number ??? After draw rectangular box ? or before ? |
| ||
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. |
| ||
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... |
| ||
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 |
| ||
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 |
| ||
Now all we need now is to cycle the colors Just like the old Mandelbrot program on C64! |
| ||
Before Cycling i need a good sample code for generate palette ;) |
| ||
how i can do a nice color palet ? |
| ||
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! |
| ||
you can't infinite zoom, because blitz is limited with float value ! |
| ||
Woah, Back from the dead! :D |
| ||
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? |
| ||
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. |
| ||
> 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. |
| ||
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? |
| ||
> where in the code is he saying to multiply xside, yside, top, and leftside with a large number? he didn't say where. |
| ||
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. |
| ||
> 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? |
| ||
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. |
| ||
Thanks! If anyone else has any ideas to improve this, PLEASE post. |
| ||
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. |
| ||
What did you type into your calculator? |
| ||
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! |