StoneyMahoney
30th May 2005 14:23 UTC
Mandelbrots and Other Fractals
Anyone who doesn't know the procedure used to draw Mandelbrot fractals, go on with your lives or look it up ;)
I've written a Mandelbrot generation engine in AVS and I need some ideas on how to speed it up, short of rewriting it as an APE. Currently it works in three sections.
The first figures out the position on screen for the next plotted point, as well as it's size. This works to continually increase the quality the longer it's left running.
The second figures out the actual colour of the pixel. Because of the itterative nature of the Mandelbrot set, this is done with a whole superscope to get the right number of itterations, just for 1 pixel.
The third takes the details from the first two through the global megabuffer and actually draws the damn thing.
Now, what I'm wondering is how to speed it up. My first version drew 1 pixel per frame using 3 components. My current version draws 32 pixels per frame using 96 components. Is there any way I can get more than one pixel out of a component set? Is there some hidden itterative procedure I could use that I'm just too crappy a programmer to actually find?
The actual engine is at http://www.deviantart.com/deviation/18766376/
An image it produced is at http://www.deviantart.com/deviation/18766170/
It has a problem with the screen size changing mid render and has to be manually reinitialised at the moment. I'm working on that.
UnConeD
31st May 2005 06:45 UTC
A superscope is by definition a loop for 'n' points. You can also use the loop() construct to loop within code. See the Expression Help inside AVS itself for usage examples.
It's not designed for variable-length loops, but you can achieve them with some hacks. It's a trade-off between loop nesting and wasted iterations.
StoneyMahoney
31st May 2005 12:24 UTC
The mandelbrot code looks something like this outside of AVS:
cb = (something)
cbi = (something else)
maxitt = (maximum number of itterations)
repeat(
itt = itt + 1;
olda = a;
a = (a * a) - (b * b) + ca;
b = (2 * olda * b) + cbi;
lz = sqr(a) + sqr(b);
)
until (lz => 4) or (itt = maxitt)
output = itt
I wasted an hour trying to figure out how to use a
loop/if/exec2 combination to do this, but it didn't work. I'd either need an exec5 command or nested exec statements. I reread Pak-9's guide concerning exec2 statements. Am I right in thinking they can't be nested? Is there any way I can get that section of code in the repeat brackets executed in it's entirety in a single statement?
TomyLobo
31st May 2005 23:23 UTC
if you want to write code nested in loops, you might want to use this APE:
http://www.deviantart.com/deviation/12811411/
Jaak
5th June 2005 23:22 UTC
Originally posted by StoneyMahoney
Am I right in thinking they can't be nested?
loop/if/exec can be nested
exec2(assign(t, x), exec2(assign(x,y),assign(y,t)));
is perfectly valid and is actually exactly same as:
t = x;
x = y;
y = t;
StoneyMahoney
6th June 2005 17:33 UTC
A-ha! Thankyou very much, I must have had some syntax error or something when I tried it ;) Thanks for the reassurance :D