Title: Fractal generation from infinite sum Post by: ballaw on January 25, 2013, 09:37:39 PM I found a project description on a course website for computer graphics. I am trying to complete the project for fun.
Here is the link to the problem description: http://www.pdfhost.net/index.php?Action=Download&File=901bc7785bef41364b3a40f6f4493926 Below is my code. The problem I am running in to is that the terms of the series grow so fast I can't map the points to the screen correctly. From the problem description it says the points will be mappable within a -2 - 2 square but the difference in value between the points is so huge that normalizing by the largest would collapse most of the points to a single pixel. I assume I have a fundamental misunderstanding that I can't identify. Any help or insight would be appreciated! int w = 800, h = 600; int numTimes = 10, cSize = 5; float xr = 2, yr = 2; void setup() { size(w,h); } void draw() { background(255); Complex v = new Complex(mouseX*(xr/w) - (xr/2), mouseY*(yr/h) - (yr/2)); Complex[] exps = new Complex[numTimes]; for (int i = 0; i < numTimes; i++) { exps = complexExp(v,i); } ellipse(w/2, h/2, cSize, cSize); for (int i = 0; i < numTimes; i++) { drawSeries(new Complex(0,0), exps, i, i); } } void drawSeries(Complex vToDraw, Complex[] exps, int count, int clrTrunc) { if (count == 0) { Complex v = exps[0]; float progress = float(clrTrunc) / float(numTimes); fill(255*progress, 180, 255 - 255*progress); vToDraw.add(v); ellipse(vToDraw.r*(w/xr) + (w/2), vToDraw.i*(h/xr) + h/2, cSize, cSize); vToDraw.sub(v); vToDraw.sub(v); ellipse(vToDraw.r*(w/xr) + (w/2), vToDraw.i*(h/xr) + h/2, cSize, cSize); } else { Complex v = exps[count]; vToDraw.add(v); drawSeries(vToDraw, exps, count - 1, clrTrunc ); vToDraw.sub(v); vToDraw.sub(v); drawSeries(vToDraw, exps, count - 1,clrTrunc ); } } Complex complexExp(Complex v, int times) { if (times == 0) { return new Complex(1, 1); } else if ( times == 1) { return new Complex( v.r*v.r - v.i*v.i, 2*v.r*v.i ); } else { return complexExp( new Complex( v.r*v.r - v.i*v.i, 2*v.r*v.i ), times - 1 ); } } class Complex { float r, i; Complex() { this.r = 0; this.i = 0; } Complex(float r, float i) { this.r = r; this.i = i; } void add(Complex nv) { this.r += nv.r; this.i += nv.i; } void sub(Complex nv) { this.r -= nv.r; this.i -= nv.i; } } Title: Re: Fractal generation from infinite sum Post by: eiffie on January 29, 2013, 05:33:30 PM I actually had a great deal of fun with this "assignment" turning it into a distance estimate. Ballow I'm not familiar with Processing but it looks like your ComplexExp function is performing c=c*c when you want c=c*firstc. But now for my fun "ride".
My new year's resolution was to be more like knighty so I decided to come up with a distance estimate for this fractal. A distance estimate tells the distance from the point in question (p) to the fractal. The fractal formula is... c^0±c^1±c^2±c^3... where c is a complex number So to find the distance we want to minimize the funtion: p-c^0±c^1±c^2... The length of the remainder after minimizing is the distance to the fractal. But how can we minimize without recursively going down each branch? If we take each term (c^n) and choose the path that brings us closer to 0,0 we will get close but unfortunately we will get trapped in local minima and lose some of the fractal. I will leave it for the real knighty to find a better method and use this as a start. We use the dot product to determine whether to add or subtract c. if(dot(p,c)>0.0)//c pushes p farther from the origin p-=c; else p+=c; A script in Fragmentarium looks like this... Code: #include "2D.frag" But wait I've seen this fractal before! Here is a hint: The complex number (c) is used to create a scaled and rotated offset. We can achieve the exact scaling and rotation by inverting the operations and applying them to p. You then get... Code: mat2 RMat2(float a){return mat2(cos(a),sin(a),-sin(a),cos(a));}Title: Re: Fractal generation from infinite sum Post by: knighty on February 02, 2013, 12:15:13 AM My new year's resolution was to be more like knighty ... I don't think this is a good idea. :gum: :no:... so I decided to come up with a distance estimate for this fractal. err... OK! It is always good to share ideas! :joy:Seriously, The fractal formula is... c^0±c^1±c^2±c^3... where c is a complex number So to find the distance we want to minimize the funtion: p-c^0±c^1±c^2... The length of the remainder after minimizing is the distance to the fractal. But how can we minimize without recursively going down each branch? AFAIK, the answer is: there is no way to avoid recursion. Finding the distance to an IFS requires a stack or a priority list. The example you gave can be written in recursive form (IIRC these are related to Littlewood polynomials - those which coefficients are either +1 or -1): Pn+1=c*Pn±1. The DE is computed for each branche then we take the minimum: DE=(|Pn|-bvr)/|c|n. bvr is the bounding volume of the fractal. We compute the DE when the norm of Pn is grater than a bailout value. Fortunately, in general, because the norm of Pn grows rapidly and go beyond the bailout before n reaches the max recursion depth, the total number of "iteration" is not exponential when the norm of c is large enought. Another method is to use a priority queue. (see attached scripts for details. They are 2D. Converting to 3D is straightforward). Regarding performance. Hart's raytracing method is much faster (I think it is the method David Makin is using). The advantage of the DE approache is that we can use nonlinear transforms. I've also attached a very simple script for illustration purpose (see the first picture). Title: Re: Fractal generation from infinite sum Post by: eiffie on February 07, 2013, 06:29:29 PM Thanks Ballaw for posting this assignment - I just keep learning little bits from it. Thanks Knighty for explaining the proper way but also for this... Quote the answer is: there is no way to avoid recursion Whenever I see a statement like that - even when it is true as in this case - I hear it as "must find a way to avoid recursion!!"So I made a way that doesn't use recursion - actually the DE steps act as a kind of recursion and again parts of the fractal branchs are cut off - just no visual discontinuity - a nice clean pruning. Your scripts really did help. http://www.fractalforums.com/ifs-iterated-function-systems/dragonkifs-promising-formula-but-help-needed/ (http://www.fractalforums.com/ifs-iterated-function-systems/dragonkifs-promising-formula-but-help-needed/) |