Archived

This topic is now archived and is closed to further replies.

MDI

Mandelbrot set generation help

Recommended Posts

Sorry for posting this here. This is a homework question, but I'm not looking for someone to give me an answer. We've been tasked with having to generate some fractals in Java, I've already completed Menger's Sponge and Sierpinski's triangle, but the generation of the Mandelbrot and Julias-Fatou sets are giving me a bit of trouble (I have actually generated a Mandelbrot set before, I posted a picture in the thread with the animated GIFs a while back, but I've since forgotten how exactly they're done). I've tried to write the code myself, based on the limited information given to us in the notes, and some other online articles. Here's the relevant code (I've only tried the Mandelbort set so far): *Code deleted to stop plagiarism.* However, when this is plotted, all I get is a big black line running from the top left corner to the bottom right. What I'm asking is for a hint as to where I'm going wrong. I'm not looking for someone to give me an answer (as that would count as plagiarism). Is my code close to what it should be? grhodes: I'd apprecite it if you closed this thread when a satisfactory hint is given. Thanks in advance. [edited by - MDI on April 14, 2004 6:25:18 AM]

Share this post


Link to post
Share on other sites
Unless you''re using some really screwy Complex class, I think the problem is a domain error. The Mandlebrot set is only really well defined for |z| < 2 . (Or rather only generates pretty pictures when |z| < 2 or so). You need to scale your x and y before constructing a complex number from them.

Share this post


Link to post
Share on other sites
The maths looks ok, but not at all optimised. The loop doesn't seem to be exiting though when mag > 2.

Heh just spotted a slightly larger problem. A nice render of the M-Set will be given when plotted from -2 to 2 on the Real axis and -1.5 to 1.5 on the Imaginary axis. Oh deary me!

[edit] seems SiCrane got there first [/edit]

[edited by - higherspeed on April 3, 2004 6:12:25 AM]

Share this post


Link to post
Share on other sites
Sorry, I''m working on a machine not connected to the ''net, so I had to type out the code manually. There is of course a "break" in the "if" statement.

SiCrane, are you saying that I should change this line:

Complex cons = new Complex(x, y);

?

Thanks for the replies so far.

Share this post


Link to post
Share on other sites
That''s pretty much what he''s saying. You need to scale your x/y coordinates so that your complex numbers are generated as -2<=x<=2 and -1.5<=y<=1.5 to get the interesting part of the fractal. All the rest of it outside these ranges is pretty boring. If you can reassign these mappings, you can "zoom in" on the set, to show the infinitely increasing detail (at least, to the limits of double precision). The full set at [-2,2] and [-1.5, 1.5] (as higherspeed recommended) isn''t really all that interesting, all things considered. The good stuff is only found "deeper" in.

The way I like to do it is to assign 4 variables-- x1,y1,x2,y2 --the coordinates of a zoom rectangle within the set, and use x/screenwidth and y/screenheight to linearly interpolate these ranges. This way, I can use the mouse to define zoom rectangles, and reassign the ranges to zoom in.


Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller

Share this post


Link to post
Share on other sites
OK, I''m now calculating the scaling using this method:

I have two complex numbers, min and max, which define the minimum and maximum extents of the complex plane. These are set to -2 - 2i and 2 + 2i respectively as their default values.

I then calculate the "width" (incx) and "height" (incy) using max.real - min.real / screensize.width and max.imaginary - min.imaginary / screensize.height.

My "constant" is then new Complex(x + incx * width, y + incy * height);

However the fractal is not drawing correctly (this is a big improvement over it not drawing anythign at all, though!). The best I can describe how it looks like would be kind of similar to a leopard skin stretched out. It is both symmetrical in the horizontal and vertical planes.

Anyone any ideas?

Thanks.

Share this post


Link to post
Share on other sites
You are interpolating wrong. You calculate, for instance, incx as (max-min)/width, then when building the complex number, you multiply by width as (x+incx*width), which is algebraically equivalent to (x+(max-min)), and not the desired result. What you need to do instead is to multiply your interval by x, as in (x+incx*x), which equates to (x + (max-min)(x/width)). In this fashion, x/width acts as your interpolant, incrementing in the range of [0,1], 0 when x=0 and 1 when x=width.

edit: Change my screwup...
new Complex(min.real+incx*x, min.imaginary+incy*y)

Hope that helps.

edit: Ack. You're right, SiCrane. That's what I meant. Sorry.

Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller


[edited by - VertexNormal on April 3, 2004 4:14:47 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I am intrigued, how did you construct your menger sponge in Java?
I created some art based on reverse menger sponges and similar fractals a while back, but with spheres in openGL, however it ran extemely slow even at the 2nd and 3rd level of recursion. I didn''t bother fixing it

Share this post


Link to post
Share on other sites
I am intrigued, how did you construct your menger sponge in Java?
I created some art based on reverse menger sponges and similar fractals a while back, but with spheres in openGL, however it ran extemely slow even at the 2nd and 3rd level of recursion. I didn''t bother fixing it

Share this post


Link to post
Share on other sites
I was going to make a new thread, but seeing as this one appears to have all the right people''s attention, and MDI has what he needs I''ll post here.

I''ve put together a fairly simple program using SDL to display fractal images, with the ability to zoom in also provided. The problem comes when I start to zoom in - as I lose a lot of granularity very quickly and the whole point of a fractal is that it shows detail at any level, which currently mine doesn''t. I was wondering if it was possible that this was related to the precision available in C++ (although I am using double, and long double didn''t seem to make any difference)?

One other possible area I thought the problem could be in was the way I generate the ''c'' values for each pixel. I have a pair of for loops each running to the appropriate axis'' resolution, and then convert each pixel to the correct point on the complex plane using the following procedure:

inline double relocate( double current_in, double min_in, double max_in, double min_out, double max_out )
{
return( ( ( ( current_in - min_in ) / ( max_in - min_in ) ) * ( max_out - min_out ) ) + min_out );
}

Any thoughts welcome

Share this post


Link to post
Share on other sites
If I understand correctly, you''re having a problem similar to mine. The way to convert to the complex plane coordinates is:

xfactor = (max_real - min_real) / screenwidth;
yfactor = (max_imag - min_imag) / screenheight;

Then the c values are:

c_real = min_real + x * xfactor;
c_imag = min_imag + y * yfactor;

Is that what you were after?

Share this post


Link to post
Share on other sites
I think either I''m expecting too much from the precision here, or it''s something a bit more subtle.

These two pictures show firstly most of the fractal, and secondly a zoomed-in image where you can see the loss of quality fairly clearly:

Picture 1
Picture 2

Share this post


Link to post
Share on other sites
Try more iterations, and play with the way you generate your colors. You're not hitting the mathematical precision limit yet, or the image would start to look really pixellated and blocky.

Typically, I like to set up an arbitrary color scale of, say, 256 colors. Usually, I specify the scale as a curve, with control points to vary the gradations, then evaluate the curve and built a palette. Then, I use a maximum number of iterations of perhaps 512 or 768 for each pixel, take the final iteration count for a pixel, % it by the number of samples in the color scale, then index into the scale to get the final color.

Like this:





Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller


[edited by - VertexNormal on April 16, 2004 3:31:01 PM]

Share this post


Link to post
Share on other sites
Thanks, I think this is going down the right track. I''m not sure I understand exactly though.

You say you specify the scale as a curve - does that mean more weight is given to the lower iteration values? I''m currently using a logarithm of the number of iterations to generate my colour.

With the control points to vary the gradations, do you mean that, for example, 0-63 would be shades of red, 64-127 green, 128-191 blue and 192-255 yellow or something like that?

Share this post


Link to post
Share on other sites
quote:
Original post by robthebob
Thanks, I think this is going down the right track. I''m not sure I understand exactly though.

You say you specify the scale as a curve - does that mean more weight is given to the lower iteration values? I''m currently using a logarithm of the number of iterations to generate my colour.



I give equal weight to all iteration values, and ensure that the color scale repeats over the range of possible iterations.

quote:

With the control points to vary the gradations, do you mean that, for example, 0-63 would be shades of red, 64-127 green, 128-191 blue and 192-255 yellow or something like that?


Perhaps I confused the issue by talking about a curve, but that''s pretty much the idea. Basically, what I have is a palette. I set the palette up with a smooth color scale; it doesn''t really matter how the scale is generated. It works just as well with 2 control points as with 8, though I think it''s rather boring with only 2 colors. But the end result is simply a 256 color (or however many I want to use) array of RGB colors. I built a simple class that takes a list of control points and a number of samples, and constructs the color palette by interpolating between the control points.

Then to index into the palette, I take the number of iterations of the current pixel and modulus by the number of palette entries in the color scale.

paletteindex = num_iterations % ColorScale.num_palette_entries;

Then, I simply use paletteindex to index into the color palette array, retrieve the color, and plot the pixel.

It''s a linear relationship to num_iterations, but if you look at the color distribution, there is plenty of variation concentrated in the "interesting" parts of the fractal. The above and below images were made using 512 iterations, with a color scale 256 colors in length and 6 colors across the scale. With the linear mapping of the modulus of num_iterations, the color variation is concentrated at the "edges", where the interesting patterns occur. At the top level, the fractal isn''t very interesting at all:

but as you go deeper in:

the color variation starts to get more interesting:


I''ve just found this kind of linear mapping to give very pleasant results. However, even so there are places within the fractal where I just don''t do enough iterations, giving me locations like:

where you can clearly see that zooming in will not reveal fun color variation. More iterations helps, but then it takes a lot longer to compute.

I''m no mathematician by any stretch of the imagination, I just try to use what looks good to me, and this is a method that produces interesting results.

Share this post


Link to post
Share on other sites
I''m in the process of integrating this kind of palette into my program, and so far it looks to be doing exactly what I need.

Thanks a lot VertexNormal

Share this post


Link to post
Share on other sites