Mitch Richling: The Dancing Biomorph
Author: | Mitch Richling |
Updated: | 2024-10-31 |
Table of Contents
1. Introduction
Given some function,
Unlike the Mandelbrot Set, iteration stops for a biomorph when
Another difference between biomorphs and the Mandelbrot Set is the way they are normally colorized. Biomorphs are generally colored based on the escape function, but by a combination of escape function, magnitude/phase of z at iteration end, etc…
2. Algorithm & Code
#include "ramCanvas.hpp" typedef mjr::ramCanvas3c8b::colorType ct; typedef ct::csIntType cit; int main(void) { std::chrono::time_point<std::chrono::system_clock> startTime = std::chrono::system_clock::now(); const int NUMITR = 7; const int NUMFRM = 24*4; const int IMXSIZ = 7680/4; const int IMYSIZ = 7680/4; const int LIM = 10; mjr::ramCanvas3c8b theRamCanvas(IMXSIZ, IMYSIZ, -2.75, 2.75, -2.75, 2.75); for(int frame=0; frame<NUMFRM; frame++) { std::cout << "Frame: " << frame << std::endl; double angle = frame*std::numbers::pi*2/NUMFRM; theRamCanvas.clrCanvasToBlack(); for(int y=0;y<theRamCanvas.getNumPixY();y++) { for(int x=0;x<theRamCanvas.getNumPixX();x++) { std::complex<double> c(std::cos(angle), std::sin(angle)); std::complex<double> z = theRamCanvas.int2real(x, y); std::complex<double> zL(0.0, 0.0); int count = 0; while( ((std::abs(std::real(z))<LIM) || (std::abs(std::imag(z))<LIM)) && (count<NUMITR) ) { zL = z; z=std::sin(z) + std::pow(z, 2) + c; count++; } if(count < NUMITR) { if(std::abs(std::real(zL)) < LIM) theRamCanvas.drawPoint(x, y, ct::csCCu0W::c(std::abs(std::real(zL))/LIM)); else if(std::abs(std::imag(zL)) < LIM) theRamCanvas.drawPoint(x, y, ct::csCCu0W::c(1.0-std::abs(std::imag(zL))/LIM)); } else { if(std::abs(std::real(zL)) < LIM) theRamCanvas.drawPoint(x, y, ct::csCCu0Y::c(std::abs(std::real(zL))/LIM)); else if(std::abs(std::imag(zL)) < LIM) theRamCanvas.drawPoint(x, y, ct::csCCu0Y::c(1.0-std::abs(std::imag(zL))/LIM)); } } } theRamCanvas.writeTIFFfile("biomorphMorph_" + mjr::math::str::fmt_int(frame, 3, '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 96 frames of a movie which we can assemble into a GIF: