Title: Help on first fractal maker Post by: kronikel on November 18, 2010, 02:13:34 AM I just learned what a fractal was yesterday and became very interested in them.
I decided to try and make my own fractal drawer. I don't know much about them, but I think it worked (I was very surprised) But now I am stuck. I can't figure out how to zoom in on the fractal without the time it takes to draw it increasing. Every time I zoom in it takes a lot longer to draw out than the last time, even though the area drawn is the same size. You very quickly get to the point where it takes too long to render. Here is my code (are there any code tags I can use) Quote var Canvas: TCanvas; tx, ty, f: extended; const Height = 2; Width = 2; Zoom = 50; procedure ColorPoint(px, py: extended); var x, y, xtemp: extended; Iteration, Max_iteration, Color: integer; begin Max_iteration:= 200; x:= px; y:= py; while ((x*x + y*y <= (2*2)) and (Iteration < Max_iteration)) do begin xtemp:= x*x - y*y + px; y:= 2*x*y + py; x:= xtemp; Iteration:= Iteration + 1; end; if (Iteration = Max_iteration) then Color:= 0 else Color:= HSLToColor(Iteration * 10, 100, 50); Canvas.Pixels[Round(px * Zoom) + (Width * Zoom), Round(py * Zoom) + (Height * Zoom)]:= Color; end; begin Canvas:= GetDebugCanvas; Canvas.Brush.Color:= 0; Canvas.Rectangle(-10, -10, 999, 999); tx:= -Width; ty:= -Height; f:= 0.01; repeat repeat tx:= tx + f; ColorPoint(tx, ty); until(tx >= Width); ty:= ty + f; tx:= -Width; until(ty >= Height); DisplayDebugImgWindow(500, 500); end. And I will attach a picture to make sure it is turning out right I think I can get around the problem. It seems like no matter how zoomed in you go there would be a way to make all renderings take the same amount of time. Title: Re: Help on first fractal maker Post by: cKleinhuis on November 18, 2010, 12:12:14 PM hello, and rofl, this is one all fractals have in common, the point is, that you are approaching the boarder ever closer, this means, you have to increase
iteration depth, and the problem with that is, that the "black" areas, which are "inside" are possessing endless iteration cycles, there exist some optimizations to improve rendering speed, at mu ency there is a good tutorial on how to do successive refinment renderings http://mrob.com/pub/muency/successiverefinement.html although this method is not very good at special coloring algorithms, but plain escape time coloring is well for this method! O0 Title: Re: Help on first fractal maker Post by: kronikel on November 18, 2010, 05:54:11 PM Well that is no good, it took me a few minutes to render the one I showed and it is hardly zoomed in at all.
I still feel there is a way to only set the color of each pixel ONE time. The way it is now it does decimals and will set the color of a single pixel multiple times. For example it will calculate the color for the pixels (1.1, 2.3), (1.2, 2.3), (1.3, 2.3) But all of those points round to (1, 2) There has to be a way to make the points it sets look more like (1, 2), (1, 3), (1, 4) Edit: I haven't gotten to the point where the "iteration cycles" are getting large. That I can understand. The issue I'm having is that the more I zoom the more times it will cycle through a single pixel setting its color multiple times. Title: Re: Help on first fractal maker Post by: ker2x on November 18, 2010, 07:49:05 PM What is the language ? Delphi ?
if i understood your code correctly, you're doing it wrong. Well... not wrong, but it's suboptimal. There is tons of mandelbrot sample code in every possible (and impossible) language. i'm not sure about what you're doing with this f variable. what i suggest is something like : Code: foreach pixel x,y Here is the key parts of my C#/HLSL code to convert coordinate (and zoom, move, etc ...) : C# code : Code: Vector2 pan = new Vector2(0.25f, 0.000f); // (0.25,0) is the center of the screen (in complex value) and my hlsl code to convert pixel->complex : Code: float2 c = (texCoord - 0.5) * Zoom * float2(1, Aspect) - Pan; //converting pixel coordinate (texcoord) to complex coordinate. if you can't do math operation on float2 type, here is the equivalent : Code: float cx = (texCoord.x - 0.5) * Zoom * Aspect - Pan.x; now you just have to change pan value to "move" up/down and left/right and zoom ... to zoom. hope this help. Feel free to ask questions, we all got the same problem sooner or later :) Title: Re: Help on first fractal maker Post by: ker2x on November 18, 2010, 07:55:47 PM It seems like no matter how zoomed in you go there would be a way to make all renderings take the same amount of time. Yes and no ... 1) it's highly dependent of the area you're zooming in. (zone with high iteration -> slower. zone with low iteration -> faster) 2) the more you zoom, the more you should iterate. (more iteration -> slower) 3) deep zooming require high numeric precision. (higher -> slower) Title: Re: Help on first fractal maker Post by: kronikel on November 18, 2010, 08:03:13 PM Assuming all iterations would be the same though, no matter how zoomed in you go it should take the same amount of time to render.
But I figured out my problem. I fixed it by making it keep track of 2 sets of variables. One set of points for the screen (whole numbers) and one set of points that are used to determine color (decimals) And now it sets each pixel once because I have it cycle through the whole numbers rather than the decimal numbers. Title: Re: Help on first fractal maker Post by: kronikel on November 18, 2010, 08:06:27 PM Didn't see your first post.
This is pretty much in delphi. I use a compiler called SCAR which I believe is some custom mix of delphi and pascal. Title: Re: Help on first fractal maker Post by: cKleinhuis on November 18, 2010, 08:30:43 PM hello, you need a step size for your image, with the top left corner and the lower left corner in complex coordinates, you calculate the distance ( xmin-xmax) and divide it by the pixel resolution, and the same for your y step
then you initialise your rendering loop with the topleft pixel, and increment by the step sizes for every new pixel, this way you wouldnt calculate the same pixel twice... Title: Re: Help on first fractal maker Post by: kronikel on November 18, 2010, 09:01:29 PM Thanks trifox that's exactly what I changed to make it work.
Took me a while to catch it though because doing it like that required me to rewrite a lot of the code and also come up with an equation for the step using the constant "Zoom" Something I just noticed. A lot of people seem to be talking about these complex and imaginary numbers. I understand for the most part what they are but I don't use them in any way that I'm aware of. Title: Re: Help on first fractal maker Post by: David Makin on November 18, 2010, 09:06:45 PM Actually in the outer (y) loop you should convert the y pixel to the imaginary coordinate and in the inner (x) loop convert the x pixel to the real coordinate rather than using start values and delta steps for the complex value.
Delta steps is (slightly) quicker but considerably less accurate and will introduce rounding errors at lower magnifications - typically up to 100* worse than the calculation method. I made the mistake of using delta steps for the complex values in MMFrac and that loses resolution at around magnification 1e14 whereas converting the pixel values to coordinates as described will result in reasonable accuracy to magnifications of around 1e16. Title: Re: Help on first fractal maker Post by: David Makin on November 18, 2010, 09:14:19 PM I understand for the most part what they are but I don't use them in any way that I'm aware of. You are using them, but when applied in a computer program they have to be treated as two real values with a specific method of performing the various mathematical operations on a 2D number system - hence the "x= x^2-y^2 and y = 2*x*y" for when squaring the complex number z where z = x+ i*y. The best documentation I found on how to use complex numberrs programmatically is in the appendices of the "fractint.doc" document that used to be produced when typing "fractint -makedoc" in DOS or a command-line shell - I believe this document is now also available online in HTML format. Other links: http://en.wikipedia.org/wiki/Complex_number (http://en.wikipedia.org/wiki/Complex_number) http://mathworld.wolfram.com/ComplexNumber.html (http://mathworld.wolfram.com/ComplexNumber.html) Title: Re: Help on first fractal maker Post by: kronikel on November 18, 2010, 09:23:51 PM Hmm I understand what you are saying about the delta steps and also about how I am using complex numbers.
But I'm not sure how to go about not using steps. Title: Re: Help on first fractal maker Post by: David Makin on November 18, 2010, 10:07:15 PM Hmm I understand what you are saying about the delta steps and also about how I am using complex numbers. But I'm not sure how to go about not using steps. Assuming we do mean essentially the same thing then using "delta steps" would be something like: yimag = calculate top coord of complex number (imaginary value) for (pixely=toppixel;pixely<btmpixel;pixely++) xreal = calculated left coord of complex number (real value) for (pixelx=leftpixel;pixelx<rightpixel;pixelx++) render fractal for coordinate (xreal,yimag) for pixel (pixelx,pixely) xreal = xreal + xrealstep next pixelx yimag = yimag + yimagstep next pixely Whereas the equivalent more accurate code would be: for (pixely=toppixel;pixely<btmpixel;pixely++) yimag = top coord of complex number (imaginary value) + (pixely-toppixel)*yimagstep for (pixelx=leftpixel;pixelx<rightpixel;pixelx++) xreal = calculated left coord of complex number (real value) + (pixelx-leftpixel)*xrealstep render fractal for coordinate (xreal,yimag) for pixel (pixelx,pixely) next pixelx next pixely Note that to add rotation/zooming/translation etc. simply add appropriate transform/s of (xreal,yimag) after the calculation of xreal before rendering of the fractal for the pixel. Edit: My mistake - obviously for zooming and translation (and even independant x/y scaling) you only need to adjust the base coord values and the step values. But as soon as you require rotation then both the pre-render x (real) and y (imag) components of the coord need adjusting in the inner loop so in that case you'd use code like this (at its simplest): for (pixely=toppixel;pixely<btmpixel;pixely++) for (pixelx=leftpixel;pixelx<rightpixel;pixelx++) Apply affine transform to pixelx and pixely resulting in xreal and yimag render fractal for coordinate (xreal,yimag) for pixel (pixelx,pixely) next pixelx next pixely Said affine transform would normally consist of rotation/scaling and translation but could also include skewing and other possibilities. Title: Re: Help on first fractal maker Post by: kronikel on November 18, 2010, 10:15:32 PM I barely know any c based language so that was a bit confusing.
I'll have to look into it though because I know it will be faster than what I am using. I have a new problem though. To scale this the way I would like to I need to figure out this- Input - Output 1 2 2 1 3 .5 4 .25 5 .125 Each output is half of the last one But what to do to the input to get the output? This code gives correct output but but will only work on whole numbers. But the input could be anything, such as 2.34029 Code: Output:= 2; Title: Re: Help on first fractal maker Post by: David Makin on November 18, 2010, 10:21:40 PM I barely know any c based language so that was a bit confusing. I'll have to look into it though because I know it will be faster than what I am using. I have a new problem though. To scale this the way I would like to I need to figure out this- Input - Output 1 2 2 1 3 .5 4 .25 5 .125 Each output is half of the last one But what to do to the input to get the output? This code gives correct output but but will only work on whole numbers. But the input could be anything, such as 2.34029 Code: Output:= 2; scale = 2^(2-n) n scale 1 2 2 1 3 0.5 etc. Here's a slightly related fractal link... http://www.fractalgallery.co.uk/cantor-set.html (http://www.fractalgallery.co.uk/cantor-set.html) Title: Re: Help on first fractal maker Post by: David Makin on November 18, 2010, 10:23:05 PM I barely know any c based language so that was a bit confusing. I'll have to look into it though because I know it will be faster than what I am using. Probably my fault for writing it in a mix of C and BASIC syntax :) Title: Re: Help on first fractal maker Post by: kronikel on November 18, 2010, 10:27:16 PM Any ideas on an equation?
I'm pretty stumped but I feel like I'm over thinking this Title: Re: Help on first fractal maker Post by: David Makin on November 18, 2010, 10:33:04 PM I think you missed it:
http://www.fractalforums.com/programming/help-on-first-fractal-maker/msg24585/#msg24585 (http://www.fractalforums.com/programming/help-on-first-fractal-maker/msg24585/#msg24585) "^" is "to the power of" - in standard c you might have to use "scale = pow(2, 2-n)" I think - or is that "scale = pow(2-n,2)" ? Title: Re: Help on first fractal maker Post by: kronikel on November 18, 2010, 10:40:23 PM Ahah! I didn't see that and I didn't think of that because my brain wanted to shut off when approaching negative exponents for some reason.
Output:= Pow(2, 2 - Input); I think that's all I needed I'll try to throw it together and see what I get. Title: Re: Help on first fractal maker Post by: kronikel on November 18, 2010, 11:33:58 PM Everything is working but I'm still left with the problem of it taking a lot longer to render when zooming in.
Now it does each pixel only once and I'm sure of it. It does not execute more lines of code by zooming in on the fractal at all. The only difference I see is that the numbers is uses get a log bigger. Does computing a number like 1.203592928220659 take a long longer than just 1.2? I've never noticed it before so I'm thinking even if larger numbers do take more time it can't make this much of a difference. Title: Re: Help on first fractal maker Post by: ker2x on November 19, 2010, 01:24:11 AM Does computing a number like 1.203592928220659 take a long longer than just 1.2? No. They are both 64bits floating point numbers on a 64bits CPU, it take exactly the same time. Title: Re: Help on first fractal maker Post by: kronikel on November 19, 2010, 02:01:44 AM Edit:
Uggh I was changing the wrong variable when I was testing the max iteration problem and that actually was it. If I set it lower I can render a high magnification in under a second now. Title: Re: Help on first fractal maker Post by: Tabasco Raremaster on November 19, 2010, 03:01:58 AM "I can't figure out how to zoom in on the fractal without the time it takes to draw it increasing.
Every time I zoom in it takes a lot longer to draw out than the last time, even though the area drawn is the same size" For as far as I know there is no fractal rendering program in where the rendering time does not increase with a higher zoom. My sugestion is : Figure it out. Just do it! Title: Re: Help on first fractal maker Post by: ker2x on November 19, 2010, 09:03:01 AM A lot of people seem to be talking about these complex and imaginary numbers. I understand for the most part what they are but I don't use them in any way that I'm aware of. You are drawing the mandelbrot set, the formula is : z = zē+c where z and c are compex numbers. your code : Code: xtemp:= x*x - y*y + px; is doing z = zē+c with "px" -> real part of c "py" -> imaginary part of c "x" -> real part of z "y" -> imaginary part of z Title: Re: Help on first fractal maker Post by: David Makin on November 19, 2010, 03:38:08 PM Everything is working but I'm still left with the problem of it taking a lot longer to render when zooming in. Now it does each pixel only once and I'm sure of it. It does not execute more lines of code by zooming in on the fractal at all. The only difference I see is that the numbers is uses get a log bigger. Does computing a number like 1.203592928220659 take a long longer than just 1.2? I've never noticed it before so I'm thinking even if larger numbers do take more time it can't make this much of a difference. Zooming in taking longer to render is pretty unavoidable if you're zooming into areas on the boundary of the Set, in particular if the image has large areas of "inside", this is simply because more iterations are necessary on average per pixel to decide if the pixels are inside or outside. As you say a solution is reduce the max iteration value but of course doing this results in loss of detail and the more you zoom in the greater the loss of detail will be, in fact normally one would actually want to *increase* the max iterations on higher magnifications. One way of offsetting the speed problem that is emploiyed in many fractal programs is early detection of "inside" points where the orbit of the point concerned is tending to a fixed value (point attractor). To do this on each iteration before calculation of the new z value, store the current value as say zold, then after calculating the new z value test the value of (z.x-zold.x)^2+(z.y-zold.y)^2 against a small threshold (smallbailout), say at largest 1e-3 and if the calculated value is less than 1e-3 then assume the point is "inside" and stop iterating. The problem with this method is if the theshold value (here 1e-3) is too large then this test in itself will introduce "errors" in the render i.e. reduce the detail level. The thing to do to render a given view of an escape-time fractal in an optimum manner speedwise is to use a correct balance of the 3 values - the bailout value, the max iteration value and this small bailout test value (here 1e-3). Speedwise of course one should always use the minimum possible bailout value, e.g. testing z.x^2+z.y^2 against 4.0 for the z^2+c Mandelbrot (and z^2+c Julias), the optimum max iterations and smallbailout test value will depend on individual views but in general the more zoomed in you are then to avoid gross loss of detail then the larger you need to make max iterations and the smaller you need to make the small bailout test value. For a better guide on fractal orbits see: http://www.fractalgallery.co.uk/orbits.html (http://www.fractalgallery.co.uk/orbits.html) Title: Re: Help on first fractal maker Post by: ker2x on November 19, 2010, 05:47:18 PM Everything is working but I'm still left with the problem of it taking a lot longer to render when zooming in. Now it does each pixel only once and I'm sure of it. It does not execute more lines of code by zooming in on the fractal at all. The only difference I see is that the numbers is uses get a log bigger. Does computing a number like 1.203592928220659 take a long longer than just 1.2? I've never noticed it before so I'm thinking even if larger numbers do take more time it can't make this much of a difference. Zooming in taking longer to render is pretty unavoidable if you're zooming into areas on the boundary of the Set, in particular if the image has large areas of "inside", this is simply because more iterations are necessary on average per pixel to decide if the pixels are inside or outside. As you say a solution is reduce the max iteration value but of course doing this results in loss of detail and the more you zoom in the greater the loss of detail will be, in fact normally one would actually want to *increase* the max iterations on higher magnifications. One way of offsetting the speed problem that is emploiyed in many fractal programs is early detection of "inside" points where the orbit of the point concerned is tending to a fixed value (point attractor). To do this on each iteration before calculation of the new z value, store the current value as say zold, then after calculating the new z value test the value of (z.x-zold.x)^2+(z.y-zold.y)^2 against a small threshold (smallbailout), say at largest 1e-3 and if the calculated value is less than 1e-3 then assume the point is "inside" and stop iterating. The problem with this method is if the theshold value (here 1e-3) is too large then this test in itself will introduce "errors" in the render i.e. reduce the detail level. The thing to do to render a given view of an escape-time fractal in an optimum manner speedwise is to use a correct balance of the 3 values - the bailout value, the max iteration value and this small bailout test value (here 1e-3). Speedwise of course one should always use the minimum possible bailout value, e.g. testing z.x^2+z.y^2 against 4.0 for the z^2+c Mandelbrot (and z^2+c Julias), the optimum max iterations and smallbailout test value will depend on individual views but in general the more zoomed in you are then to avoid gross loss of detail then the larger you need to make max iterations and the smaller you need to make the small bailout test value. For a better guide on fractal orbits see: http://www.fractalgallery.co.uk/orbits.html (http://www.fractalgallery.co.uk/orbits.html) Mmm, it may be interesting for my openCL buddhabrot code :) Title: Re: Help on first fractal maker Post by: David Makin on November 20, 2010, 06:45:46 PM Of course with respect to using a "smallbailout' to test for point-attractors so you have early detection of "inside", you can extend this to test for attractors of higher period - for instance period 2 attractors are almost as easy to detect as point attractors but here you need z, zold and zolder and would test the value of (z.x-zolder.x)^2+(z.y-zolder.y)^2 against a smallbailout. There are also reasonably quick (but less efficient) algorithms to test for periodic attractors of arbitrary period. Of course for particular Julia Sets (at least for z^p+c) then one only needs test for a specific periodic attractor in order to detect "inside" early, though obviously the period would be best known at runtime for maximum efficiency. To state the obvious, the larger the period then the less effective testing for periodic attractors becomes. |