Welcome to Fractal Forums

Fractal Software => Programming => Topic started by: CalvinCreator on April 20, 2017, 12:28:13 AM




Title: Triangle Inequality Average Coloring
Post by: CalvinCreator on April 20, 2017, 12:28:13 AM
I am interested in learning how to implement the Triangle Inequality Average Coloring algorithm. However, I can only find information on it in Jussi Härkönen's master's thesis, which I don't have the math to understand, or in the Ultra Fractal formula database, and while I have tried to understand what is going on I am very unfamiliar with the libraries used. How does the Triangle Inequality Average Coloring algorithm work? Pheudo code would be much appreciated, or even just a paragraph or two of description!

*EDIT* I have also found a JavaScript implementation here: http://jsfiddle.net/LMNu9/5/     but it's just so much gibberish to me because I have no familiarity with JavaScript or languages like it.

Thank you very much!


Title: Re: Triangle Inequality Average Coloring
Post by: Softology on April 20, 2017, 01:38:23 AM
Maybe this code will help (if you are more familiar with C based GLSL shader code)?  This is for a basic power 2 Mandelbrot with TIA coloring.

Code:
#version 400

uniform vec2 resolution;
uniform vec3 palette[256];
uniform double xmin;
uniform double xmax;
uniform double ymin;
uniform double ymax;
uniform double bailout;
uniform int maxiters;
uniform int samplepixels;

double sqrsamplepixels=double(samplepixels*samplepixels);
double bailout_squared=double(bailout*bailout);
double magnitude,r1,r2,g1,g2,b1,b2,tweenval;
double realiters;
vec4 finalcol,col;
int superx,supery;
double stepx=(xmax-xmin)/resolution.x/samplepixels;
double stepy=(ymax-ymin)/resolution.y/samplepixels;
int colval,colval1,colval2;
dvec2 z,c;
//triangle inequality average coloring
double sum,sum2,ac,il,lp,az2,lowbound,f,index,tr,ti;
int mandelbrotPower;
double rval,gval,bval,rval1,gval1,bval1,rval2,gval2,bval2;

void main(void)
{
sum=0;
sum2=0;
ac=0;
il=0;
lp=0;
mandelbrotPower=2;

finalcol=vec4(0,0,0,0);
for (supery=0;supery<samplepixels;supery++)
{
for (superx=0;superx<samplepixels;superx++)
{
c.x = xmin+gl_FragCoord.x/resolution.x*(xmax-xmin)+(stepx*superx);
c.y = ymin+gl_FragCoord.y/resolution.y*(ymax-ymin)+(stepy*supery);
int i;
z = dvec2(0.0,0.0);

//triangle inequality average coloring
sum = 0;
sum2 = 0;
ac = sqrt(c.x * c.x + c.y * c.y);
il = 1.0 / log(mandelbrotPower);
lp = log(float(log(float(bailout)) / mandelbrotPower));
az2 = 0.0;
lowbound = 0.0;
f = 0.0;
index = 0.0;

for(i=0; i<maxiters; i++)
{
//START OF FRACTAL FORMULA
double x = (z.x * z.x - z.y * z.y) + c.x;
double y = (z.y * z.x + z.x * z.y) + c.y;
//END OF FRACTAL FORMULA

magnitude=(x * x + y * y);
if(magnitude>bailout_squared) break;
z.x = x;
z.y = y;

//triangle inequality average
sum2=sum;
if ((i!=0)&&(i!=maxiters-1)) {
tr=z.x-c.x;
ti=z.y-c.y;
az2=sqrt(tr * tr + ti * ti);
lowbound=abs(az2 - ac);
sum+=((sqrt(z.x * z.x + z.y * z.y)-lowbound)/(az2+ac-lowbound));
}

}

if (i==maxiters) {
col=vec4(0.0,0.0,0.0,1.0);
} else {
//triangle inequality average
sum=sum/i;
sum2=sum2/(i-1.0);
f=il*lp - il*log(log(float(length(z))));
index=sum2+(sum-sum2)*(f+1.0);
realiters=255*index;
colval1= int(mod(realiters,255));
colval2=int(mod((colval1+1),255));
tweenval=fract(realiters);
if (colval1<0) { colval1=colval1+255; }
if (colval2<0) { colval2=colval2+255; }
rval1 =palette[colval1].r;
gval1 =palette[colval1].g;
bval1 =palette[colval1].b;
rval2 =palette[colval2].r;
gval2 =palette[colval2].g;
bval2 =palette[colval2].b;
rval =rval1 +((rval2 - rval1)*tweenval);
gval =gval1 +((gval2 - gval1)*tweenval);
bval =bval1 +((bval2 - bval1)*tweenval);
col=vec4(rval,gval,bval,1.0);
}
finalcol+=col;
}
}
gl_FragColor = vec4(finalcol/sqrsamplepixels);
}


Title: Re: Triangle Inequality Average Coloring
Post by: Adam Majewski on April 20, 2017, 02:49:22 PM
http://jussiharkonen.com/gallery/coloring-techniques/
http://www.hiddendimension.com/fractalmath/divergent_fractals_main.html

HTH

-----------edit------
https://en.wikibooks.org/wiki/Fractals/Iterations_in_the_complex_plane/triangle_ineq


Title: Re: Triangle Inequality Average Coloring
Post by: CalvinCreator on April 21, 2017, 03:19:22 AM
Softology, can you describe how it works qualitatively? That would be wonderful! If you don't have the time, could you tell me what samplepixels is and what the fract method does? Are supery and superx the current x and y pixels? Is the mod method modulus or floor modulus? Finally, is c the complex number represented by the coordinates of the point being examined, and do these lines:
c.x = xmin+gl_FragCoord.x/resolution.x*(xmax-xmin)+(stepx*superx);
c.y = ymin+gl_FragCoord.y/resolution.y*(ymax-ymin)+(stepy*supery);
convert the screen coordinates into real world coordinates?

Adam Majewski, I actually mentioned one of your sources already as unintelligible to me, and your second source mentions Triangle Inequality in passing only, pointing out that one of the fractal images was created using that method. Thanks, however.


Title: Re: Triangle Inequality Average Coloring
Post by: Softology on April 21, 2017, 06:33:00 AM
Fract returns the fractional part of a number, ie fract(1.23) returns 0.23.
Mod is modulus.

See here for the official GLSL language spec https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.1.20.pdf

The c.x and c.y calculate the real and imaginary parts of the complex C in Z=Z^2+C
But yes, they convert the pixel location onto the complex plane.

Samplepixels supports calculating mutliple values per pixel.

Here is the code without supersampling to make it (maybe?) easier to follow.

Code:
#version 400

uniform vec2 resolution;
uniform vec3 palette[256];
uniform double xmin;
uniform double xmax;
uniform double ymin;
uniform double ymax;
uniform double bailout;
uniform int maxiters;

double bailout_squared=double(bailout*bailout);
double magnitude,r1,r2,g1,g2,b1,b2,tweenval;
double realiters;
vec4 finalcol,col;
int superx,supery;
double stepx=(xmax-xmin)/resolution.x;
double stepy=(ymax-ymin)/resolution.y;
int colval,colval1,colval2;
dvec2 z,c;
//triangle inequality average coloring
double sum,sum2,ac,il,lp,az2,lowbound,f,index,tr,ti;
int mandelbrotPower;
double rval,gval,bval,rval1,gval1,bval1,rval2,gval2,bval2;

void main(void)
{
sum=0;
sum2=0;
ac=0;
il=0;
lp=0;
mandelbrotPower=2;

finalcol=vec4(0,0,0,0);
c.x = xmin+gl_FragCoord.x/resolution.x*(xmax-xmin);
c.y = ymin+gl_FragCoord.y/resolution.y*(ymax-ymin);
int i;
z = dvec2(0.0,0.0);

//triangle inequality average coloring
sum = 0;
sum2 = 0;
ac = sqrt(c.x * c.x + c.y * c.y);
il = 1.0 / log(mandelbrotPower);
lp = log(float(log(float(bailout)) / mandelbrotPower));
az2 = 0.0;
lowbound = 0.0;
f = 0.0;
index = 0.0;

for(i=0; i<maxiters; i++)
{
//START OF FRACTAL FORMULA
double x = (z.x * z.x - z.y * z.y) + c.x;
double y = (z.y * z.x + z.x * z.y) + c.y;
//END OF FRACTAL FORMULA

magnitude=(x * x + y * y);
if(magnitude>bailout_squared) break;
z.x = x;
z.y = y;

//tia
sum2=sum;
if ((i!=0)&&(i!=maxiters-1)) {
tr=z.x-c.x;
ti=z.y-c.y;
az2=sqrt(tr * tr + ti * ti);
lowbound=abs(az2 - ac);
sum+=((sqrt(z.x * z.x + z.y * z.y)-lowbound)/(az2+ac-lowbound));
}

}

if (i==maxiters) {
col=vec4(0.0,0.0,0.0,1.0);
} else {
//triangle inequality average
sum=sum/i;
sum2=sum2/(i-1.0);
f=il*lp - il*log(log(float(length(z))));
index=sum2+(sum-sum2)*(f+1.0);
realiters=255*index;
colval1= int(mod(realiters,255));
colval2=int(mod((colval1+1),255));
tweenval=fract(realiters);
if (colval1<0) { colval1=colval1+255; }
if (colval2<0) { colval2=colval2+255; }
rval1 =palette[colval1].r;
gval1 =palette[colval1].g;
bval1 =palette[colval1].b;
rval2 =palette[colval2].r;
gval2 =palette[colval2].g;
bval2 =palette[colval2].b;
rval =rval1 +((rval2 - rval1)*tweenval);
gval =gval1 +((gval2 - gval1)*tweenval);
bval =bval1 +((bval2 - bval1)*tweenval);
col=vec4(rval,gval,bval,1.0);
}
gl_FragColor = vec4(col);
}


What language are you using to write the code?  If you can get a basic Mandelbrot renderer going first then adding TIA functionality should not be that difficult.


Title: Re: Triangle Inequality Average Coloring
Post by: xenodreambuie on April 21, 2017, 10:38:23 AM
Here's some general explanation. The triangle inequality is basically a cheap way to calculate an angle. TIA is averaging the angle over all iterations to get a smooth result. So there is some initialization and some calculations per iteration to do the sum. It has to store the sum at the previous iteration before adding the next one so you can interpolate between them to get a continuous function between iteration bands (in the same way that continuous potential is usually interpolated). This interpolation is done after the iterations bail out.


Title: Re: Triangle Inequality Average Coloring
Post by: CalvinCreator on April 21, 2017, 02:24:53 PM
Thank you both very much! The code is much more understandable without the supersampling(it's probably rather obvious that I had never heard of it before) and the qualitative description is great. Thank you!


Title: Re: Triangle Inequality Average Coloring
Post by: superheal on April 21, 2017, 04:15:40 PM
I tried to reproduce the result but I got this
http://imgur.com/a/JCyPd

there are discontinuities between the bailout bands, anyone knows what might causing this?


Title: Re: Triangle Inequality Average Coloring
Post by: superheal on April 21, 2017, 04:34:32 PM
Nevermind I changed the smoothing method, to general smoothing that uses the current and previous value of z and got it to work.

http://imgur.com/a/Ex7wx


Title: Re: Triangle Inequality Average Coloring
Post by: Adam Majewski on April 21, 2017, 06:00:49 PM
How do you run this code ? ( gcc, fragmentarium, shadertoy ? )
It is fragment or vertex shader ?


Title: Re: Triangle Inequality Average Coloring
Post by: Adam Majewski on April 21, 2017, 06:16:00 PM
How do you run this code ? ( gcc, fragmentarium, shadertoy ? )
can you post the code ?


Title: Re: Triangle Inequality Average Coloring
Post by: CalvinCreator on April 21, 2017, 10:59:41 PM
I turned the GLSL code into a java program that I have been executing, although I am not sure I did it correctly. When I set the bailout value too high (over 10^5) the value of z becomes NaN as far as Java is concerned so the algorithm breaks. I would think this is because the number is too big, but I'm not getting an error so I don't know. Even when it doesn't work, when the bailout value is close to the limit I get color bands like this:
http://imgur.com/a/yeU2L
When I make the bailout lower, like 10^3, it looks like this:
http://imgur.com/a/odP3i

There are two things I see wrong with this: a, my understanding is the Triangle Inequality Average Coloring works best with high bailout values--I believe 10^20 is recommended and b, the second option looks the same regardless of whether or not I use the calculated fractional value to interpolate between the two colors.

Any ideas?


Title: Re: Triangle Inequality Average Coloring
Post by: CalvinCreator on April 22, 2017, 12:35:53 AM
Additionally, when I zoom in a lot all contrast disappears. I seems most of my color palette is not being used, or not being used often. Why is this?

http://imgur.com/a/wwfhM


Title: Re: Triangle Inequality Average Coloring
Post by: Softology on April 25, 2017, 10:54:10 PM
How do you run this code ? ( gcc, fragmentarium, shadertoy ? )
It is fragment or vertex shader ?

The shader code is included above.
I use my own software http://softology.com.au/voc.htm which has a shader editor built in, ie
https://softologyblog.wordpress.com/2016/09/18/custom-formula-editor-for-visions-of-chaos/

With minimal changes shadertoy or glsl sandbox could run the code.  You would need to specify the complex plane coordinates and create a palette array.


Title: Re: Triangle Inequality Average Coloring
Post by: Softology on April 25, 2017, 10:59:12 PM
my understanding is the Triangle Inequality Average Coloring works best with high bailout values--I believe 10^20 is recommended

I use 800,000 as a bailout.  It seems to stop the iteration banding and image corruption.

Some areas do lack details when using TIA.  A more busy palette can help, ie one with bands of shaded colors rather than a simple single shade from blue to white.


Title: Re: Triangle Inequality Average Coloring
Post by: xenodreambuie on April 26, 2017, 12:52:40 AM
I wasn't satisfied with pure TIA so did things differently in Jux (and called it Fibers, taking some ideas from a Ron Barnett UF coloring). First, I prefer a running average with a weight parameter (0 - 0.999), which avoids any possible precision issues and lets you adjust detail. Second, I use sin or cos instead of the plain angle, and add a frequency parameter. And some other variations. The results are usually smooth with any bailout over about 3, assuming correct interpolation (and when there are artifacts it tends to be in awkward rational formulas).

Mixing between this and potential or distance estimate also adds a lot more nice control of color.