Welcome to Fractal Forums

Fractal Software => Fragmentarium => Topic started by: Roquen on August 28, 2013, 05:24:04 PM




Title: Fractal + Change of domain mashup
Post by: Roquen on August 28, 2013, 05:24:04 PM
First pass at a simple example of using domain distortion with a fractal.  Standard m-set fractal where c = T(s) and 's' is input in the sampling domain.  The single transform is this:

T(s) = (1/s) + k

which maps a fixed point 'k' to infinity.  The presets which match images commonly seen are: "Cusp", "Origin" and "Needle".

(NOTE: The actual transform in the code is: s/dot(s,s)+k which is eqv. due to the sym about the x-axis)


Title: Re: Fractal + Change of domain mashup
Post by: 3dickulus on August 29, 2013, 11:10:20 AM
The first thing I wondered while looking at a fractal using your "domain mashup" was : Very nice! will it apply to a 3D fractal like a mandelbulb?...

It does ?

(http://domain-transform.jpg)

Code:
vec3 domainMap(vec3 c)
{
  float s = dot(c,c);
  return c/s;
}
called like...
Code:
z = domainMap(z);
right before the powN1 function in DE of mandelbulb.frag

Would this be a Roquen-bulb? or is that just plain 3Dickulus :laugh:
I just rendered a few preliminary shots but I think this object warrants some more exploration.


Title: Re: Fractal + Change of domain mashup
Post by: Roquen on August 29, 2013, 11:29:33 AM
I banged out my post quickly.  I mentioned application to all fractals in this post: http://www.fractalforums.com/index.php?topic=16887.msg64838#msg64838

So if the bulb formulation is using DE, you'd want to compare against a non-DE version so see if any undesirable defects are being introduced.  Change of domains is a very powerful technique IMHO.

Also I should note that the transform above is a tricky one in that it make larger changes of the visual domain and that the implementation blows chunks for precision. 


Title: Re: Fractal + Change of domain mashup
Post by: 3dickulus on August 29, 2013, 02:25:03 PM
read that post, wow, my brain hurts, that's some pretty heady stuff, I'll have to read it one or two more times to let it soak in
http://www.fractalforums.com/index.php?action=gallery;sa=view;id=14769 (http://www.fractalforums.com/index.php?action=gallery;sa=view;id=14769) a picture is worth a thousand... utterations :)


Title: Re: Fractal + Change of domain mashup
Post by: Roquen on August 29, 2013, 02:53:01 PM
Thanks for tossing up some 3D examples.  I joined DeviantArt (http://roquendm.deviantart.com) and tossed up some example from the example code above, but don't see how embedded them in the post.

I'll try to toss a post together that might make more sense to more people.



Title: Re: Fractal + Change of domain mashup
Post by: 3dickulus on August 29, 2013, 04:29:27 PM
The image in my gallery has a slight twist...
Added a float3 widget for invertC as in the 2D version and...
Code:
// coordinate to invert to infinity
uniform vec3 InvertC; slider[(-5,-5,-5),(0,0,0),(5,5,5)]

// performs the active c = T(s)
vec3 domainMap(vec3 c)
{
  float s = dot(c,c);
  return c/s + InvertC;
}
called as...
Code:
z += domainMap(-z);
...right after the Julia test  z+= JuliaC : pos
seemed to give the bulb more body less holes and then I got to fiddling with the parameters and, well, there you have it  :)
another tool in the kit Thanks Roquen, I'm starting to enjoy playing with the GLSL side of Fragmentarium.


Title: Re: Fractal + Change of domain mashup
Post by: Roquen on August 29, 2013, 05:02:23 PM
Here's a quick example of me attempting to design a domain from scratch to achieve a specific result.  I just grabbed a raytracing routine which is used to map values in a unit square (from a pseudo or quasi random number generator) to a unit circle.  This has no basis in complex numbers...it's just an ad-hoc function.  Visually we'll see the opposite...we'll see circles being mapped to squares.  Here's the base code:

Code:
const float M_PI = 3.141592653589793238463;
const float M_PI_2 = (M_PI * 0.5);
const float M_PI_4 = (M_PI * 0.25);

// Map 'c' within unit square ([0,1],[0,1]) to a unit disk
vec2 toUnitDisk(vec2 c)
{
  c += c;

  float a = c.x - 1.0;
  float b = c.y - 1.0;
  float t,r;
 
  if (a*a > b*b) {
    r = a;
    t = M_PI_4*(b/a);
  } else {
    r = b;
    t = M_PI_2 - M_PI_4*(a/b);
  }
 
  return r*vec2(cos(t),sin(t));
}

vec2 zortho(vec2 a) { return vec2(-a.y, a.x); }

So I replaced the contents of domainMap with "return toUnitDisk(c);"  which ended up looking humanoid like, but turn sidewise.  So to place the "head" up I needed to rotate it in the visual domain, so I changed the code to this:

Code:
vec2 domainMap(vec2 c) { return toUnitDisk(zortho(c)); }

Which results in this image: http://roquendm.deviantart.com/art/Square1-396691344

There are no squares because we don't have any circles about the origin, so let's get a square.  There's a circle at (-1,0) so let's move that to the origin (from the function's perspective) and try again:

Code:
vec2 domainMap(vec2 c) { return toUnitDisk(c)-vec2(1.0,0.0); }

Which results in this image: http://roquendm.deviantart.com/art/Square2-396691523

Fun a square and a heart!  Of course the image is distorted due to the nature of the transform.  If I really cared I could try to come up with another transform to attempt to correct that.

Anyone that want to play around with this stuff, try looking at the domain plots I posted here: http://s824.photobucket.com/user/RoquenDM/library/DomainPlots?sort=9&page=1.

Examine the identity transform and some other transform and then use that other transform for your domain mapping function.

Also fragmentarium has an example: Experimental/LiftedDomainColoring.

While I'm at it the domain images were created with Mathematica with some code I lifted from somewhere, here it is:
Code:
complexGrid = 
  Compile[{{max, _Real}, {n, _Integer}},
   Module[{r}, r = Range[-max, max, 2 max/(n - 1)];
    Outer[Plus, -I r, r]]];

complexHSB =
  Compile[{{Z, _Complex, 2}},
   Module[{h, s, b, b2}, h = 0.5 + Arg[Z]/(2 Pi);
    s = Abs[Sin[2 Pi Abs[Z]]];
    b = Abs[Sin[2 Pi Im[Z]] Sin[2 Pi Re[Z]]]^0.25;
    b2 = 0.5 ((1 - s) + b + Sqrt[(1 - s - b)^2 + 0.01]);
    Transpose[{h, Sqrt[s], b2}, {3, 1, 2}]]];

domainImage[func_, max_, n_] :=
  ImageResize[
   ColorConvert[
    Image[complexHSB@func@complexGrid[max, 2 n], ColorSpace -> "HSB"],
     "RGB"], n];

domainPlot[func_, max_: Pi, n_: 500] :=
  ContourPlot[0, {x, -max, max}, {y, -max, max}, Contours -> {},
   RotateLabel -> False,
   FrameLabel -> {"X", "Y", ToString@StandardForm@func@"z"},
   BaseStyle -> {FontFamily -> "Calibri", 14},
   Epilog ->
    Inset[domainImage[func, max, n], {0, 0}, {Center, Center},
     2` max]];

And usage examples:
Code:
domainPlot[# &] (* identity *)

F[z_] := Abs[Re[z]] + I Im[z]  (* the fold used in kaliset *)
domainPlot[F[#] &]

F[z_] = Sqrt[z*z]      (* note relation to the kaliset fold *)
domainPlot[F[#] &]

domainPlot[Sin]         (* zeroes along the x-axis yield one origin per zero, unless there's a constant added, in that case the constant will be the point of the base fractal mapped to the zero *)


Title: Re: Fractal + Change of domain mashup
Post by: Roquen on August 29, 2013, 09:17:47 PM
called as...
Code:
z += domainMap(-z);
This is awesome because recall that this first transform is suppose to be: T(s) = 1/s + k.  1/s = s*/dot(s,s) and I dropped the conjugate as an example of making use of a symmetry...specifically about the x-axis which makes the conjugate not needed.  Moving to 3D, then T(s) = 1/s + k = s*/dot(s,s) + k = -s/dot(s,s) + k.


Title: Re: Fractal + Change of domain mashup
Post by: 3dickulus on August 30, 2013, 12:15:52 AM
Quote
This is awesome ...
I was playing with the idea of mapping the difference between current pos and the accumulated z coord ie:
Code:
 z += domainMap(pos-z);
but again, that made for a very dense core with a majority of solutions beyond maxiter, holes.

You have some great images there, the domain plots are particularly interesting, I'm looking for a different color scheme than orbittrap, this might be helpful.


Title: Re: Fractal + Change of domain mashup
Post by: 3dickulus on August 30, 2013, 02:46:10 AM
an image to illustrate the difference
LEFT pos-z RIGHT -z


Title: Re: Fractal + Change of domain mashup
Post by: 3dickulus on August 30, 2013, 03:12:17 AM
and here we are plotting it for color as in...
Code:
if (i<ColorIterations) orbitTrap = min(orbitTrap, abs(vec4(domainMap(-z),r)));
...where r = length(z);

cool :)


Title: Re: Fractal + Change of domain mashup
Post by: Roquen on September 06, 2013, 03:38:35 PM
Little free time ATM.  Completed a hacky port of my example above to webgl: http://glsl.heroku.com/e#10873.3 (http://glsl.heroku.com/e#10873.0) for folks without fragmentarium.


Title: Re: Fractal + Change of domain mashup
Post by: Roquen on September 10, 2013, 05:07:20 PM
In a moment of work avoidance, I tossed a picture together which isn't one of the presets:

(http://i824.photobucket.com/albums/zz168/RoquenDM/DomainMashup/MsCiLt_zpsbdccd98f.jpg) (http://s824.photobucket.com/user/RoquenDM/media/DomainMashup/MsCiLt_zpsbdccd98f.jpg.html)


Title: Re: Fractal + Change of domain mashup
Post by: Nahee_Enterprises on September 11, 2013, 04:20:07 AM
    In a moment of work avoidance, I tossed a picture together which isn't one of the presets:

A couple of interesting areas in this image.     :D
 


Title: Re: Fractal + Change of domain mashup
Post by: Roquen on September 12, 2013, 02:16:11 PM
Fixed some bugs in the WebGL example: http://glslsandbox.com/e#10873.3


Title: Re: Fractal + Change of domain mashup
Post by: SCORPION on December 28, 2013, 05:02:53 AM
This option turned out to Mandelbulb:

Code:
uniform vec3 InvertC; slider[(-5,-5,-5),(0,0,0),(5,5,5)]

vec3 domainMap(vec3 c)
{
  float s = dot(c,c);
  return c=s * InvertC;
}


Code:
  if (i<ColorIterations) orbitTrap = min(orbitTrap, abs(vec4(domainMap(pos),r*r)));


Title: Re: Fractal + Change of domain mashup
Post by: Roquen on January 06, 2014, 11:05:57 AM
It's probably worth pointing out that if you're using some change of domain function for something other than geometry then it opens up a wider class of functions since you no longer need them to be locally continuous.  In fact those that are not can be pretty interesting since you can get "strata/banding" and reaction-diffusion (to name a couple) like effects in (as in the previous example) it's being used as a coloring function.


Title: Re: Fractal + Change of domain mashup
Post by: Roquen on August 29, 2014, 12:01:11 PM
Logistic's map

Code:
vec2 domainMap(vec2 c)
{
  //c = 0.5*c;             // only effects resulting scale
  c = zpow2(c) - c;      // give the domain two zeros
  c   +=K ;
  return c;
}

http://glslsandbox.com/e#19502.1


Title: Re: Fractal + Change of domain mashup
Post by: 3dickulus on March 06, 2016, 11:50:36 PM
just noticed the new post (better late than never)
when I get some time to play with GLSL I will be exploring the effect in 3D

ty Roquen, for another little toy/tool  :beer:


Title: Re: Fractal + Change of domain mashup
Post by: 3dickulus on March 07, 2016, 01:00:25 AM
modified for 3D, frag attached...