Mitch Richling: Multibrot Fractal
Author: | Mitch Richling |
Updated: | 2024-10-31 |
Table of Contents
1. Introduction
The Multibrot Fractal is a family of Mandelbrot'alikes in that the generating functions are a minor modification of the one used for the Mandelbrot Set:
Notice the only difference is the power,
We render Multibrot Fractals using the
2. When is not an integer
When
#include "ramCanvas.hpp" int main(void) { std::chrono::time_point<std::chrono::system_clock> startTime = std::chrono::system_clock::now(); const double MINPOW = 0.9; const double MAXPOW = 4.0; const int NUMFRM = 192; const int NUMITR = 255; const int IMXSIZ = 7680/8; const int IMYSIZ = 4320/8; mjr::ramCanvas3c8b theRamCanvas(IMXSIZ, IMYSIZ, -2.75, 2.75, -1.55, 1.55); for(int f=0;f<NUMFRM;f++) { double p = MAXPOW*static_cast<double>(f)/static_cast<double>(NUMFRM) + MINPOW; std::chrono::time_point<std::chrono::system_clock> frameStartTime = std::chrono::system_clock::now(); theRamCanvas.clrCanvasToBlack(); for(int y=0;y<theRamCanvas.getNumPixY();y++) { for(int x=0;x<theRamCanvas.getNumPixX();x++) { std::complex<double> c(theRamCanvas.int2realX(x), theRamCanvas.int2realY(y)); std::complex<double> z(0.0, 0.0); int count = 0; while((std::norm(z)<4) && (count<=NUMITR)) { z=std::pow(z, p) + c; count++; } if(count < NUMITR) theRamCanvas.drawPoint(x, y, mjr::ramCanvas3c8b::colorType::csCColdeFireRamp::c(static_cast<mjr::ramCanvas3c8b::csIntType>(count*20))); } } theRamCanvas.writeTIFFfile("multibrotMovie_" + mjr::math::str::fmt_int(f, 3, '0') + ".tiff"); std::chrono::duration<double> frameRunTime = std::chrono::system_clock::now() - frameStartTime; std::cout << "Frame " << f << " 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 192 frames of a movie which we can assemble into a GIF:
3. When is an integer
When
#include "ramCanvas.hpp" int main(void) { std::chrono::time_point<std::chrono::system_clock> startTime = std::chrono::system_clock::now(); const int MINPOW = 2; const int MAXPOW = 9; const int NUMITR = 1024; const int IMXSIZ = 7680/2; const int IMYSIZ = 4320/2; mjr::ramCanvas3c8b theRamCanvas(IMXSIZ, IMYSIZ, -2.75, 2.75, -1.55, 1.55); for(int p=MINPOW;p<=MAXPOW;p++) { std::chrono::time_point<std::chrono::system_clock> frameStartTime = std::chrono::system_clock::now(); theRamCanvas.clrCanvasToBlack(); for(int y=0;y<theRamCanvas.getNumPixY();y++) { for(int x=0;x<theRamCanvas.getNumPixX();x++) { std::complex<double> c(theRamCanvas.int2realX(x), theRamCanvas.int2realY(y)); std::complex<double> z(0.0, 0.0); int count = 0; while((std::norm(z)<4) && (count<=NUMITR)) { z=std::pow(z, p) + c; count++; } if(count < NUMITR) theRamCanvas.drawPoint(x, y, mjr::ramCanvas3c8b::colorType::csCColdeFireRamp::c(static_cast<mjr::ramCanvas3c8b::csIntType>(count*20*log(p)))); } } //theRamCanvas.autoHistStrech(); theRamCanvas.writeTIFFfile("multibrotSnaps_" + mjr::math::str::fmt_int(p, 3, '0') + ".tiff"); std::chrono::duration<double> frameRunTime = std::chrono::system_clock::now() - frameStartTime; std::cout << "Frame " << p << " 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; }