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...
#include "2D.frag"
#include "Complex.frag"
#group thingy
uniform int Iterations; slider[1,50,320]
uniform int FirstPower;slider[0,7,10]
uniform float JuliaX; slider[-1,0.78,1]
uniform float JuliaY; slider[-1,-0.36,1]
uniform float Radius; slider[0.0,0.002,0.05]
uniform bool Mirror; checkbox[true]
vec3 color(vec2 p) {
if(Mirror)p.x=abs(p.x);
for(int i=FirstPower;i<Iterations;i++){
vec2 c=cPower(vec2(JuliaX,JuliaY),float(i));//these can be pre-calculated
p+=faceforward(c,p,c);//bad name - make c face OPPOSITE direction of p
}
return vec3(float((length(p)-Radius)>0.0));//only plotting last iter is enough for shape
}
The missing pieces actually make it more appealing IMHO.
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...
mat2 RMat2(float a){return mat2(cos(a),sin(a),-sin(a),cos(a));}
float scale=1.0/sqrt(JuliaX*JuliaX+JuliaY*JuliaY);
mat2 rmx=RMat2(-atan(JuliaY,JuliaX));
vec3 color(vec2 p) {
float dr=1.0;
for(int i=0;i<Iterations;i++){
p*=rmx*scale;dr*=scale;
if(p.x<0.0)p=-p;
p-=vec2(1.0,0.0);
}
return vec3(float((length(p)-Radius)/dr>0.0));
}
Its kali's dragon kifs in 2d. This may give me some insite into how to correct the DE. Maybe not. But it was a fun exercise to see the many ways we can produce the same fractal.