This is a diff of the original fractal.cpp from mandelbulber 1.08 and the generalized box fold changes. The code essentially replaces the Tglad mandelbox box fold with the generalized fold. I had trouble implementing the "folding limit" function, so I have used this parameter to select between a number of polyhedron.

Folding limit polyhedron

default tet

2 cube

3 oct

4 dodeca

5 turncated oct.

Disclaimer. The cube selection does not reproduce the original box fold. This points to a bug in either the theory or the implementation. However it produces some interesting fractals as is. I expect to find the bug when I try to implement the melting poly version suggested by Hobold.

I would be honored if Budda wants to integrate this into the mandelbulber, but he might want to wait a couple of days to see if I can fix the bug and melt some polys.

19a20,111

>

>

> inline CVector3 Cross(CVector3 A , CVector3 B){

> CVector3 C;

> C.x = A.y*B.z - A.z*B.y;

> C.y = -A.x*B.z + A.z*B.x;

> C.z = A.x*B.y - A.y*B.x;

> return (C);

> }

>

> // The box used by the generalized box fold is specified by a set

> // of normalized unit vectors. Each vector is a normal that defines a plane.

> // Xp dot N = foldingvalue.

> #define sqrt_i3 .57735

> CVector3 Nv_tet[] =

> {

> { sqrt_i3, sqrt_i3,-sqrt_i3},

> { sqrt_i3,-sqrt_i3, sqrt_i3},

> {-sqrt_i3, sqrt_i3, sqrt_i3},

> {-sqrt_i3,-sqrt_i3,-sqrt_i3}

> };

>

> int sides_tet = 4;

>

>

> CVector3 Nv_cube[] =

> {

> { 1, 0, 0},

> {-1, 0, 0},

> { 0, 1, 0},

> { 0,-1, 0},

> { 0, 0, 1},

> { 0, 0,-1}

> };

>

> int sides_cube = 6;

>

> CVector3 Nv_oct[] =

> {

> { sqrt_i3, sqrt_i3,-sqrt_i3},

> { sqrt_i3,-sqrt_i3, sqrt_i3},

> {-sqrt_i3, sqrt_i3, sqrt_i3},

> {-sqrt_i3,-sqrt_i3,-sqrt_i3},

> { sqrt_i3, sqrt_i3, sqrt_i3},

> {-sqrt_i3,-sqrt_i3, sqrt_i3},

> {-sqrt_i3, sqrt_i3,-sqrt_i3},

> { sqrt_i3,-sqrt_i3,-sqrt_i3}

> };

>

> int sides_oct = 8;

>

> CVector3 Nv_oct_cube[] =

> {

> { sqrt_i3, sqrt_i3,-sqrt_i3},

> { sqrt_i3,-sqrt_i3, sqrt_i3},

> {-sqrt_i3, sqrt_i3, sqrt_i3},

> {-sqrt_i3,-sqrt_i3,-sqrt_i3},

> { sqrt_i3, sqrt_i3, sqrt_i3},

> {-sqrt_i3,-sqrt_i3, sqrt_i3},

> {-sqrt_i3, sqrt_i3,-sqrt_i3},

> { sqrt_i3,-sqrt_i3,-sqrt_i3},

> { 1, 0, 0},

> {-1, 0, 0},

> { 0, 1, 0},

> { 0,-1, 0},

> { 0, 0, 1},

> { 0, 0,-1}

> };

> int sides_oct_cube = 14;

>

>

> #define aa ((1.0+sqrt(5.0))/2.0)

> #define bb (1.0/sqrt(aa*aa+1))

>

> CVector3 Nv_dodeca[] =

> {

> { 0, bb, aa*bb},

> { 0, bb,-aa*bb},

> { 0,-bb, aa*bb},

> { 0,-bb,-aa*bb},

> { bb, aa*bb, 0},

> { bb,-aa*bb, 0},

> {-bb, aa*bb, 0},

> {-bb,-aa*bb, 0},

> { aa*bb, 0, bb},

> {-aa*bb, 0, bb},

> { aa*bb, 0,-bb},

> {-aa*bb, 0,-bb}

> };

> int sides_dodeca = 12;

>

>

456,484c548,626

< if (z.x > par.mandelbox.doubles.foldingLimit)

< {

< z.x = par.mandelbox.doubles.foldingValue - z.x;

< tgladColor += par.mandelbox.doubles.colorFactorX;

< }

< else if (z.x < -par.mandelbox.doubles.foldingLimit)

< {

< z.x = -par.mandelbox.doubles.foldingValue - z.x;

< tgladColor += par.mandelbox.doubles.colorFactorX;

< }

< if (z.y > par.mandelbox.doubles.foldingLimit)

< {

< z.y = par.mandelbox.doubles.foldingValue - z.y;

< tgladColor += par.mandelbox.doubles.colorFactorY;

< }

< else if (z.y < -par.mandelbox.doubles.foldingLimit)

< {

< z.y = -par.mandelbox.doubles.foldingValue - z.y;

< tgladColor += par.mandelbox.doubles.colorFactorY;

< }

< if (z.z > par.mandelbox.doubles.foldingLimit)

< {

< z.z = par.mandelbox.doubles.foldingValue - z.z;

< tgladColor += par.mandelbox.doubles.colorFactorZ;

< }

< else if (z.z < -par.mandelbox.doubles.foldingLimit)

< {

< z.z = -par.mandelbox.doubles.foldingValue - z.z;

< tgladColor += par.mandelbox.doubles.colorFactorZ;

---

> int i;

> CVector3 *Nv;

> int sides;

> // HACK HACK HACK. I high jacked the foldingLimit parameter to chose the poly type.

> // Do not try this at home.

> Nv = Nv_tet;

> sides = sides_tet;

>

> if(int(par.mandelbox.doubles.foldingLimit) == 2){

> Nv = Nv_cube;

> sides = sides_cube;

> }

> if(int(par.mandelbox.doubles.foldingLimit) == 3){

> Nv = Nv_oct;

> sides = sides_oct;

> }

> if(int(par.mandelbox.doubles.foldingLimit) == 4){

> Nv = Nv_dodeca;

> sides = sides_dodeca;

> }

> if(int(par.mandelbox.doubles.foldingLimit) == 5){

> Nv = Nv_oct_cube;

> sides = sides_oct_cube;

> }

>

> int sort[3];

> int tmp_sort;

> double Z_Dot_Nv[3];

> double tmp_Z_Dot_Nv;

>

> // Find the three closest normal vectors to z as defined by max dot product.

> sort[0] = 0;

> Z_Dot_Nv[0] = z.Dot(Nv[0]);

> sort[1]= 1;

> Z_Dot_Nv[1] = z.Dot(Nv[1]);

> sort[2]= 2;

> Z_Dot_Nv[2] = z.Dot(Nv[2]);

>

> if(Z_Dot_Nv[1]>Z_Dot_Nv[0]){

> tmp_sort = sort[0];

> tmp_Z_Dot_Nv = Z_Dot_Nv[0];

> sort[0] = sort[1];

> Z_Dot_Nv[0]=Z_Dot_Nv[1];

> sort[1]=tmp_sort;

> Z_Dot_Nv[1]= tmp_Z_Dot_Nv;

> }

> if(Z_Dot_Nv[2]>Z_Dot_Nv[1]){

> tmp_sort = sort[1];

> tmp_Z_Dot_Nv = Z_Dot_Nv[1];

> sort[1] = sort[2];

> Z_Dot_Nv[1]=Z_Dot_Nv[2];

> sort[2]=tmp_sort;

> Z_Dot_Nv[2]=tmp_Z_Dot_Nv;

> }

> if(Z_Dot_Nv[1]>Z_Dot_Nv[0]){

> tmp_sort = sort[0];

> tmp_Z_Dot_Nv = Z_Dot_Nv[0];

> sort[0] = sort[1];

> Z_Dot_Nv[0]=Z_Dot_Nv[1];

> sort[1]=tmp_sort;

> Z_Dot_Nv[1]= tmp_Z_Dot_Nv;

> }

>

> for(i=3;i<sides;i++){

> tmp_Z_Dot_Nv = z.Dot(Nv[i]);

> tmp_sort = i;

> if(tmp_Z_Dot_Nv>Z_Dot_Nv[2]){

> sort[2] = tmp_sort;

> Z_Dot_Nv[2]= tmp_Z_Dot_Nv;

> if(tmp_Z_Dot_Nv>Z_Dot_Nv[1]){

> sort[2] = sort[1];

> Z_Dot_Nv[2]=Z_Dot_Nv[1];

> sort[1]=tmp_sort;

> Z_Dot_Nv[1]= tmp_Z_Dot_Nv;

> if(tmp_Z_Dot_Nv>Z_Dot_Nv[0]){

> sort[1] = sort[0];

> Z_Dot_Nv[1]=Z_Dot_Nv[0];

> sort[0]=tmp_sort;

> Z_Dot_Nv[0]= tmp_Z_Dot_Nv;

485a628,674

> }

> }

> }

> CVector3 Nv0=Nv[sort[0]];

> CVector3 Nv1=Nv[sort[1]];

> CVector3 Nv2=Nv[sort[2]];

>

> CVector3 new_z;

> double new_z_sqr;

> CVector3 Zm;

>

> // Assume z inside the poly and we are wasting our time.

> new_z = z;

> new_z_sqr = new_z.Dot(new_z);

>

> // Find reflection point to closest plain.

> Zm = z - (Nv0 + Nv0)*(z.Dot(Nv0) - par.mandelbox.doubles.foldingValue);

> if(new_z_sqr > Zm.Dot(Zm)){

> new_z = Zm;

> new_z_sqr = new_z.Dot(new_z);

> tgladColor += par.mandelbox.doubles.colorFactorX;

> }

>

> // Find rotation point to closest line.

> CVector3 T01, L01;

> L01 = Cross(Nv0,Nv1);

> L01 = L01 * (1.0/L01.Length());

> T01 = (Nv0+Nv1) * ( (par.mandelbox.doubles.foldingValue)/(1 + Nv0.Dot(Nv1)));

> CVector3 Zr;

> Zr = (T01 + L01 * z.Dot(L01)) * 2 - z;

> if(new_z_sqr > Zr.Dot(Zr)){

> new_z = Zr;

> new_z_sqr = new_z.Dot(new_z);

> tgladColor += par.mandelbox.doubles.colorFactorY;

> }

>

> // Find inversion point to closest vert.

> CVector3 Zi;

> double a;

> a = ((par.mandelbox.doubles.foldingValue)-T01.Dot(Nv2))/(L01.Dot(Nv2));

> Zi = (L01*a + T01) * 2 - z;

> if(new_z_sqr > Zi.Dot(Zi)){

> new_z = Zi;

> new_z_sqr = new_z.Dot(new_z);

> tgladColor += par.mandelbox.doubles.colorFactorZ;

> }

> z = new_z;

487c676

<

---

>