fractower
Iterator
Posts: 173
|
|
« Reply #14 on: September 22, 2011, 04:50:51 PM » |
|
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 < --- >
|