Welcome to Fractal Forums

Fractal Software => Programming => Topic started by: tryptophan on October 26, 2013, 10:44:43 PM




Title: Boolean operation on a point (vector)?
Post by: tryptophan on October 26, 2013, 10:44:43 PM
I'm wondering if there is way to do an boolean intersection on a formula using the point position (vector) rather than the distance (float). Basically I would like to cut just a sphere out of a formula before the distance estimate is calculated.

thanks
Keith


Title: Re: Boolean operation on a point (vector)?
Post by: DarkBeam on October 27, 2013, 10:35:07 AM
I think you are mixing what cannot be mixed!
A "sphere" is defined by the distance of its surface because it is a "surface" (lol)
How can you ever "subtract" this from a "formula"...  and what you mean?

:)


Title: Re: Boolean operation on a point (vector)?
Post by: tryptophan on October 27, 2013, 06:00:34 PM
Yeah I thought I was approaching it from the wrong angle. Basically I have a formula that continues in all directions infinitely (I call it spherical) and after the distance estimate I am using a boolean intersection using a sphere to "cut" the infinitely repeating fractal so only a sphere of it is left. I am then mixing that DE with another. My problem is that because I am cutting the sphere after the orbit trap calculations it is coloring areas where the the fractal no longer exists (ie where the other formula exists).

I tried another approach where I used an if statement to test if the point was within a certain radius but I couldn't seem to get to work but I think that is the way I would have to do it? If it is is possible?

cheers
Keith


Title: Re: Boolean operation on a point (vector)?
Post by: ker2x on October 28, 2013, 08:44:07 AM
I don't understand, you want to do CSG ? http://en.wikipedia.org/wiki/Constructive_solid_geometry


Title: Re: Boolean operation on a point (vector)?
Post by: eiffie on October 28, 2013, 05:13:53 PM
It sounds like you have to orbit trap both formulas then choose which trap to color with by testing which formula you hit.


Title: Re: Boolean operation on a point (vector)?
Post by: tryptophan on October 28, 2013, 05:40:15 PM
Thanks I am using an intersection now but I'm trying to figure out a way not to.  Ah thanks Effie I was just typing my formula now.  Here is the formula:

Code:
par int ColorIterations 2 100 20 val
par int ColoringType 0 4 0 val
par float ColorScale 0.0 2.0 1.0 val
par float ColorOffset -2.0 2.0 0.0 val
par int sIterations 0 100 20 val
par vec3 sOffset -10 10 0 val
par float sZoom 0 4 1 val
par float sScale 0 6 1 val
par float sFatness 0 10 2 val
par vec3 sJulia -10 10 -1 val
par vec2 sJulia2MinMax -1 100 -1 val
par vec3 sJulia2 -10 10 0 val
par float sMoonSize 0 4 1 val

par int kIterations 0 100 20 val
par float kScale 0 6 2 val
par float kFatness 0 5 0 val
par vec3 kOffset -10 10 .5 val
par vec3 kFold -4 4 0 val
par vec3 kJulia -4 4 0 val
par vec3 kJulia2 -4 4 0 val
par vec2 kJulia2MinMax -1 100 -1 val
par vec3 Rotate -360 360 0 val
par vec2 RotMinMax -1 100 -1 val
par float OutputMode 0 1 0 val
par float OrbitSK 0 1 0 val
par vec3 kRotate2 -360 360 0 val

float r;
int n = 0;
mat3 rot;
mat3 rot2;

void init()
{
rot = rotationAngleMatrixXYZ(Rotate);
rot2 = rotationAngleMatrixXYZ(kRotate2);
}

float sminPoly( float a, float b, float k )
{
    float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
    return mix( b, a, h ) - k*h*(1.0-h);
}

float absScalem1 = abs(kScale - 1.0);
float AbsScaleRaisedTo1mIters = pow(abs(kScale), float(1-kIterations));
float absScale = abs(kScale);

float DE(vec3 p)
{
vec3 p2 = p;

orbitTrap = vec4(1000.0);

float fat = sFatness;
vec3 sP = p * sZoom - sOffset;
vec4 sOrbitTrap = orbitTrap;
vec4 kOrbitTrap = orbitTrap;

float dr = 1.0;
int n = 0;

float l = 0;
float prevl = 0;

for( int i=0; i<sIterations;i++ )
{
// Spherical

prevl = l;

sP = abs(sP);
float sR = dot(sP,sP);

   if (i <= ColorIterations)
   {
   if (ColoringType==0) sOrbitTrap = min(sOrbitTrap, vec4((1/sP),sR) );    
   if (ColoringType==1) sOrbitTrap = min(sOrbitTrap, abs(vec4(sP.xyz,0)));
   if (ColoringType==2) sOrbitTrap = min(sOrbitTrap, vec4((1/sP),sR));
   if (ColoringType==3) sOrbitTrap = min(sOrbitTrap, vec4((1/sP),sR));

   //if (ColoringType==2) sOrbitTrap += exp(-1/abs(l+prevl+ColorOffset));
   //if (ColoringType==3) sOrbitTrap+=abs(l-prevl+ColorOffset);
   }
   l = length(sP);
float k = max(sScale/sR,0.1);
sP     *= k;
fat *= k;
sP += sJulia;

if  (i >= int(sJulia2MinMax.x) && i <= int(sJulia2MinMax.y)) sP += sJulia2;
//if  (i >= int(RotMinMax.x) && i <= int(RotMinMax.y)) sP *= rot;
}

l = 0.0;
prevl =0.0;

p *= rot2;

        //IFS
while (n < kIterations)
{
prevl = l;

p-= 2.0 * min(0.0, dot(p, vec3(-0.5, 0.309017, 0.809017))) * vec3(-0.5, 0.309017, 0.809017);
p-= 2.0 * min(0.0, dot(p, vec3(0.309017, 0.809017, -0.5))) * vec3(0.309017, 0.809017, -0.5);
p-= 2.0 * min(0.0, dot(p, vec3(0.809017, -0.5, 0.309017))) * vec3(0.809017, -0.5, 0.309017);
p-= 2.0 * min(0.0, dot(p, vec3(-0.5, 0.309017, 0.809017))) * vec3(-0.5, 0.309017, 0.809017);
p-= 2.0 * min(0.0, dot(p, vec3(0.309017, 0.809017, -0.5))) * vec3(0.309017, 0.809017, -0.5);
p-= 2.0 * min(0.0, dot(p, vec3(0.809017, -0.5, 0.309017))) * vec3(0.809017, -0.5, 0.309017);
p-= 2.0 * min(0.0, dot(p, vec3(-0.5, 0.309017, 0.809017))) * vec3(-0.5, 0.309017, 0.809017);
p-= 2.0 * min(0.0, dot(p, vec3(0.309017, 0.809017, -0.5))) * vec3(0.309017, 0.809017, -0.5);
p-= 2.0 * min(0.0, dot(p, vec3(0.809017, -0.5, 0.309017))) * vec3(0.809017, -0.5, 0.309017);

if (p.x<p.y) p.xy = p.yx;
if (p.x<p.z) p.xz = p.zx;
if (p.y<p.z) p.yz = p.zy;

p -= kJulia;
p = abs(p+kFold)-kFold;
p = p*kScale - kOffset*(kScale-1.0);
float kR = dot(p, p);

if (n <= ColorIterations)
   {
   if (ColoringType==0) kOrbitTrap = min(kOrbitTrap, vec4(p,kR) );    
   if (ColoringType==1) kOrbitTrap = min(kOrbitTrap, abs(vec4(p.xyz,0)));
   if (ColoringType==2) kOrbitTrap = min(min(kOrbitTrap, vec4(p,kR)),sOrbitTrap);
   if (ColoringType==3) kOrbitTrap = min(min(kOrbitTrap, vec4(p,kR)),sOrbitTrap);

   //if (ColoringType==2) kOrbitTrap += exp(-1/abs(l-prevl+ColorOffset));
  //if (ColoringType==3) kOrbitTrap += abs(l-prevl+ColorOffset);
   }

//if (n <= ColorIterations) kOrbitTrap = min(kOrbitTrap, vec4((p),kR) );

dr *= absScale;  
if  (n >= int(kJulia2MinMax.x) && n <= int(kJulia2MinMax.y)) p -= kJulia2;
if  (n >= int(RotMinMax.x) && n <= int(RotMinMax.y)) p *= rot;

l = length(p);

n++;
}

orbitTrap = mix(sOrbitTrap,kOrbitTrap,OrbitSK)* ColorScale + ColorOffset;
//if (ColoringType==3) orbitTrap/=ColorIterations;
//orbitTrap = min(sOrbitTrap,kOrbitTrap);

float d;

d = max(sdSphere(p2,sMoonSize),0.25*length(sP.xyz)/fat);

//float da = length(p)  * pow(kScale, -float(n))-(kFatness * 0.001);

float db = ((length(p) - absScalem1) / dr - AbsScaleRaisedTo1mIters)-(kFatness * 0.001);

//float mn = min(d,db);

float mn = sminPoly(d,db,OutputMode);

return mn;
}

void main() { RayMarchMain(); }

This formula basically blends two formulas an infinitely repeating spherical formula and an IFS but in the line:
Code:
d = max(sdSphere(p2,sMoonSize),0.25*length(sP.xyz)/fat);
A boolean intersection is done on the "Spherical" formula with a sphere so only globe of the "Spherical" formula appears.

What I would like to do is modify the "Spherical" formula so it stops at a certain radius rather than use a boolean.  I've tried something like:
Code:
float dist = length(p);
   if (dist > sMoonSize) break;

in the beginning of the "Spherical" iteration and it does work and does stop the formula from continuing beyond a set size but it doesn't draw properly.  I'm not sure...


Title: Re: Boolean operation on a point (vector)?
Post by: tryptophan on October 28, 2013, 05:46:49 PM
Now though because the boolean is done after the orbit test it will still color the IFS (with Spherical orbit traps) where the Spherical doesn't appear outside of the "globe" radius. It does work perfectly where the Spherical formula doesn't exist within the formula itself. I'll post some images.


Title: Re: Boolean operation on a point (vector)?
Post by: tryptophan on October 28, 2013, 06:29:42 PM
Sorry it wasn't working. So Eiffie I do have two orbit trap formulas but I'm not sure how to test which surface was hit in the renderer?


Title: Re: Boolean operation on a point (vector)?
Post by: eiffie on October 28, 2013, 06:49:47 PM
Here is what I do...

float d1=max(InfiniteFractalDE,SphereDE);
float d2=OtherThingyDE;
float mn=min(d1,d2);
if(abs(mn-d1)<0.0001){//you hit the InfiniteFractal inside the sphere
  orbitTrap=InfiniteFractalOrbitTrap;
}else orbitTrap=OtherThingiesOrbitTrap;

I hope the technical jargon isn't too much :)


Title: Re: Boolean operation on a point (vector)?
Post by: tryptophan on October 28, 2013, 06:58:17 PM
Sweet!!! I understand! Thanks Effie again for the amazing help.

cheers
Keith


Title: Re: Boolean operation on a point (vector)?
Post by: cKleinhuis on October 28, 2013, 07:04:09 PM
I was about to answer as well but it seems to be settled, i talked about basic de combinations in the tutorial4 of chaostube along with the axolotl script and a sweet smooth min function dont want to spam around so you gotta find it yourself i think it might be of help


Title: Re: Boolean operation on a point (vector)?
Post by: tryptophan on October 28, 2013, 07:07:51 PM
Thanks I'll check it out asap. For sure.