Logo by jwm-art - Contribute your own Logo!

END OF AN ERA, FRACTALFORUMS.COM IS CONTINUED ON FRACTALFORUMS.ORG

it was a great time but no longer maintainable by c.Kleinhuis contact him for any data retrieval,
thanks and see you perhaps in 10 years again

this forum will stay online for reference
News: Visit us on facebook
 
*
Welcome, Guest. Please login or register. July 27, 2021, 08:45:02 AM


Login with username, password and session length


The All New FractalForums is now in Public Beta Testing! Visit FractalForums.org and check it out!


Pages: [1] 2   Go Down
  Print  
Share this topic on DiggShare this topic on FacebookShare this topic on GoogleShare this topic on RedditShare this topic on StumbleUponShare this topic on Twitter
Author Topic: Generalized Box Fold.  (Read 5275 times)
Description: Generalized conformal convex box fold algorithm.
0 Members and 1 Guest are viewing this topic.
fractower
Iterator
*
Posts: 173


« on: August 25, 2010, 07:09:02 AM »

I have taken up Tglad's Mandelbox advanced folding challenge and think I have an algorithm for a generalized conformal box fold. Consider any convex box (cube, tet, potato etc.). Identity map any point inside the box. For any point outside the box find the closest point on the box and perform a point inversion. Because the box is convex the closest point is unique.

Now apply this to a cube. Any localized group of points where the closest point is a plane will be reflected. Any localized group of points which are closest to a line will be rotated by Pi around the line. Any localized group of points which are closest to a vertex will be inverted through the vertex. This performs the same operation as the box fold for a greatly increased computational cost.

Now apply this algorithm to any convex box consisting of planes, edges and vortexes. The result is a kind of conformal convex box inversion which preserves the symmetry of the box. I suspect that any resulting images will be less interesting than those obtained using the kaleidoscope method since symmetries are often boring, but Who CAres WheN WE ARE TAlKInG ABOUT MATH PURITY... OOPS, I tend to over capitalize when I get excited.

I am not sure that applying this to a box with curves will not be conformal, but it may result in interesting pictures.


Logged
hobold
Fractal Bachius
*
Posts: 573


« Reply #1 on: August 25, 2010, 03:13:26 PM »

I agree, this algorithm really does lead to a contiguous conformal mapping. I am not sure if it is really equivalent to the Mandelbox, though.

There is one kind of "curvy boxes" to which this construction can be easily generalized. As an example, take the set of points that are exactly at some given distance d from a given cube. This gets you a rounded cube: faces are still flat squares, but edges are now cylindrical and corners are spherical surface patches (both of radius d). The original reflection with respect to the the closest point can still be done with this new surface, and still leads to a contiguous conformal mapping.
Logged
fractower
Iterator
*
Posts: 173


« Reply #2 on: August 25, 2010, 08:29:30 PM »


The box fold equivalence probably needs a bit more explanation. For the box fold the points outside the box will be reflected 1, 2, or 3 times by orthogonal planes. A single reflection is just a reflection. Two reflections is equivalent to a rotation by Pi around the line of intersection. Three reflections is equivalent to a point inversion through the point of intersection of the three planes. The points which are reflected only once are in a prism projection orthogonal to a cube face which coincidentally are the points whose closest point to the cube is that cube face. A similar wedge and pyramid exist for the 2 and 3 reflection points.

The melted cube will be relatively easy to implement. The result of the 6 comparisons used to determine the box folds can also be used to determine the whether a reflection, rotation or inversion is to be performed. It will also be nice to compare with the original Mandelbox.
Logged
Tglad
Fractal Molossus
**
Posts: 703


WWW
« Reply #3 on: August 26, 2010, 03:50:28 AM »

Nice way to think of the box fold and it sounds like it does indeed generalise to any convex polyhedron fold, and it isn't a sequence of folds so is symmetric. Its quite similar to msltoe's fractals in the way it reflects around nearest points on a polyhedron http://www.fractalforums.com/3d-fractal-generation/sierpinski-like-fractals-using-an-iterative-function/.
Can't do curvy folds without losing conformality (or whatever the word is), but might make nice, stretchy results none-the-less. Also, it you couldn't use this directly on a spherical fold as the distance to edge isn't maintained in conformal sphere inversions, so that's one reason why it couldn't apply to inflated polyhedrons.
Logged
hobold
Fractal Bachius
*
Posts: 573


« Reply #4 on: August 26, 2010, 03:46:18 PM »

Dang, you are right. :-( Inversions aren't just reflections on spheres. And there seems to be no way to properly blend a true inversion into such a piecewise map. Still, it might be enlightening to continuously control the distortion of angles and get a feel for the amount and type of whipped cream that results from that particular flaw.
Logged
fractower
Iterator
*
Posts: 173


« Reply #5 on: September 21, 2011, 08:52:47 AM »

I finally had time to program the generalized box fold and produce some renders. I hope to get the the melted cube version that Hobold suggested soon.

Logged
DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #6 on: September 21, 2011, 09:04:53 AM »

Formulaaaaaaaa! grin
Logged

No sweat, guardian of wisdom!
fractower
Iterator
*
Posts: 173


« Reply #7 on: September 21, 2011, 03:17:25 PM »

It is more of an algorithm than a formula. If z is inside the polyhedron, do nothing. If z is outside the box, find the closest point on the surface of the box and do a point inversion.

If I can figure out how to post code on the thread, I will. I only touch fractal.cpp, so anyone who can build mandelbulber 1.08 can play with it.
Logged
cKleinhuis
Administrator
Fractal Senior
*******
Posts: 7044


formerly known as 'Trifox'


WWW
« Reply #8 on: September 21, 2011, 04:06:29 PM »

Code:
just use
the
code [ code ] tag
Logged

---

divide and conquer - iterate and rule - chaos is No random!
DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #9 on: September 21, 2011, 04:18:11 PM »

Do you mean it's not an escape-time formula? cry
Logged

No sweat, guardian of wisdom!
taurus
Fractal Supremo
*****
Posts: 1175



profile.php?id=1339106810 @taurus_arts_66
WWW
« Reply #10 on: September 21, 2011, 04:24:13 PM »

@ fractower

ever thought of cooperating with buddhi? afaik he is in search of people helping him coding new formulas in mandelbulber.
Logged

when life offers you a lemon, get yourself some salt and tequila!
fractower
Iterator
*
Posts: 173


« Reply #11 on: September 21, 2011, 06:22:55 PM »

Quote
Do you mean it's not an escape-time formula?

It is essentially Tglad's Mandelbox with the cubic box fold replaced with a generalized box fold.

Is there a way to add a source file to a thread?

Logged
Buddhi
Fractal Iambus
***
Posts: 895



WWW
« Reply #12 on: September 21, 2011, 06:24:21 PM »

@ fractower

ever thought of cooperating with buddhi? afaik he is in search of people helping him coding new formulas in mandelbulber.

Of course I'm interested to implement some new formulas
Logged

DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #13 on: September 21, 2011, 06:49:25 PM »

Quote
Do you mean it's not an escape-time formula?

It is essentially Tglad's Mandelbox with the cubic box fold replaced with a generalized box fold.

Is there a way to add a source file to a thread?



Yes, so paste directly the code please! wink
Logged

No sweat, guardian of wisdom!
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.

Code:
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
<
---
>
Logged
Pages: [1] 2   Go Down
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
Generalized Box folds. Mandelbulber Gallery fractower 0 795 Last post September 21, 2011, 08:47:33 AM
by fractower
Generalized Apollonius: random ellipsoid packings 3D Fractal Generation hobold 3 1554 Last post February 04, 2013, 07:28:29 PM
by knighty
3-fold symmetry Still Frame Kalles Fraktaler 0 744 Last post May 08, 2014, 05:02:44 PM
by Kalles Fraktaler
Generalized shape inversion applied to the Mandelbox Amazing Box, Amazing Surf and variations « 1 2 » CozyG 17 3010 Last post August 12, 2017, 02:45:07 PM
by Alef
Generalized Fold Box Mesh Images Showcase (Rate My Fractal) Buddhi 0 560 Last post November 09, 2017, 08:32:59 PM
by Buddhi

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM
Page created in 0.325 seconds with 25 queries. (Pretty URLs adds 0.015s, 2q)