1

I'm trying to code the Mandelbrot set as a fun project. I did it on my own, so it probably isn't optimized very well. I have a few questions about how to make my code better and how to add certain things to it. I used the library p5js, but that probably doesn't matter. (My code is at the bottom.)

First of all, when I render the set, the edges are very sharp. For example: See how the edges are sharp, because it operates pixel by pixel. However, I see in, for example, the Wikipedia page that it is possible to blend pixels and give more detail to the picture. How might I go about doing this? I've thought about calculating four values for each pixel, and blending them, but I feel like there should be another way.

Secondly, rendering the set takes much longer than it can if I want to animate it. I have to iterate more and more the more I zoom, so each frame would end up taking entire minutes to render. However, then I see videos like this https://www.youtube.com/watch?v=LhOSM6uCWxk or this https://www.youtube.com/watch?v=b005iHf8Z3g and I'd like to know how they are able to render these in less than a century. Is there an optimization method that I'm missing out on?

Another thing about the videos is how they are colored. For example, the first video I showed seemed like the colors were moving around everywhere, instead of staying in a constant spot, like the second video. What is the coloring method?

I've tried making the iterations low, but then I lose quality. I've tried an array of colors, but then it looks flat, like the second video. I want to know what's going on that I'm missing. I've looked at other solutions and seen that some people are rendering one pixel at a time, and that's what is making it slow. I do rows at a time for speed. All in all, what should I change to animate a set that looks pretty cool?

Finally, is there anything else that I should know to make my Mandelbrot set look amazing? Is there a completely different method for rendering that I should know? How is the first video made to look 3D? All of these clarifications would be nice to know.

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/addons/p5.sound.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <main>
    </main>
    <script src="sketch.js"></script>
  </body>
</html>
//noprotect
var y = 0;
var ratio;
var xstart = -2;
var xend = 2;
var ystart = -2;
var yend = 2;
var maxiter = 100;
var _xstart;
var _xend;
const colors = [
  "rgb(255, 0, 255)",
  "rgb(255, 0, 127)",
  "rgb(255, 0, 0)",
  "rgb(255, 127, 0)",
  "rgb(255, 255, 0)",
  "rgb(127, 255, 0)",
  "rgb(0, 255, 0)", 
  "rgb(0, 255, 127)", 
  "rgb(0, 255, 255)",
  "rgb(0, 127, 255)", 
  "rgb(0, 0, 255)", 
  "rgb(127, 0, 255)"
];

function setup() {
  noStroke();
  createCanvas(window.innerWidth, window.innerHeight);
  ratio = width/height;
  background(0);
  
_xstart = xstart * (width/height);
_xend = xend * (width/height);
_xstart = (xstart + xend)/2 + xstart*(width/height);
_xend = (xstart+xend)/2 + xend*(width/height);
}

function mandelbrot(rconst, iconst) {
  var iter = math.complex(0, 0);
  var current = 0;
  for(var i = 0; i < maxiter; i ++) {
    iter = iter.pow(2);
    iter = iter.add(rconst, iconst);
    current ++;
    if(sqrt(pow(iter.re, 2)+pow(iter.im, 2)) > 2) {
      break;
    }
  } 
  if(current === maxiter) {
    return(0);
  } else {
    //color array
    return(colors[(current) % colors.length]);

    //purple
    var temp = floor(map(current, 0, maxiter/3, 0, 255));
    if(temp > 255) {
      temp = 255;
    }
    // return('rgb(' + temp + ', 0, ' + temp + ')')

    //black and white
    // return(map(current, 0, 30, 0, 255))
    return('rgb(0, 0, ' + temp + ')')
  }
}

function draw() {
  if(y < height+1) {
    for(var x = 0; x < width+1; x ++) {
      fill(mandelbrot(map(x, 0, width, _xstart, _xend), map(y, 0, height, ystart, yend)))
      rect(x, y, 1, 1);
    }
    y++;
  }
  fill(0);
  rect(0, 0, 300, 15);
  fill(255);
  text("x: " + map(mouseX, 0, width, _xstart, _xend) + ", y: " + map(mouseY, 0, height, ystart, yend), 0, 10); 
}
Eli Bauer
  • 29
  • 5
  • The videos probably did take a long while to render, video vs live computation is not a fair comparison. – NickSlash Nov 20 '22 at 17:24
  • Yes, but the way I have it set up, it would take me years to get a zoom to even a quarter of some videos that are a decade old. – Eli Bauer Nov 20 '22 at 17:41

0 Answers0