Logo by Maya - Contribute your own Logo!

END OF AN ERA, FRACTALFORUMS.COM IS CONTINUED ON FRACTALFORUMS.ORG

it was a great time but no longer maintainable by c.Kleinhuis contact him for any data retrieval,
thanks and see you perhaps in 10 years again

this forum will stay online for reference
News: Check out the originating "3d Mandelbulb" thread here
 
*
Welcome, Guest. Please login or register. March 29, 2024, 02:51:24 AM


Login with username, password and session length


The All New FractalForums is now in Public Beta Testing! Visit FractalForums.org and check it out!


Pages: [1] 2   Go Down
  Print  
Share this topic on DiggShare this topic on FacebookShare this topic on GoogleShare this topic on RedditShare this topic on StumbleUponShare this topic on Twitter
Author Topic: Triangle Inequality Average Coloring  (Read 7883 times)
Description: No clue how to do it
0 Members and 1 Guest are viewing this topic.
CalvinCreator
Forums Newbie
*
Posts: 9


« 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!
Logged
Softology
Conqueror
*******
Posts: 120


« Reply #1 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);
}
« Last Edit: April 20, 2017, 01:48:01 AM by Softology » Logged
Adam Majewski
Fractal Lover
**
Posts: 221


WWW
« Reply #2 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
« Last Edit: April 21, 2017, 09:48:35 PM by Adam Majewski, Reason: new link » Logged
CalvinCreator
Forums Newbie
*
Posts: 9


« Reply #3 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.
Logged
Softology
Conqueror
*******
Posts: 120


« Reply #4 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.
Logged
xenodreambuie
Conqueror
*******
Posts: 124



WWW
« Reply #5 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.
Logged

Regards, Garth
http://xenodream.com
CalvinCreator
Forums Newbie
*
Posts: 9


« Reply #6 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!
Logged
superheal
Alien
***
Posts: 24


« Reply #7 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?
Logged
superheal
Alien
***
Posts: 24


« Reply #8 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
Logged
Adam Majewski
Fractal Lover
**
Posts: 221


WWW
« Reply #9 on: April 21, 2017, 06:00:49 PM »

How do you run this code ? ( gcc, fragmentarium, shadertoy ? )
It is fragment or vertex shader ?
« Last Edit: April 23, 2017, 12:17:10 PM by Adam Majewski, Reason: ext » Logged
Adam Majewski
Fractal Lover
**
Posts: 221


WWW
« Reply #10 on: April 21, 2017, 06:16:00 PM »

How do you run this code ? ( gcc, fragmentarium, shadertoy ? )
can you post the code ?
Logged
CalvinCreator
Forums Newbie
*
Posts: 9


« Reply #11 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?
Logged
CalvinCreator
Forums Newbie
*
Posts: 9


« Reply #12 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
Logged
Softology
Conqueror
*******
Posts: 120


« Reply #13 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.
Logged
Softology
Conqueror
*******
Posts: 120


« Reply #14 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.
Logged
Pages: [1] 2   Go Down
  Print  
 
Jump to:  


Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM
Page created in 0.217 seconds with 24 queries. (Pretty URLs adds 0.012s, 2q)