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 the official fractalforums.com Youtube Channel
 
*
Welcome, Guest. Please login or register. April 27, 2024, 01:59:22 PM


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]   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: Mandelbox 2D questions and code attempt  (Read 5537 times)
0 Members and 1 Guest are viewing this topic.
asimes
Fractal Lover
**
Posts: 212



asimes
WWW
« on: April 24, 2012, 08:20:07 AM »

I'm trying to make a Mandelbox for the first time. I was using this as reference: http://www.fractalforums.com/3d-fractal-generation/amazing-fractal/45/

Here is my code so far. If anyone has Processing installed you can see it:
Code:
float bScale = 2;
float minRad = 0.5;
float fixedRad = 1.0;
float xmin = -2.0;
float ymin = -2.0;
float wh = 4;
int maxIterations = 100;

void setup() {
  size(800, 800, P2D);
}

void draw() {
  loadPixels();
  float xmax = xmin+wh;
  float ymax = ymin+wh;
  float dx = (xmax-xmin)/width;
  float dy = (ymax-ymin)/height;
  float x = xmin;
  float highestVal = 0;
  float[] pixVals = new float[width*height];
  for (int i = 0; i < width; i++) {
    float y = ymin;
    for (int j = 0;  j < height; j++) {
      float nx = x;
      float ny = y;
      float nMag = 0;
      int n = 0;
      while (n < maxIterations) {
        if (nx > 1) nx = bScale-nx;
        else if (nx < -1) nx = -bScale-nx;
        if (ny > 1) ny = bScale-ny;
        else if (ny < -1) ny = -bScale-ny;
        nMag = sqrt(nx*nx+ny*ny);
        if (nMag < minRad) {
          float t = (fixedRad*fixedRad)/(minRad*minRad);
          nx *= t;
          ny *= t;
        }
        else if (nMag < 1) {
          float t = (fixedRad*fixedRad)/(nMag*nMag);
          nx *= t;
          ny *= t;
        }
        if (nx*nx+ny*ny > 2) break;
        n++;
      }
      if (nMag > highestVal) highestVal = nMag;
      if (n == maxIterations) pixVals[i+j*width] = 0;
      else pixVals[i+j*width] = nMag;
      y += dy;
    }
    x += dx;
  }
  for (int i = 0; i < width*height; i++) {
    int val = (int)(pixVals[i]/highestVal*255);
    pixels[i] = (val<<16)+(val<<8)+val;
  }
  updatePixels();
  println("Time: "+millis());
  noLoop();
}

If not, here is a sample image for scale = 2.0, minRad = 0.5, and fixedRad = 1.0:


What I am wondering:
- Is this a normal output for a Mandelbox in 2D?
- My bailout doesn't work when I set it to 4 (black screen), is this bad? I am used to this for Mandelbrot.
- Does Mandelbox require internal coloring or can typical Mandelbrot coloring techniques be used? How do people normally color a Mandelbox for that matter, right now I'm just using the magnitude after a bail.
- For anyone patient enough to look at my code, am I doing this correctly? I have seen examples like this before (linked below), not sure if they are the same or not, they don't make as much sense as what I was referring to in the link I put above: http://www.geeks3d.com/20100427/do-you-know-the-mandelbox-fractal/
Logged
asimes
Fractal Lover
**
Posts: 212



asimes
WWW
« Reply #1 on: April 24, 2012, 08:38:59 PM »

Ok, significant improvement. I discovered that I don't need to test if a point hit the maximum number of iterations... also I discovered that log coloring looks a million times nicer. Still some questions, I will ask below.

New version of bailout for if (x*x+y*y > 2):


Correctly working bailout for if (x*x+y*y > 4):


New code (if anyone is interested and has Processing):
Code:
float bScale = 2.0;
float minRad = 0.5;
float fixedRad = 1.0;
float xmin = -2.0;
float ymin = -2.0;
float wh = 4;
int maxIterations = 100;

void setup() {
  size(800, 800, P2D);
}

void draw() {
  loadPixels();
  float xmax = xmin+wh;
  float ymax = ymin+wh;
  float dx = (xmax-xmin)/width;
  float dy = (ymax-ymin)/height;
  float x = xmin;
  float highestVal = 0;
  float[] pixVals = new float[width*height];
  for (int i = 0; i < width; i++) {
    float y = ymin;
    for (int j = 0;  j < height; j++) {
      float nx = x;
      float ny = y;
      float nMag = 0;
      int n = 0;
      while (n < maxIterations) {
        if (nx > 1) nx = bScale-nx;
        else if (nx < -1) nx = -bScale-nx;
        if (ny > 1) ny = bScale-ny;
        else if (ny < -1) ny = -bScale-ny;
        nMag = sqrt(nx*nx+ny*ny);
        if (nMag < minRad) {
          float t = (fixedRad*fixedRad)/(minRad*minRad);
          nx *= t;
          ny *= t;
        }
        else if (nMag < 1) {
          float t = (fixedRad*fixedRad)/(nMag*nMag);
          nx *= t;
          ny *= t;
        }
        if (nx*nx+ny*ny > 4) break;
        nMag = nx*nx+ny*ny;
        n++;
      }
      if (nMag > highestVal) highestVal = nMag;
      pixVals[i+j*width] = nMag;
      y += dy;
    }
    x += dx;
  }
  for (int i = 0; i < width*height; i++) {
    int val = (int)(log(pixVals[i])/log(highestVal)*255);
    pixels[i] = (val<<16)+(val<<8)+val;
  }
  updatePixels();
  println("Time: "+millis());
  noLoop();
}

Questions:
- What are normal coloring techniques for a 2D Mandelbox? The images above are using the magnitude after a bailout.
- Is it useful to think of a Mandelbox as having an inside / outside?
- Does normal Mandelbox code assume that the range of points used per axis goes from -2 to 2 (or less)?
- Still wondering if this is normal output for a 2D Mandelbox
« Last Edit: April 24, 2012, 08:46:16 PM by asimes » Logged
cKleinhuis
Administrator
Fractal Senior
*******
Posts: 7044


formerly known as 'Trifox'


WWW
« Reply #2 on: April 24, 2012, 09:39:39 PM »

ok, for the bailout test: mandelbox is having a range of -4 to 4 i think, and bailout would then be 16 ....
cant say if it really is 2d output, i think you have area -2 to 2 rendered ? zoom out! and show us then ... as i said, mandelbox goes from -4 to 4...
- coloring techniques are basically the same as for mandelbrot .. but since it is a folding operation that leads to hard-cuts they could behave oddly ...
- rendering techniques: the mandelbox is just the black area, the same as with the mandelbrot ... you are painting/coloring the outside area, this is not used
very much in 3d rendering because it is heavy volume rendering stuff, when rendering 3d you are just interested in retrieving a color for the exact cut point ...
- give any distance estimation method a chance and enjoy what the offer for results ... wink search for "distance estimation coloring"
- and please render image a litte zoomed out .... so we can check visually if your code is correct wink if you wanna us re-check something always include exact parameter lists and exact locations ...
- do not forget that iteration count has severe influence on the image, using higher iteration counts yields chaotic results, e.g. just pixel crap .... when zoomed out....
- it is always the black area of interest cheesy
Logged

---

divide and conquer - iterate and rule - chaos is No random!
visual.bermarte
Fractal Fertilizer
*****
Posts: 355



« Reply #3 on: April 25, 2012, 11:15:51 PM »

Nice images ! this is one crazy test..a sort of mandelbox-painter  grin
actually mouseX and mouseY are not that useful  embarrass would be better using smaller numbers (and not int!)
Code:
float xmin = -2.5; 
float ymin = -2.5;
float wh = 5;
void setup() {
  size(800, 800, P2D);
  loop();
  background(0);
  // Make sure we can write to the pixels[] array.
  // Only need to do this once since we don't do any other drawing.
  loadPixels();
}
void draw() {
  // Maximum number of iterations for each point on the complex plane
  int maxiterations = 9;
  // x goes from xmin to xmax
  float xmax = xmin + wh;
  // y goes from ymin to ymax
  float ymax = ymin + wh;  
  // Calculate amount we increment x,y for each pixel
  float dx = (xmax - xmin) / (width);
  float dy = (ymax - ymin) / (height);
  // Start y
  float y = ymin;
  for (int j = 0; j < height; j++) {
    // Start x
    float x = xmin;
    for (int i = 0;  i < width; i++) {
      float a = x;
      float b = y;
      int n = 0;
      float xx,yy,r2,mr,scaleb;
      //float zz,DEfactor;
      float fr, fr2, mr2;
      scaleb=-2.7;
      mr2=mouseX;
      fr2=mr2*2.;
      xx=a;yy=b;
      while (n < maxiterations) {
        if (a > mouseX)a = mouseY - a;
        else if (a < -mouseX)a = -mouseY - a;
        if (b > mouseX) b = mouseY - b;
        else if (b < -mouseX) b = -mouseY - b;
        r2=a*a+b*b;
      if(r2<mr2){
        a=a*fr2/mr2;
        b=b*fr2/mr2;
        //z=z*fr2/mr2;
        //DEfactor=DEfactor*fr2/mr2;
      } else if(r2<fr2){
        a=a*fr2/r2;
        b=b*fr2/r2;
        //z=z*fr2/r2;
       // DEfactor=DEfactor*fr2/r2;
      }
      a=a*scaleb+xx;
      b=b*scaleb+yy;
      //z=z*scaleb+zz;
      //DEfactor=DEfactor*abs(scaleb)+1;
      // r2=x*x+y*y+z*z;
      //repeat r2 babe!
      //r2=a*a+b*b;
      //}
      //return sqrt(r2)/DEfactor;
        if(r2 > 5555) {//// Bail me!
          break;
        }
        n++;
      }
      if (n == maxiterations) {
        colorMode(HSB, width, height, 32);
        float  ca = color(165, 167, 20);
        float  cb = color(77, 86, 59);
        //float  cc = color(42, 106, 105);
        //float  cd = color(165, 89, 20);
        //float  ce = color(146, 150, 127);
        pixels[i+j*width] = (int)lerp((int)ca,(int)cb,mouseY);
      } else {
         //mothing here
        //colorMode(HSB);
      }
      x += dx;
    }
    y += dy;
  }
  updatePixels();
}
in 3d would be something like that?
Code:
float minThreshold = 0.0001,maxDepth=8.0;//8.0 is about right for most fractals

void setup() {
  size(800, 600, P2D);
  noLoop();
}
float DE(float x, float y, float z){//this is our old friend menger
   int n,iters=12;
   float xx,yy,zz,DEfactor,r2,mr,scaleb;
   float fr, fr2, mr2;
   scaleb=3.2;
   mr2=0.5;
   fr2=1.2;
   xx=0.;yy=0.;zz=0.;
   r2=x*x+y*y+z*z;
   DEfactor=1.;

for(n=0;n<iters;n++){
      if(x>1) x=2-x;
      else if(x<-1) x=-2-x;
      if(y>1) y=2-y;
      else if(y<-1) y=-2-y;
      if(z>1) z=2-z;
      else if(z<-1) z=-2-z;
     
      r2=x*x+y*y+z*z;
      if(r2<mr2){
        x=x*fr2/mr2;
        y=y*fr2/mr2;
        z=z*fr2/mr2;
        DEfactor=DEfactor*fr2/mr2;
      } else if(r2<fr2){
        x=x*fr2/r2;
        y=y*fr2/r2;
        z=z*fr2/r2;
        DEfactor=DEfactor*fr2/r2;
      }
      x=x*scaleb+xx;
      y=y*scaleb+yy;
      z=z*scaleb+zz;
      DEfactor=DEfactor*abs(scaleb)+1;
      r2=x*x+y*y+z*z;
  }
  return sqrt(r2)/DEfactor;

}
void draw() {
  loadPixels();
  for (int i = 0; i < width; i++) {
    for (int j = 0; j < height; j++) {
      float dx=(float)i/(float)width-0.5;
      float dy=((float)j/(float)height-0.5)*(float)height/(float)width;
      float dz=1.0,r=1.0/sqrt(dx*dx+dy*dy+1.0);dx*=r;dy*=r;dz*=r;
      float x=0,y=0,z=0,rayLen=0,dist=maxDepth;
      int steps = 255;
      while (steps-- > 0 && dist>=minThreshold && rayLen < maxDepth) {
        rayLen += dist = DE(x,y,z-4.0)*0.5;
        x=dx*rayLen;y=dy*rayLen;z=dz*rayLen;
      }
      if(dist<minThreshold){//eventually you will want to do more here
        //... like find the surface normal and calculate lighting
        pixels[i+j*width] = (steps<<16)+(steps<<8)+steps;
      }
    }
  }
  updatePixels();
}
PS: thanx 2 Knighty
« Last Edit: April 25, 2012, 11:34:46 PM by visual.bermarte, Reason: adding 3d » Logged
asimes
Fractal Lover
**
Posts: 212



asimes
WWW
« Reply #4 on: April 26, 2012, 04:09:46 AM »

cKleinhuis, thanks for the tips. If I understood correctly, I'm only interested in points that never hit the bailout? Also, I'm having a very difficult time finding a distance estimation tutorial that doesn't assume I rock at math, do you know a nice one?

visual.bermarte, I made some changes to the first code you posted, it is pretty fun! It works in Processing now, I'll post it below. The biggest change was multiplying mouseX by dx and the same for mouseY but with dy (I took off the colors, a bit too psychedelic for me, ha ha). I'll have to go through your Mandelbox code a few more times to make sure I make sense of why it works now though:

Code:
float xmin = -4; 
float ymin = -4;
float wh = 8;
int maxiterations = 10;

void setup() {
  size(800, 800, P2D);
}

void draw() {
  loadPixels();
  background(0);
  float xmax = xmin + wh;
  float ymax = ymin + wh;  
  float dx = (xmax - xmin) / (width);
  float dy = (ymax - ymin) / (height);
  float y = ymin;
  for (int j = 0; j < height; j++) {
    float x = xmin;
    for (int i = 0;  i < width; i++) {
      float a = x;
      float b = y;
      int n = 0;
      float xx, yy, r2, mr, scaleb;
      float fr, fr2, mr2;
      scaleb = -2.7;
      mr2 = mouseX*dx;
      fr2 = mr2*2;
      xx = a;
      yy = b;
      while (n < maxiterations) {
        if (a > mouseX*dx) a = mouseX*dx - a;
        else if (a < -mouseX*dx) a = -mouseX*dx - a;
        if (b > mouseY*dx) b = mouseY*dx - b;
        else if (b < -mouseY*dx) b = -mouseY*dx - b;
        r2 = a*a+b*b;
        if (r2 < mr2) {
          a = a*fr2/mr2;
          b = b*fr2/mr2;
        }
        else if (r2 < fr2) {
          a = a*fr2/r2;
          b = b*fr2/r2;
        }
        a = a*scaleb+xx;
        b = b*scaleb+yy;
        if (r2 > 5555) break;
        n++;
      }
      if (n == maxiterations) pixels[i+j*width] = 0xffffff;
      x += dx;
    }
    y += dy;
  }
  updatePixels();
}

I didn't realize you could make an interactive Mandelbox. I am familiar with the second code you posted but for a Menger Sponge instead (same Raymarching code). I'm gonna leave off playing with 3D for a while until 2D makes a lot more sense.
« Last Edit: April 26, 2012, 09:45:58 PM by asimes » Logged
asimes
Fractal Lover
**
Posts: 212



asimes
WWW
« Reply #5 on: April 26, 2012, 09:05:50 AM »

I think I got it. I just threw in:
Code:
nx = nx*bScale+x;
ny = ny*bScale+y;

before my bailout and I got completely different images. Here is a sample (areas that bailed are red):


My screen goes from -4 to 4 on both axes, the bailout is 16, and it looks more like what I was expecting for a Mandelbox. Is it a Mandelbox yet? Here's code again:
Code:
float bScale = 2.0;
float minRad = 0.5;
float fixedRad = 1.0;
float xmin = -4.0;
float ymin = -4.0;
float wh = 8;
int maxIterations = 3;

void setup() {
  size(800, 800, P2D);
}

void draw() {
  loadPixels();
  float xmax = xmin+wh;
  float ymax = ymin+wh;
  float dx = (xmax-xmin)/width;
  float dy = (ymax-ymin)/height;
  float x = xmin;
  float highestVal = 0;
  float[] pixVals = new float[width*height];
  for (int i = 0; i < width; i++) {
    float y = ymin;
    for (int j = 0;  j < height; j++) {
      float nx = x;
      float ny = y;
      float nMag = 0;
      int n = 0;
      while (n < maxIterations) {
        if (nx > 1) nx = bScale-nx;
        else if (nx < -1) nx = -bScale-nx;
        if (ny > 1) ny = bScale-ny;
        else if (ny < -1) ny = -bScale-ny;
        nMag = sqrt(nx*nx+ny*ny);
        if (nMag < minRad) {
          float t = (fixedRad*fixedRad)/(minRad*minRad);
          nx *= t;
          ny *= t;
        }
        else if (nMag < fixedRad) {
          float t = (fixedRad*fixedRad)/(nMag*nMag);
          nx *= t;
          ny *= t;
        }
        nx = nx*bScale+x;
        ny = ny*bScale+y;
        if (nx*nx+ny*ny > 16) break;
        nMag = nx*nx+ny*ny;
        n++;
      }
      if (nMag > highestVal) highestVal = nMag;
      if (n == maxIterations) pixVals[i+j*width] = nMag;
      else pixVals[i+j*width] = -1;
      y += dy;
    }
    x += dx;
  }
  for (int i = 0; i < width*height; i++) {
    if (pixVals[i] == -1) pixels[i] = 0xff0000;
    else {
      int val = (int)(log(pixVals[i])/log(highestVal)*255);
      pixels[i] = (val<<16)+(val<<8)+val;
    }
  }
  updatePixels();
  println("Time: "+millis());
  noLoop();
}

Next step is still figuring out distance estimation coloring. Oy
Logged
DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #6 on: April 26, 2012, 01:02:53 PM »

I see some discontinuities on your images - that's impossible because mandelbox never breaks continuity. Or maybe it's a visual effect?

Anyway it looks significantly different from what you did. alien
Logged

No sweat, guardian of wisdom!
visual.bermarte
Fractal Fertilizer
*****
Posts: 355



« Reply #7 on: April 26, 2012, 09:18:39 PM »

Quote
maybe it's a visual effect?
no, no it's not my fault!  cheesy

it's ok, just increase a bit maxIteration and bailout value and try removing sqrt as well inside nMag (but 4 me the 2 of them  work fine; with or without sqrt).
To be able to obtain negative scales   you should remove bScale here, so just:
Code:
if (nx > 1) nx = 2-nx;
else if (nx < -1) nx = -2-nx;
if (ny > 1) ny = 2-ny;
 else if (ny < -1) ny = -2-ny;
« Last Edit: April 26, 2012, 09:52:17 PM by visual.bermarte » Logged
asimes
Fractal Lover
**
Posts: 212



asimes
WWW
« Reply #8 on: April 26, 2012, 09:45:13 PM »

I actually don't really know what you guys mean when you say a fractal is continuous, I've seen that term on this board a lot. If it's not continuous it probably isn't a visual effect, I just don't know wtf I'm doing attempting to make this fractal, ha ha.

On that note, could someone post a picture of what a 2D Mandelbox is "supposed" to look like with scale = 2.0, min radius = 0.5, and fixed radius = 1.0 please? It would make my life a lot easier if I knew what exactly it was that I was aiming for instead of asking / posting every time it feels close.

I tried out the method that uses the boxFold() and ballFold() functions:
http://www.geeks3d.com/20100427/do-you-know-the-mandelbox-fractal/
v = s * ballFold(r, f*boxFold(v)) + c

It gave me a result that looks like this:


If anyone wants to see what I tried to do coding wise interpreting the link, here it is:
Code:
float bScale = 2.0;
float minRad = 0.5;
float fixedRad = 1.0;
float xmin = -4.0;
float ymin = -4.0;
float wh = 8;
int maxIterations = 3;

void setup() {
  size(800, 800, P2D);
}

void draw() {
  loadPixels();
  float xmax = xmin+wh;
  float ymax = ymin+wh;
  float dx = (xmax-xmin)/width;
  float dy = (ymax-ymin)/height;
  float x = xmin;
  float highestVal = 0;
  float[] pixVals = new float[width*height];
  for (int i = 0; i < width; i++) {
    float y = ymin;
    for (int j = 0;  j < height; j++) {
      float nx = x;
      float ny = y;
      float nMag = 0;
      int n = 0;
      while (n < maxIterations) {
        nx = fixedRad*boxFold(nx);
        ny = fixedRad*boxFold(ny);
        nMag = sqrt(nx*nx+ny*ny);
        float transform = bScale*ballFold(nMag);
        nx = nx*transform+x;
        ny = ny*transform+y;
        nMag = nx*nx+ny*ny;
        if (nMag > 16) break;
        n++;
      }
      if (nMag > highestVal) highestVal = nMag;
      if (n == maxIterations) pixVals[i+j*width] = nMag;
      else pixVals[i+j*width] = -1;
      y += dy;
    }
    x += dx;
  }
  for (int i = 0; i < width*height; i++) {
    if (pixVals[i] == -1) pixels[i] = 0xff0000;
    else {
      int val = (int)(log(pixVals[i])/log(highestVal)*255);
      pixels[i] = (val<<16)+(val<<8)+val;
    }
  }
  updatePixels();
  println("Time: "+millis());
  noLoop();
}

float boxFold(float v) {
  if (v > 1) v = bScale-v;
  else if (v < -1) v = -bScale-v;
  return v;
}

float ballFold(float m) {
  if (m < minRad) m = m/(minRad*minRad);
  else if (m < fixedRad) m = fixedRad/(m*m);
  return m;
}
Logged
visual.bermarte
Fractal Fertilizer
*****
Posts: 355



« Reply #9 on: April 26, 2012, 10:24:33 PM »


sqrt and no sqrt ver. side by side

There's also this one (with code) > http://www.antispork.com/
« Last Edit: April 26, 2012, 10:31:38 PM by visual.bermarte » Logged
asimes
Fractal Lover
**
Posts: 212



asimes
WWW
« Reply #10 on: April 27, 2012, 06:09:48 AM »

I think I have it for real! It seems like I just had to flip:
Code:
nMag = nx*nx+ny*ny;
if (nMag > 16) break;

to be:
Code:
if (nMag > 16) break;
nMag = nx*nx+ny*ny;



Thanks visual.bermarte! I will look into the code you put too, that one looks really nice

On a side note, doing:
Code:
if (sqrt(nMag) > 16) break;
nMag = nx*nx+ny*ny;

Gives me this:



Happy, happy, happy, happy smiley
Logged
DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #11 on: April 27, 2012, 09:28:49 AM »

Latest images look a lot better wink
Logged

No sweat, guardian of wisdom!
Pages: [1]   Go Down
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
Some Mandelbulber Questions Mandelbulber mephisto69 3 5424 Last post October 19, 2010, 02:59:05 PM
by jwm-art
Some questions Theory Cobbles 8 4142 Last post June 22, 2011, 05:51:07 PM
by Cobbles
Helpful vid I made and questions. Mandelbulb 3d wolfwing1 1 602 Last post July 21, 2011, 10:29:26 AM
by Xenodimensional
Some Buddhabrot questions / techniques Programming asimes 12 12205 Last post March 13, 2012, 05:00:36 PM
by ker2x
simple code for mandelbox Programming Owl 10 8628 Last post July 28, 2016, 12:57:34 PM
by faxingberlin

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.223 seconds with 27 queries. (Pretty URLs adds 0.008s, 2q)