Mitch Richling: Orbit Traps
Author: | Mitch Richling |
Updated: | 2024-10-31 |
Table of Contents
1. Introduction
The classic way to render a Mandelbrot Set is to use the
2. Pickover Stalks
#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 int IMGSIZ = 7680; const int MAXITR = 1024; const double MAXZSQ = 1008.0; mjr::ramCanvas3c8b theRamCanvas(IMGSIZ, IMGSIZ, -2.2, 0.8, -1.5, 1.5); # pragma omp parallel for schedule(static,1) 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); double minX = theRamCanvas.getCanvasWidD(); double minY = theRamCanvas.getCanvasWidD(); int count = 0; while((std::norm(z)<MAXZSQ) && (count<=MAXITR)) { z=std::pow(z, 2) + c; if (std::abs(std::real(z)) < minX) minX = std::abs(std::real(z)); if (std::abs(std::imag(z)) < minY) minY = std::abs(std::imag(z)); count++; } if(count < MAXITR) theRamCanvas.drawPoint(x, y, ct::csCCfractalYB::c(static_cast<ct::csIntType>(std::log(1+std::min(minX, minY))*500))); } } theRamCanvas.writeTIFFfile("mandelbrot_pickover.tiff"); 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 this image:
3. Mandelbrot Lemniscates
The Mandelbrot Set is ringed by the "Mandelbrot Curves" or "Mandelbrot Lemniscates" – an infinite family of continuous, closed curves that converge to the Mandelbrot Set. We can use these curves as orbit traps:
#include "ramCanvas.hpp" typedef mjr::ramCanvas3c8b::colorType ct; double lp(std::complex<double> z, int n) { std::complex<double> lpv(0.0, 0.0); for(int i=0; i<n; i++) lpv = std::pow(lpv, 2) + z; return std::abs(lpv) - 2; } int main(void) { std::chrono::time_point<std::chrono::system_clock> startTime = std::chrono::system_clock::now(); const int IMGSIZ = 7680; const int MAXITR = 1024; const double MAXZSQ = 4.0; const int NUMFRM = 10; # pragma omp parallel for schedule(static,1) for(int frame=1;frame<=NUMFRM;frame++) { # pragma omp critical std::cout << "Frame " << frame << " of " << NUMFRM << std::endl; mjr::ramCanvas3c8b theRamCanvas(IMGSIZ, IMGSIZ, -2.2, 0.8, -1.5, 1.5); 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); double minDval = theRamCanvas.getCanvasWidD(); double minDsgn = 0; int count = 0; while((std::norm(z)<MAXZSQ) && (count<=MAXITR)) { z=std::pow(z, 2) + c; double ld = lp(z, frame); if (std::abs(ld) < minDval) { minDval = std::abs(ld); minDsgn = (ld > 0 ? 1 : -1); } count++; } if(count < MAXITR) { ct::csIntType csIdx = static_cast<ct::csIntType>(std::log(1+minDval)*100); if (minDsgn > 0) theRamCanvas.drawPoint(x, y, ct::csCCfractalYB::c(csIdx)); else theRamCanvas.drawPoint(x, y, ct::csCCfractalYR::c(csIdx)); } } } theRamCanvas.writeTIFFfile("mandelbrot_ltrap_" + mjr::math::str::fmt_int(frame, 2, '0') + ".tiff"); } 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 all of the images in the gallery below.
These may be transformed into a movie: