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:
- Full sized webm movie This is the one to watch!
- Half sized webm movie
- Full sized gif
- Half sized gif
- Quarter sized gif
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:
- Full sized webm movie This is the one to watch!
- Half sized webm movie
- Full sized gif
- Half sized gif
- Quarter sized gif