Welcome to Fractal Forums

Fractal Math, Chaos Theory & Research => Sierpinski Gasket => Topic started by: mclarekin on December 04, 2016, 02:11:41 AM




Title: Implementing Menger Sponge 45 rot
Post by: mclarekin on December 04, 2016, 02:11:41 AM
Implementing Menger Sponge - 45 degree rot of xyplane.

So no cos sin trig

based on code by Trafassel// Gestaltlupe 3.4
http://www.fractalforums.com/ifs-iterated-function-systems/menger-sponge-45-rotation/msg97840/#new



// Menger Sponge Tree
public override bool GetBool(double x,double y,double z)
{
  double sin45 = Math.Sqrt(0.5);
  double scale = 1.81;
  double offsetX = 1.15;
  double offsetY = 0.932;
  double offsetZ = 1.01;
  for (int n=1;n<100;n++)
  {
    x = Math.Abs(x);
    y = Math.Abs(y);
    z = Math.Abs(z);
    // Bailout Condition:
    if (x>2) return false;
    if (y>2) return false;
    if (z>2) return false;
    if (x<y) { double a=x; x=y; y=a; }
    if (x<z) { double a=x; x=z; z=a; }
    if (y<z) { double a=y; y=z; z=a; }
    x = scale*x - offsetX*(scale-1);
    y = scale*y - offsetY*(scale-1);
    z = scale*z - offsetZ*(scale-1);
    // Rotate x,y plane by 45 degree:
    double xtemp = sin45 * ( x - y );
    y = sin45 * ( y + x );
    x = xtemp;
  }
  return true;
}
//......................................
What is interesting us that Trafassel produces non-DE rendered fractals.
They are not a distance estimation approximation of a fractal?
But I will need DE to render with Mandlebulber.

45 degree rotation is the only rotation that "works" with some linear fractals,
so it is a useful transform to include in an exploring frag.


I will need this constant:

const float sin45  = 0.707106781186547524; // not sure on decimal places

A standard menger sponge is made up of four parts

a) The abs(), I will include a pre-add as well:

      z = abs(z + PreAddM);

b) Conditional swizzle
   

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

c) Scale
      z *= ScaleM;
      Dd *= ScaleM; // * Tweak

d) Offset  
      z.x -= OffsetM.x;
      z.y -= OffsetM.y;

      // "true" reverts to standard Menger Sponge
      if (EnableConditionalZ)
      {
         if (z.z > 1.0) z.z -= OffsetM.z;
      }
      else
      {
         z.z -= OffsetM.z;
      }

"If EnableConditionalZ" is just a check box to make a standard menger with conditional offset,
so I can check that the code is correct. So 'else" is non-conditional offset mode.
(this can be replicated in MandelbuberV2.07 Menger_Middle_Mod UI)

I have  modified "offsetX*(scale-1) to  OffsetM.x


Then I added // Rotate x,y plane by 45 degree:
      if ( i >= StartR45 && i < StopR45)
      {  
      float xtemp = sin45 * ( z.x - z.y );
      z.y = sin45 * ( z.y + z.x );
      z.x = xtemp;
      }


I include start & stop parameters to control the complexity of the rotations.

Later I will add some other transforms to the mix.

BTW still have an old rot left in my .frag code because if I delete it, I crash???

      


Title: Re: Implementing Menger Sponge 45 rot
Post by: mclarekin on December 04, 2016, 04:55:37 AM
For exploring, I have added the 45degree XY rot, to the axis swap transform. I can now swap in many 180, 90, 45 degree combinations.


Title: Re: Implementing Menger Sponge 45 rot
Post by: Sabine on December 04, 2016, 12:19:58 PM
@mclarekin Thank you for dissecting the Menger cube! Another learning experience for me :}


Title: Re: Implementing Menger Sponge 45 rot
Post by: DarkBeam on December 04, 2016, 01:33:55 PM
Why? Nonsense... use a rotation matrix :beer: :police:


Title: Re: Implementing Menger Sponge 45 rot
Post by: trafassel on December 04, 2016, 03:13:45 PM
DarkBeam using:

Code:
xtemp = sin45 * ( x - y );
y = sin45 * ( y + x );
x = xtemp;

needs two additions and two multiplications. 3x3 matrix multiplication is more costly.

 


Title: Re: Implementing Menger Sponge 45 rot
Post by: DarkBeam on December 04, 2016, 04:09:21 PM
DarkBeam using:

Code:
xtemp = sin45 * ( x - y );
y = sin45 * ( y + x );
x = xtemp;

needs two additions and two multiplications. 3x3 matrix multiplication is more costly.

 
Not so much and in parallel implements like SSE2 not at all :)


Title: Re: Implementing Menger Sponge 45 rot
Post by: trafassel on December 04, 2016, 10:05:42 PM
SSE2 supports fast inbuild matrix multiplikation? Cool.


Title: Re: Implementing Menger Sponge 45 rot
Post by: mclarekin on December 04, 2016, 10:05:59 PM
When I coded it, I tested it and was surprised to find no obvious difference in speed

For Trafassel's code to run quicker, I would  implement some maths before the iteration loop (4D Menger example)

   // initial conditions
        float scaleM  default 3.0
   vec4 offsetM  default (1.0,1.0,0.5,0.5);
   vec4 opt1 = scaleM - 1.0;
   offsetM *= opt1;
   float opt2 = 0.5 * offsetM.z  / scaleM;

// iteration loop
   z4D.x = scaleM * z4D.x - offsetM.x;
   z4D.y = scaleM * z4D.y - offsetM.y;
   z4D.w = scaleM * z4D.w - offsetM.w;
   z4D.z -= opt2;
   z4D.z = -fabs(-z4D.z);
   z4D.z += opt2;
   z4D.z *= scaleM;
   Dd *= scaleM;


Title: Re: Implementing Menger Sponge 45 rot
Post by: trafassel on December 04, 2016, 10:32:01 PM
Just learned: SSE/SIMD isn't well supported in .Net. There is an implementation for mono, but not in Microsoft .Net. But my job is not to write optimized code for generating fractals or create nice looking pictures.

(Goes away and continues to search for the 3D mandelbrot formula in my research lab.)


Title: Re: Implementing Menger Sponge 45 rot
Post by: DarkBeam on December 04, 2016, 10:49:35 PM
Goodbye then trafassel :beer: