Jump to my Home Page Send me a message Check out stuff on GitHub Check out my photography on Instagram Check out my profile on LinkedIn Check out my profile on reddit Check me out on Facebook

Mitch Richling: Mandelbrot Count

Author: Mitch Richling
Updated: 2024-10-31

Table of Contents

1. Introduction

Here we explore how increasing the iteration count "fills in" the space in a Mandelbrot Set render. In this particular case, we ramp the iteration count from \(157\) up to \(461\).

2. Algorithm & Code

#include "ramCanvas.hpp"

typedef mjr::ramCanvas3c8b::colorType ct;

int main(void) {
  std::chrono::time_point<std::chrono::system_clock> startTime = std::chrono::system_clock::now();
  const double MAXZSQ =  4.0;
  const int    IMGSIZ = 7680/4;

  const int    MXITRS = 157;
  const double BALSIZ =  0.00019065;
  const double CNTRX  = -0.745258237857;
  const double CNTRY  =  0.130272017858;
  const int    ITRSTP = 1;
  const int    NUMFRM = 304;
  const int    COLMAG = 1;

  // const double BALSIZ =  6.25e-7;
  // const double CNTRX  =  0.241810410968;
  // const double CNTRY  = -0.510269600591;
  // const int    MXITRS = 750;
  // const int    MXITRE = 2000;
  // const int    ITRSTP = 3;
  // const int    NUMFRM = (MXITRE-MXITRS)/ITRSTP+1;
  // const int    COLMAG = 10;

# pragma omp parallel for schedule(static,1)
  for(int frame=0; frame<NUMFRM; frame++) {
    int curMaxItr = MXITRS + frame * ITRSTP;
    mjr::ramCanvas3c8b theRamCanvas(IMGSIZ, IMGSIZ, CNTRX-BALSIZ, CNTRX+BALSIZ, CNTRY-BALSIZ, CNTRY+BALSIZ);
    std::chrono::time_point<std::chrono::system_clock> frameStartTime = std::chrono::system_clock::now();
    for(int y=0;y<theRamCanvas.getNumPixY();y++) {
      for(int x=0;x<theRamCanvas.getNumPixX();x++) {
        std::complex<double> c = theRamCanvas.int2real(x, y);
        std::complex<double> z(0.0, 0.0);
        int count = 0; 
        while((std::norm(z)<MAXZSQ) && (count<=curMaxItr)) {
          z=std::pow(z, 2) + c;
          count++;
        }
        if(count < curMaxItr)
          theRamCanvas.drawPoint(x, y, ct::csCColdeFireRamp::c(static_cast<ct::csFltType>(COLMAG*count)/curMaxItr));
      }
    }
    theRamCanvas.writeTIFFfile("mandelbrot_count_movie_" + mjr::math::str::fmt_int(frame, 3, '0') + ".tiff");
    std::chrono::duration<double> frameRunTime = std::chrono::system_clock::now() - frameStartTime;
#   pragma omp critical
    std::cout << "Frame " << frame << " of " << NUMFRM << " Runtime " << frameRunTime.count() << " sec" << std::endl;
  }
  std::chrono::duration<double> runTime = std::chrono::system_clock::now() - startTime;
  std::cout << "Total Runtime " << runTime.count() << " sec" << std::endl;
}

The above program will generate frames for a movie which may be rendered into a movie:

Here are some alternative versions of the above:

There is nothing special about the parameters used in the above program other than we pick an interesting part of the Mandelbrot set and a range of iteration counts that yield something interesting. The commented out parameters are for the center of another spiral, but one with very different qualitative behavior:

Here are some alternative versions of the above:

3. References

Check out the fractals section of my reading list.

All the code used to generate everything on this page may be found on github.