Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

Fractals/kallesfraktaler

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

Kalles Fractaler wikipedia :Kalles_Fraktaler Kalles Fraktaler 2 + homepage manual Images See commons category: Created with Kalles Fraktaler install Latest binary downloads for Windows (64bit recommended, includes 32bit too) which also work in Wine on Linux (you need 7-zip to unpack recent releases) kalles-fraktaler-2 source code git repo - fork of http://www.chillheimer.de/kallesfraktaler/ run Launch wine ./kf.x86_64.exe Set the image size the same as window size ( in View) Simply save your settings KFS (required if you want something other than 640x360), location KFR (required if you want anything other than unzoomed M-set), palette KFP (optional, overrides the stuff from the KFR) and invoke KF like: /path/to/kf.exe -s my.kfs -l my.kfr -c my.kfp -x my.exr and then you can load the EXR in your program via OpenEXR (C++) or other library. For (re-)colouring existing EXR files containing raw iteration data, try: /path/to/kf.exe -s old.exr -l old.exr -o old.exr -c new-palette.kfp -x new.exr See KF's manual (near the end) for EXR channel documentation, for third-party software that handles EXR from KF look at zoomasm. Saving as other formats is supported also: check kf.exe --help for details. complex Steps to make video mkdir ~/work cd ~/work wine32 ~/windows/fraktal_sft.exe # render zoom out sequence with kalles fraktaler, saving to ~/work for i in *.kfb ; do ~/code/maximus_kf-extras/pseudo-de < ${i} | pgmtoppm white > ${i%kfb}ppm done # count number of kfb files, (ls *.kfb | tail -n 1) gives a hint, I had 311 ls *.kfb | ~/code/maximus_kf-extras/expmap 311 > expmap.pgm ghc -e "100 / sqrt ( 565 * 19820 / (120 * 8000) )" # or your favourite calculator program if you don't have ghc # prints 29.27922435677391 # where 565 * 19820 is the size of the expmap # 8000 is desired sample rate # 120 is desired movie length in seconds gimp expmap.pgm # downscale by 29.27922435677391% (output from ghci) # flip vertically # make sure it's greyscale with no alpha # save as expmap-downscaled.png # gimp saves comments in its netpbm writers, my bad code doesn't handle it pngtopnm < expmap-downscaled.png > expmap-downscaled.pgm audacity # import raw expmap-downscaled.pgm as raw unsigned 8bit PCM mono 8000Hz # set project sample rate to 48000Hz # select the track, mix and render # select the track, apply filter DC Offset Removal (maybe needs a plugin) # select the track, select amplify and apply to normalize the volume # duplicate the track twice # for each of the duplicates in turn, select it and apply a reverb (GVerb plugin) # use slightly different reverb settings for each track (for stereo effect) # normalize the duplicates by select track, select amplify, apply # make one duplicate a left channel and the other a right channel # set the levels of each track to -3dB # select all tracks, mix and render # normalize volume if needed # select track, export as stereo wav 16bit PCM to expmap.wav # note down the length (my test gave 1m56s) ghc -e "1 * 60 + 56" # to get the audio length in seconds (116) # check the size of the kfb files (here I used 640 by 360) # remember we have 311 kfb files ls 00*.ppm | tac | xargs cat | ~/code/maximus_book/code/zoom 640 360 311 116 | avconv -f yuv4mpegpipe -i - -i expmap.wav -acodec vorbis -ab 192k -vb 2M out.ogv # finally! mplayer out.ogv image in Kalle's Fraktaler only updates the image every half second size of image Discounting the size of the image (pixels plus raw iteration data):fractalforums.org : how-much-memory-is-needed-to-render-an-image-with-andgt-1-billion-iterations For KF 2.15.2.2 If using double: 24 bytes per iteration (to zoom depth e300, or e600 for scaled double for Mandelbrot power 2 only) If using long double: 40 bytes per iteration on 64bit, 32 bytes per iteration on 32bit (to zoom depth e4900, or e9800 for scaled long double for Mandelbrot power 2 only) If using floatexp: 40 bytes per iteration ("unlimited" zoom) For KF 2.15.3 (work in progress, mostly working, not released): If using double: 24 bytes per iteration (to zoom e300) If using scaled double: 24 bytes per iteration plus 48 bytes per iteration that is close to 0 ("unlimited" zoom) If using long double: 48 bytes per iteration on 64bit; maybe 36 bytes per iteration on 32bit (to zoom e4900) If using floatexp: 48 bytes per iteration ("unlimited" zoom) For KF 2.15.3 (potentially, need to test if it actually works after implementing it, work in progress, not released let alone finished): If using single precision float: 12 bytes per iteration (up to zoom depth 1e38) If using single precision scaled float: 12 bytes per iteration plus 24 bytes per iteration that is close to 0 ("unlimited" zoom) if using single precision floatexp: 24 bytes per iteration ("unlimited" zoom) KF does not implement the memory optimization to store reference only after series approximation, it stores the whole orbit. It does however upload only the part after series approximation to the device if using OpenCL. Note that 32bit programs are limited to 4GB address space, which is not enough for 1 billion iterations at 4 bytes per iteration; figures included for completeness. To convert 1 giga-iterations (1 billion) of N bytes per pixel is simple, it's N giga-bytes. doc Karl Runmo ( chillheimer) - original site Fork by Claude Heiland-Allen manual README.md KF uses Win32 API for user interface, implemented in C++. Pro: no need to install complicated toolkits like Qt or GTK; C++ can be fast for inner loops. Con: dated look, Windows only. videos Kalles Fraktaler - Tutorial by Maths Town Kalles Fraktaler Tutorial - How to Export a Video by Maths Town - Tutorials & Effects Kalles Fraktaler v2.15 how to make a background byBen's Fractals kf-hybrid-zoom-video-tutorial variables T: the number type, double or long double or floatexp (used when more range is needed) Zr, Zi: the final escaped Z value Jxa, Jxb, Jya, Jyb: the running derivative (for complex analytic formulas Jxa = Jyb and Jxb = - Jya, aka Cauchy-Riemann conditions) Jxa = Jyb = Re(dz/dc), Jya = -Jxb = Im(dz/dc) s: the pixel spacing TK: the rotation and skew matrix (if you don't rotate or skew then this should be the identity matrix) mouse Set the level of zoom, CTRL-left mouse click to zoom in, right to zoom out. status bar D%pixels done with current reference G%pixels guessed by neighboring interior R% reference iterations vs maxiters A% series approximation skipped vs maxiters Menu menu depends on the version of KF File File->Open is for KFR File->Open Map is for KFB Fraktal View Exponential Map Apply exponential map coordinate transform. For best (more conformal) results use a wide aspect ratio (9:1 works well, window size 1152x128 or 1536x170). You can store exponential map zoom out sequences (set zoom size to 2) and combine them into a movie with the zoomasm zoom video assembler. This is much more efficient than storing flat keyframes. Navigation Advanced ? Parameters seed value: for the fractal type = Z0 Fractal type Dialog box Iterations: "Maximum number of iterations"; "Minimum number of iteration in current view"; "Maximum number of iteration in current view"; "Iterations skipped by Series Approximation"; "Bailout value for iterations"; "Power of Mandelbrot function"; "Maximum of extra references for glitch correction"; "Checked for low tolerance of Series Approximation\nComplex images may need this to be checked to be rendered correctly\nThe render time may be faster if this checkbox is not checked"; "Terms for Series approximation is adjusted\nbased on the number of pixels to be rendered."; "List of type of Mandelbrot based Fractals\nSome of them have additional Power options"; "Terms for Series approximation.\nMore terms usually yield more skipped iterations and faster rendering,\nhowever is more time consuming to be processed"; "Display number of calculations performed"; "Include real part when checking bailout.\nUncheck for variation"; "Include imaginary part when checking bailout.\nUncheck for variation"; "Real seed value (0 is standard)"; "Imaginary seed value (0 is standard)"; bailout value and type p-norm with weights:fractalforums.org : additionnal-bailout-variations-on-kalles-fraktaler all of { a b p R } are configurable, with a special case for p = infinity (using max) Seed values for the fractal type To change open dialog window using: Menu/Actions/Iterations Keys: Ctrl+I Fractal type = m_nFractalType One can change it in the Iterations menu Menu/Fractal/Iterations Ctrl+I Types: 0 = Mandelbrot ( standard setting) 1 = Burning Ship 2 = Buffalo 3 = Celtic 4 = Mandelbar 5 = Mandelbar Celtic 6 = Perpendicular Mandelbrot 7 = Perpendicular Burning Ship 8 = Perpendicular Celtic 9 = Perpendicular Buffalo 10 = Cubic Quasi Burning Ship 11 = Cubic Partial BS Real 12 = Cubic Partial BS Imag 13 = Cubic Flying Squirrel (Buffalo Imag) 14 = Cubic Quasi Perpendicular 15 = 4th Burning Ship Partial Imag 16 = 4th Burning Ship Partial Real 17 = 4th Burning Ship Partial Real Mbar 18 = 4th Celtic Burning Ship Partial Imag 19 = 4th Celtic Burning Ship Partial Real 20 = 4th Celtic Burning Ship Partial Real Mbar 21 = 4th Buffalo Partial Imag 22 = 4th Celtic Mbar 23 = 4th False Quasi Perpendicular 24 = 4th False Quasi Heart 25 = 4th Celtic False Quasi Perpendicular 25 26 = 4th Celtic False Quasi Heart 26 27 = 5th Burning Ship Partial 27 28 = 5th Burning Ship Partial Mbar 28 29 = 5th Celtic Mbar 29 30 = 5th Quasi Burning Ship (BS/Buffalo Hybrid) 30 313 = 5th Quasi Perpendicular 31 32 = 5th Quasi Heart 32 33 = SimonBrot 4th 33 34 = 4th Imag Quasi Perpendicular / Heart 34 35 = 4th Real Quasi Perpendicular 35 36 = 4th Real Quasi Heart 36 37 = 4th Celtic Imag Quasi Perpendicular / Heart 37 38 = 4th Celtic Real Quasi Perpendicular 38 39 = 4th Celtic Real Quasi Heart 39 40 = SimonBrot 6th 40 41 = HPDZ Buffalo : Z = |Z0|^2 - |Z| + C 42 = TheRedshiftRider 1: a*z^2+z^3+c"); // 42 43 = TheRedshiftRider 2: a*z^2-z^3+c"); // 43 44 = TheRedshiftRider 3: 2*z^2-z^3+c"); // 44 45 = TheRedshiftRider 4: a*z^2+z^4+c"); // 45 46 = TheRedshiftRider 5: a*z^2-z^4+c"); // 46 47 = TheRedshiftRider 6: a*z^2+z^5+c"); // 47 48 = TheRedshiftRider 7: a*z^2-z^5+c"); // 48 49 = TheRedshiftRider 8: a*z^2+z^6+c"); // 49 50 = TheRedshiftRider 9: a*z^2-z^6+c"); // 50 51 = SimonBrot2 4th // 51 files KF can export raw iteration data in EXR (and obsolete KFB) formats, so you can colour it with other software map files (*.kfb, *.exr) with iteration data parameter file (*.kfr) with the current location and settings ( also in the image metadata) exe fraktal_sft.exe ( old kf ) exr EXR file channels: raw iteration data = normalized iteration counttowards a common file format for 2D escape time iteration data N = integer iteration count ( uint32 ) NF = fractional iteration count, float in range [0.0 .. 1.0) T = phase = the argument of the first Z value to escape, measured in turns Jxa, Jxb, Jya, Jyb: the running derivative for complex analytic formulas Jxa = Jyb and Jxb = - Jya, aka Cauchy-Riemann conditions Jxa = Jyb = Re(dz/dc), Jya = -Jxb = Im(dz/dc) DE = directional Distance Estimation (when derivatives have been calculated) RGB = colours (half float): half R, half G, half B in linear light Metadata The channel names are strings pnmcat -tb *.exr > *.ppm normalized iteration count uint32 N integer iteration count 0xFFFFFFFF is non-escaped before header metadata field int Iterations (or string Iterations, as it can exceed the range of int) 0x00000000 is uncalculated/glitch/no-data-available. If actual iteration values can be zero or negative, add a bias constant to each count and store it in the header metadata field int IterationsBias (or string IterationsBias, it can exceed the range of int). The bias could be negative, this might allow you to store high iteration counts without necessarily needing two channels if the actual min/max range is small enough) For images with biased iteration counts above 0xFFFFFFFE, split into two channels: uint32 N0 least significant 32 bits uint32 N1 most significant 32 bits (0xFFFFFFFF, 0xFFFFFFFF) is interpreted as non-escaped For future supercomputers, this can be extended with N2 etc… NF The continuous iteration count (when escaped) is N+NF-IterationsBias. This is stored separately to avoid losing precision at high iteration counts It is desirable that this aligns with NF to give 2D exterior grid cell coordinates, KF versions before 2.15 align only with Linear smoothing. genType NF fractional iteration count, expected to be in [0.0 .. 1.0) for float32 and half (float16), and the full range normalized by dividing by 0x100000000 for uint32. The continuous iteration count (when escaped) is N+NF-IterationsBias. This is stored separately to avoid losing precision at high iteration counts T phase of first escaped Z value, measured in turns. phase channel (T in EXR) based on argument angle of final iterate float T in [0.0 .. 1.0) DE directional DE (when derivatives have been calculated) float DEX, float DEY directional distance estimate in cartesian form, normalized such that distance to a neighbouring boundary pixel sqrt(DEX^2 + DEY^2) is approximately 1.0. If some pixels have no directional DE the missing data can be written as (0.0, 0.0), but readers should also handle NaNs in this case. The vector points away from the fractal boundary. floatType DE signed distance estimate, normalized such that distance to a neighbouring boundary pixel is approximately 1.0 for exterior distance estimate and -1.0 for interior distance estimate. If there are exterior de and no interior de available (or vice versa) the missing data can be written as 0.0, but readers should also handle NaN in this case. floatType DEX, floatType DEY directional distance estimate in cartesian form, normalized such that distance to a neighbouring boundary pixel sqrt(DEX^2 + DEY^2) is approximately 1.0. If some pixels have no direcitonal DE the missing data can be written as (0.0, 0.0), but readers should also handle NaNs in this case. The vector should point away from the fractal boundary. ZX ZY floatType ZX, floatType ZY coordinates at the first escaped iteration. Image should have a header attribute floatType EscapeRadius. TRAP Orbit traps can be handled as layers with TRAP somewhere in the path: uint32 TRAP.N iteration number at which trap was hit, see above for large iteration counts floatType TRAP.TD distance to trap (eg an x-axis trap would have |y-coordinate|) (normalized however you like, as deep images may have tiny values (perhaps?), but should be monotonic, it could eg be negative if you take logs for more range than float32) floatType TRAP.ZX, floatType TRAP.ZY coordinates at the trap iteration, should be normalized so that the magnitude at the edge of the trap is 1.0 (can't use just X and Y because Y is already claimed in EXR for colour luminance). jpg JPEG is lossy kfc "KFC" is bNewFormat 1, vertical lines of float32 combined data (int32 iteration + float32 smooth) kfb Obsolete format , see exr The map file (.kfb) contains: the calculated fractal data: iteration counts N (max iterations , integer) NF ( iteration , smooth part = double) sometimes distance estimates if you enabled derivative calculations) It also contains some colouring information (but this is not complete) It does NOT contain the coordinates. These files are created: when saving the jpg files, there is also a kfb file created for each image save a map Description: "KF can export raw iteration data in EXR (and obsolete KFB) formats, so you can colour it with other software" "KFB files store raw uncompressed (ie huge but high quality) iteration data (the results of the fractal calculations before colouring is applied)." Claude at FF, for example raw float32 DE images (scaled to pixel spacing) "the KFB files are images used as maps to store iteration data. No location, palette, etc" youhn Claude on FF: fractalforums org: KF file-types They are strings found inside .kfb files (the first 3 bytes) to distinguish different versions of the data format stored in the file. "KFB" is bNewFormat 0, vertical lines of int32 iteration plane followed by float32 smooth colouring plane. "KFC" is bNewFormat 1, vertical lines of float32 combined data (int32 iteration + float32 smooth) "KFD" is bNewFormat 2, horizontal lines of float32 combined data (int32 iteration + float32 smooth) As far as I can tell, only "KFB" is actually saved by current versions of Kalles Fraktaler. "KFB" is also the only format that preserves smooth colouring at high iteration counts, because single precision float32 can only represent integers after 2^24 = 16M, can only represent even integers after 2^25 = 33M, etc, with gradual degradation before that. // from fractal_sftp.cpp Kalles Fraktaler 2 © 2014-2015 Karl Runmo void CFraktalSFT::SaveMapB(char *szFile) { if (!m_nPixels) return; DWORD dw; HANDLE hFile = CreateFile(szFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); int x; WriteFile(hFile, "KFB", 3, &dw, NULL); WriteFile(hFile, &m_nX, sizeof(m_nX), &dw, NULL); WriteFile(hFile, &m_nY, sizeof(m_nY), &dw, NULL); for (x = 0; x<m_nX; x++) WriteFile(hFile, m_nPixels[x], m_nY*sizeof(int), &dw, NULL); int div = m_nIterDiv; WriteFile(hFile, &div, sizeof(m_nParts), &dw, NULL); WriteFile(hFile, &m_nParts, sizeof(m_nParts), &dw, NULL); WriteFile(hFile, m_cKeys, sizeof(COLOR14)*m_nParts, &dw, NULL); WriteFile(hFile, &m_nMaxIter, sizeof(int), &dw, NULL); for (x = 0; x<m_nX; x++) WriteFile(hFile, m_nTrans[x], m_nY*sizeof(float), &dw, NULL); CloseHandle(hFile); } Here is the octave/matlab code by Gerrit:fractalforums org : matlaboctave-code-for-kfb-reading function [width,height,counts,trans,maxiter,parts,keys] = readKFB(fn) % counts are iterations % trans is the correction to smooth iteration count based on escape time % (see wiki) % parts is number of colors, keys are the colors. % to make a colormap(cmap): % > cmap = reshape(keys,3,parts)'/255.; % > cmap = flipud(fliplr(cmap)); info = dir(fn); fid = fopen(fn,'r'); d = fread(fid, [1, info.bytes], '*uint8'); fclose(fid); %d(1:3) == 'KFB' test skipped k = 4; nBytes = 4; width = typecast(uint8(d(k:k+nBytes-1)),'uint32'); width = double(width); k = k + nBytes; height = typecast(uint8(d(k:k+nBytes-1)),'uint32'); height = double(height); k = k + nBytes; nCounts = width*height; %32 bit ints nBytes = 4 * nCounts; counts = typecast(uint8(d(k:k+nBytes-1)),'uint32'); counts = reshape(counts,height,width); counts = single(counts); k = k + nBytes; nBytes = 4; iterdiv = typecast(uint8(d(k:k+nBytes-1)),'uint32'); k = k + nBytes; parts = typecast(uint8(d(k:k+nBytes-1)),'uint32'); parts = double(parts); k = k + nBytes; nBytes = parts * 3; % r,g,b,... parts triples keys = typecast(uint8(d(k:k+nBytes-1)),'uint8'); keys = double(keys); k = k + nBytes; nBytes = 4; maxiter = typecast(uint8(d(k:k+nBytes-1)),'uint32'); maxiter = double(maxiter); k = k + nBytes; nBytes = 4 * nCounts; trans = typecast(uint8(d(k:k+nBytes-1)),'single'); trans = reshape(trans,height,width); File header in hexadecimal editor : KFB....h. kfd kfp kfp = Kalles Fraktaler palette files Jeremy Thomson's collection description On the file naming convention used a file name such as "p512bcgwmryk.kfp" is a 512 colour palette a 3bit colour cube sorted into Blue, Cyan, Green, White, Magenta, Red and yellow groups, then sub sorted within these groups to get a smooth changes in colour. Most files will have a striping ending "p512bcgwmrykof8.kfp" shifts each 2nd colour 8 places. "p512bcgwmrykpm4816" is a more complex striping, the 2nd colour is shifted 4 paces, the 4th 8 places, the 6th 4 places and the 8th 16 places and so on. "p512X2bcgwyrmkof32" duplicates the 512 colour palette into light and dark halves. "p1024bmwmbcgyrk" the "bm" stands for bit mix a more satisfactory way of sampling the 8 bit colour cube into 1024 colours. There are a few other oddball palettes, "LenaSoderburg.kfp" is a palette that is a 32x32 low resolution version of the famous "Lena" picture use in early image processing development. Jeremy Thomson ColorOffset: 0 Rotate: 0 Ratio: 363.025211 Colors: 0,0,255,0,4,255,0,8,255,0,12,255,0,16,255,0,20,255,0,24,255,0,28,255,0,32,255,0,36,255,0,40,255,0,45,255,0,49,255,0,53,255,0,57,255,0,61,255,0,65,255,0,69,255,0,73,255,0,77,255,0,81,255,0,85,255,0,89,255,0,93,255,0,97,255,0,101,255,0,105,255,0,109,255,0,113,255,0,117,255,0,121,255,0,125,255,0,130,255,0,134,255,0,138,255,0,142,255,0,146,255,0,150,255,0,154,255,0,158,255,0,162,255,0,166,255,0,170,255,0,174,255,0,178,255,0,182,255,0,186,255,0,190,255,0,194,255,0,198,255,0,202,255,0,206,255,0,210,255,0,215,255,0,219,255,0,223,255,0,227,255,0,231,255,0,235,255,0,239,255,0,243,255,0,247,255,0,251,255,0,255,255, Smooth: 0 MultiColor: 0 BlendMC: 0 MultiColors: Power: 2 FractalType: 0 Slopes: 0 SlopePower: 50 SlopeRatio: 50 SlopeAngle: 45 image: 1 real: 1 SeedR: 0 SeedI: 0 FactorAR: 1 FactorAI: 0 grep -nR "kfp" fraktal_sft/cmdline.cpp:280:" -c, --load-palette [FILE.kfp] load palette file\n" fraktal_sft/main_color.cpp:481: if(BrowseFile(hWnd,FALSE,"Save palette","Palette\0*.kfp\0\0",szFile)) fraktal_sft/main_color.cpp:696: if(BrowseFile(hWnd,TRUE,"Open palette","Palette\0*.kfp\0\0",szFile)){ Using /path/to/kf.exe -s my.kfs -l my.kfr -c my.kfp -x my.exr For (re-)colouring existing EXR files containing raw iteration data, try /path/to/kf.exe -s old.exr -l old.exr -o old.exr -c new-palette.kfp -x new.exr kfr text file contain parametrs The parameter file (.kfr) before loading the map file to be able to navigate further. You can rename .kfr to .kfp and load it in the colour dialog. Re: -1.252075014867735555974940801848588674907763636282052371316271536003707048655691466436892204807423486911208873753204122 Im: -0.008791858755657632997049331233776536713263464347924936644487037690633902732242296004830894920786698063372255536046170 Zoom: 2.9333318059216862E91 Iterations: 31394 IterDiv: 0.010000 SmoothMethod: 0 ColorMethod: 7 Differences: 3 ColorOffset: 0 Rotate: 0.000000 Ratio: 383.431953 Colors: 195,192,201,41,59,47,31,230,221,54,211,5,239,241,216,219,206,62,238,205,241,9,21,23, InteriorColor: 0,0,0, Smooth: 1 MultiColor: 0 BlendMC: 0 MultiColors: Power: 2 FractalType: 0 Slopes: 1 SlopePower: 50 SlopeRatio: 20 SlopeAngle: 45 imag: 1 real: 1 SeedR: -0.5 SeedI: 0 FactorAR: 1 FactorAI: 0 Period: 0 ZoomSize: 2 MaxReferences: 10000 GlitchLowTolerance: 0 ApproxLowTolerance: 0 AutoApproxTerms: 1 ApproxTerms: 63 WindowWidth: 640 WindowHeight: 360 WindowTop: 318 WindowLeft: 630 WindowBottom: 445 WindowRight: 660 ImageWidth: 8000 ImageHeight: 4500 ThreadsPerCore: 1 AnimateZoom: 1 ArbitrarySize: 1 ReuseReference: 0 AutoSolveGlitches: 1 Guessing: 1 SolveGlitchNear: 0 NoApprox: 0 Mirror: 0 LongDoubleAlways: 0 FloatExpAlways: 0 AutoIterations: 1 ShowGlitches: 1 NoReuseCenter: 1 IsolatedGlitchNeighbourhood: 4 JitterSeed: 0 JitterShape: 0 JitterScale: 1 Derivatives: 0 ShowCrossHair: 0 UseNanoMB1: 0 UseNanoMB2: 0 OrderM: 16 OrderN: 16 InteriorChecking: 0 RadiusScale: 0.100000000000000006 Examples: gallery kfs This file type is for settings (.kfs), useful for configuring command line rendering or saving presets. png Program can open and sve pang with comments: /* Kalles Fraktaler 2 Copyright (C) 2013-2017 Karl Runmo Copyright (C) 2017-2018 Claude Heiland-Allen This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include <stdio.h> #include <string.h> #include <time.h> #include <string> #include <png.h> #include <zlib.h> #include "png.h" static void kf_png_error_handler(png_structp png, png_const_charp msg) { // FIXME make this display in the GUI or something fprintf(stderr, "PNG ERROR: %s\n", msg); longjmp(*static_cast<jmp_buf *>(png_get_error_ptr(png)), 1); } static void kf_png_warning_handler(png_structp png, png_const_charp msg) { (void) png; // FIXME make this display in the GUI or something fprintf(stderr, "PNG WARNING: %s\n", msg); } static bool skip_png_image(png_structp png, png_infop info); extern int SavePNG(const std::string &szFileName, char *Data, int nHeight, int nWidth, int nColors, const std::string &comment) { jmp_buf jmpbuf; if (nColors != 3) return 0; FILE *file = fopen(szFileName.c_str(), "wb"); if (! file) return 0; png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, &jmpbuf, kf_png_error_handler, kf_png_warning_handler); if (! png) return 0; png_infop info = png_create_info_struct(png); if (! info) { png_destroy_write_struct(&png, 0); fclose(file); return 0; } if (setjmp(jmpbuf)) { png_destroy_write_struct(&png, &info); fclose(file); return 0; } png_init_io(png, file); png_set_compression_level(png, Z_BEST_COMPRESSION); png_set_IHDR(png, info, nWidth, nHeight, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_time mtime; png_convert_from_time_t(&mtime, time(0)); png_set_tIME(png, info, &mtime); png_text text; text.compression = PNG_TEXT_COMPRESSION_NONE; const std::string &key = "Comment"; text.key = const_cast<char *>(key.c_str()); text.text = const_cast<char *>(comment.c_str()); png_set_text(png, info, &text, 1); png_write_info(png, info); png_bytepp row = new png_bytep[nHeight]; for (int y = 0; y < nHeight; ++y) row[y] = (png_bytep)(Data + nWidth * nColors * y); png_write_image(png, row); png_write_end(png, 0); delete [] row; fclose(file); return 1; } extern std::string ReadPNGComment(const std::string &filename) { jmp_buf jmpbuf; FILE *file = fopen(filename.c_str(), "rb"); if (! file) return ""; png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, &jmpbuf, kf_png_error_handler, kf_png_warning_handler); if (! png) { fclose(file); return ""; } png_infop info = png_create_info_struct(png); if (! info) { png_destroy_read_struct(&png, 0, 0); fclose(file); return ""; } png_infop enfo = png_create_info_struct(png); if (! enfo) { png_destroy_read_struct(&png, &info, 0); fclose(file); return ""; } if (setjmp(jmpbuf)) { png_destroy_read_struct(&png, &info, 0); fclose(file); return ""; } png_init_io(png, file); png_read_info(png, info); png_textp text; int count = 0; std::string comment = ""; if (png_get_text(png, info, &text, &count) > 0) for (int t = 0; t < count; t++) // we save as capitalized, but processing with ImageMagick downcases if (0 == stricmp("Comment", text[t].key)) comment = text[t].text; // copy if (comment == "") { if (skip_png_image(png, info)) { png_read_end(png, enfo); png_textp etext; int ecount = 0; if (png_get_text(png, enfo, &etext, &ecount) > 0) for (int t = 0; t < ecount; t++) // we save as capitalized, but processing with ImageMagick downcases if (0 == stricmp("Comment", etext[t].key)) comment = etext[t].text; // copy } } png_destroy_read_struct(&png, &info, &enfo); fclose(file); return comment; } sampling sampling code : https://code.mathr.co.uk/kalles-fraktaler-2/blob/d685883599f7ae795bd7667834b0d2a47c00c7ef:/fraktal_sft/fraktal_sft.cpp#l3314 lines 3314 through 3379 KF does it: generates a hash of (i,j,seed) for each of dx,dy offset (seed is different for x and y) uses that to jitter. coloring methods KF can export raw iteration data in EXR (and obsolete KFB) formats, so you can colour it with other software, but learning GLSL and writing colouring shaders in KF may be as easy as writing other software. The colouring shaders in Zoomasm 4 (unreleased WIP) are more powerful than KF, because you can add additional uniform variables in the code and control them from the GUI, which makes tweaking things easier. Still only numeric entry fields, which is a bit awkward, and really designed for animation with exponential map sequences. Pauldelbrot uses a complicated "multiwave" colouring algorithm, different from (and better than) the palette waves in default KFP colouring algorithm. Check the forums for the source code that he posted in a LISP variant (maybe Clojure?). Maybe it's also in the UF formula database somewhere? The key is to have multiple waves of RGB or HSV at different rates, possibly linked to the structure of the fractal (periods etc) that influence each other in complex ways (this is definitely not just separate waves of R G B or H S V, but waves of 3D colours). Also this is done in a different colour space, because blending sRGB values (as used in image files) is wrong (they must be converted to linear first for blending to make any sense). Claude implemented something possibly similar (but probably not as good) in Rodney, Claude's fractal explorer bot. homepage with gallery and links to try-in-browser version https://mathr.co.uk/rodney palette GLSL implementation https://code.mathr.co.uk/rodney/blob/99b68fa46c0724eac8c5b55c4018cb748c98a0c4:/palette.frag palette C++ implementation https://code.mathr.co.uk/rodney/blob/99b68fa46c0724eac8c5b55c4018cb748c98a0c4:/rodney.h#l792 palette randomization including auto-white-balance https://code.mathr.co.uk/rodney/blob/99b68fa46c0724eac8c5b55c4018cb748c98a0c4:/explore.cc#l335 image rendering https://code.mathr.co.uk/rodney/blob/99b68fa46c0724eac8c5b55c4018cb748c98a0c4:/render.cc#l107 One can change it : Main Menu / Actions/ Set Colors keys: Ctrl+C Available color methods are ( in main.cpp file line 256, variable m_nColorMethod ) : 0 = Standard = Distance (Linear): Standard iteration band coloring 1 = Square root: Iterations are squared before colors are appplied 2 = Cubic root: Cube root is applied before colors 3 = Logarithm: Logarithm is applied before colors = ColorMethod_Logarithm fractalforums : distance-logarithm-test: "ColorMethod_Logarithm is not DEM at all, it's escape time with non-linear transfer function." 4 = Stretched: The palette is stretched over min-max iteration values 5 = Distance: Distance Estimation : "ColorMethod_Distance* have some image processing (looking up iteration values of neighbouring pixels) to generate a pseudo-de colouring. It's not true DEM but looks pretty close sometimes." 6 = DE+Standard Numbers describing methods ( variable m_nColorMethod) are changing between versionsfractalforums : kalles-fraktaler/backwards-compatibility Code: file fraktal_sft.cpp variable m_nColorMethod functions: CFraktalSFT::SetColorMethod void CFraktalSFT::SetColor CFraktalSFT::OpenFile CFraktalSFT::SaveFile // fraktal_sft.h enum ColorMethod { ColorMethod_Standard = 0, ColorMethod_SquareRoot = 1, ColorMethod_CubicRoot = 2, ColorMethod_Logarithm = 3, ColorMethod_Stretched = 4, ColorMethod_DistanceLinear = 5, ColorMethod_DEPlusStandard = 6, ColorMethod_DistanceLog = 7, ColorMethod_DistanceSqrt = 8, ColorMethod_LogLog = 9, ColorMethod_ATan = 10, ColorMethod_FourthRoot = 11 }; enum Differences { Differences_Traditional = 0, Differences_Forward3x3 = 1, Differences_Central3x3 = 2, Differences_Diagonal2x2 = 3, Differences_LeastSquares2x2 = 4, Differences_LeastSquares3x3 = 5, Differences_Laplacian3x3 = 6, Differences_Analytic = 7 }; //fraktal_sft.cpp void CFraktalSFT::SetColor(int nIndex, int nIter, double offs, int x, int y) { if (nIter<0 || (!g_bShowGlitches && offs==2)) return; if (nIter == m_nMaxIter) m_lpBits[nIndex] = m_lpBits[nIndex + 1] = m_lpBits[nIndex + 2] = 0; { double iter = (double)nIter + (double)1 - offs; // m_nColorMethod = 0; if (m_nColorMethod == 1){ iter = sqrt(iter); } else if (m_nColorMethod == 2){ iter = pow(iter, (double)1 / (double)3); } else if (m_nColorMethod == 3){ iter = log(iter); } else if (m_nColorMethod == 4){ int nMin, nMax; GetIterations(nMin, nMax,NULL,NULL,TRUE); iter = (double)1024 * ((double)iter - (double)nMin) / ((double)nMax - (double)nMin); } else if (m_nColorMethod == 5 || m_nColorMethod == 6){ double p1, p2, p3, p4; iter=0; if (x){ p1 = (double)m_nPixels[x - 1][y] + (double)1 - m_nTrans[x - 1][y]; p2 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; } else if (x<m_nX - 1){ p1 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; p2 = (double)m_nPixels[x + 1][y] + (double)1 - m_nTrans[x + 1][y]; } else p1 = p2 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; double _abs_val; iter += _abs(p1 - p2)*1.414; if (x && y){ p1 = (double)m_nPixels[x - 1][y - 1] + (double)1 - m_nTrans[x - 1][y - 1]; p2 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; } else if (x<m_nX - 1 && y<m_nY - 1){ p1 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; p2 = (double)m_nPixels[x + 1][y + 1] + (double)1 - m_nTrans[x + 1][y + 1]; } else p1 = p2 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; iter += _abs(p1 - p2); if (y){ p1 = (double)m_nPixels[x][y - 1] + (double)1 - m_nTrans[x][y - 1]; p2 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; } else if (y<m_nY - 1){ p1 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; p2 = (double)m_nPixels[x][y + 1] + (double)1 - m_nTrans[x][y + 1]; } else p1 = p2 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; iter += _abs(p1 - p2)*1.414; if (y && x<m_nX-1){ p1 = (double)m_nPixels[x + 1][y - 1] + (double)1 - m_nTrans[x + 1][y - 1]; p2 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; } else if (x && y<m_nY - 1){ p1 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; p2 = (double)m_nPixels[x - 1][y + 1] + (double)1 - m_nTrans[x - 1][y + 1]; } else p1 = p2 = (double)m_nPixels[x][y] + (double)1 - m_nTrans[x][y]; iter += _abs(p1 - p2); // iter/=4; // iter*=iter; iter*=(double)m_nX / (double)640; iter=sqrt(iter); /*iter=log(iter); if(iter<0) iter=0;*/ if(iter>1024) iter=1024; if(m_nColorMethod == 6 && iter>m_nIterDiv) iter = (double)nIter + (double)1 - offs; } if (m_nIterDiv != 1){ iter /= m_nIterDiv; } if (m_nColorOffset) iter += m_nColorOffset;// = (nIter+m_nColorOffset)%1024; nIter = (int)iter; offs = 1 - (iter - (double)nIter); if (m_bITrans) offs = 1 - offs; if (m_bMW){ double nH = 0, nS = 0, nB = 0; int nDR = 0, nDG = 0, nDB = 0; int i; for (i = 0; i<m_nMW; i++){ double nPeriod; nPeriod = m_MW[i].nPeriod; double g; if (m_bTrans) g = sin((pi*iter) / nPeriod) / 2 + .5; else g = sin((pi*((int)iter)) / nPeriod) / 2 + .5; if (nPeriod<0) g = -(double)nPeriod / (double)100; if (m_MW[i].nType == 0){ nH += g; nDR++; } if (m_MW[i].nType == 1){ nS += g; nDG++; } if (m_MW[i].nType == 2){ nB += g; nDB++; } } if (nDR) nH /= nDR; if (nDG) nS /= nDG; if (nDB) nB /= nDB; COLOR14 cPos; HSVToRGB(nH, nS, nB, cPos); m_lpBits[nIndex] = cPos.r; m_lpBits[nIndex + 1] = cPos.g; m_lpBits[nIndex + 2] = cPos.b; if (m_bBlend){ int nR, nG, nB; if (m_bTrans && offs){ double g1 = (1 - offs); int col = nIter % 1024; int ncol = (col + 1) % 1024; nR = m_cPos[col].r*offs + m_cPos[ncol].r*g1; nG = m_cPos[col].g*offs + m_cPos[ncol].g*g1; nB = m_cPos[col].b*offs + m_cPos[ncol].b*g1; } else{ int col = nIter % 1024; nR = m_cPos[col].r;//+n; nG = m_cPos[col].g;//+n; nB = m_cPos[col].b;//+n; } m_lpBits[nIndex] = (m_lpBits[nIndex] + nR) / 2; m_lpBits[nIndex + 1] = (m_lpBits[nIndex + 1] + nG) / 2; m_lpBits[nIndex + 2] = (m_lpBits[nIndex + 2] + nB) / 2; } } else{ if (m_bTrans && offs){ double g1 = (1 - offs); int col = nIter % 1024; int ncol = (col + 1) % 1024; m_lpBits[nIndex] = m_cPos[col].r*offs + m_cPos[ncol].r*g1; m_lpBits[nIndex + 1] = m_cPos[col].g*offs + m_cPos[ncol].g*g1; m_lpBits[nIndex + 2] = m_cPos[col].b*offs + m_cPos[ncol].b*g1; } else{ int col = nIter % 1024; m_lpBits[nIndex] = m_cPos[col].r;//+n; m_lpBits[nIndex + 1] = m_cPos[col].g;//+n; m_lpBits[nIndex + 2] = m_cPos[col].b;//+n; } } } @color[int(($iteration/$divide_constant)%pallet_size)] -- (Perl code, % is the modulo operator) where divisor ( divide_constant) is less than one, like .1, or .01. cli How to colour a KFB from the command line ? Here is a small shell script to do colour cycling: #!/bin/bash f=0 for i in $(seq 0 32 1023) do t=$((i * 360 / 1024)) echo $f $i $t cat template.kfp | sed "s/ColorOffset: 0/ColorOffset: $i/" | sed "s/SlopeAngle: 45/SlopeAngle: $t/" > tmp.kfp ./kf.exe -o input.kfb -c tmp.kfp -p "$(printf %02d $f).png" f=$((f + 1)) done for i in *.png do convert $i -colorspace RGB -geometry 320x180 -colorspace sRGB $i.gif done gifsicle --colors 256 --delay 4 --loop --optimize *.png.gif > output.gif Here's another example: find a nice location use KFP_ColorOffset in your OpenGL GLSL colouring shader figure out magic numbers to make colour cycling align with the fractal (this example uses 30.0): vec3 colour() { if (getInterior()) { return KFP_InteriorColor; } float49 N = getN(); N = div(N, 30.0); N = add(N, KFP_ColorOffset / 1024.0); return mix(vec3(0.0), texture(KFP_Palette, to_float(N)).rgb, tanh(clamp(0.25 * length(getDE()), 0.0, 4.0))); } save fractal as EXR map file at desired size (probably bigger than final output, for supersampling for antialiasing). run a bash script to animate KFP_ColorOffset and save frames: #!/bin/bash seq 0 32 1023 | cat -n | while read frame ColorOffset do echo -e "ColorOffset: ${ColorOffset}\r" > palette.kfp /path/to/kf.x86_64.exe -s map.exr -l map.exr -o map.exr -c palette.kfp -t "$(printf %04d "${frame}").tif" done this renders 32 frames, for 16 frames change 0 32 1023 to 0 64 1023, for 64 frames change to 0 16 1023 - generally power of two will be most smoothly looping convert frames to GIF with gamma-correct downscaling using ImageMagick: for i in *.tif do convert "${i}" -colorspace RGB -geometry 256x256 -colorspace sRGB "${i}.gif" done assemble frames to animated GIF: gifsicle --delay 5 --loop --optimize --colors 256 *.tif.gif > output.gif view GIF in firefox or other software post-processing effects slope "Slopes rendering is originally a screen-space post-processing effect, using differences between neighbouring pixels' smooth iteration counts. More recently it can use directional distance estimate (normalized by pixel spacing) instead, which I think gerrit proved is equivalent in the limit of infinitely fine pixel grid. Relevant part of the source code: https://code.mathr.co.uk/kalles-fraktaler- 2/blob/c78c224a4a3ae7f10ed03aa3948f0cd6b740adcb:/fraktal_sft/fraktal_sft.cpp#l933 lines 933 to 998 " Claude Variables: m_bSlopes = FALSE; is boolean variable m_nSlopePower = 50; is Slope shadow depth, integer m_nSlopeRatio = 50; is Slope shadow strength, integer m_nSlopeAngle = 45; is Slope shadow angle (0-360), integer Show slopes Enable slope encoding for 3D effect. First value is the magnification of the slopes. The start value of 100 is suitable for the unzoomed view. Deep views requires a couple of magnitudes higher value. The second value is the percentage with which the slope encoding is applied on the coloring. 100 is max, however flat areas will still have the palette color visible. Algorithm: fractalforums.org grep -nR "Slope" tools sft-map-visualizer kf-extras - programs for manipulating output from Kalles Fraktaler 2 zoomasm : KFMovieMaker KFMovieMaker fractalforums.org : after-effects-plug-in-for-kalles-fraktaler-something-im-working-on Videos: traditional colouring method A Simple Journey - Mandelbrot Fractal Zoom (7e1631) Threads of Colour - Mandelbrot Fractal Zoom (e652) (4k 60fps) Distance Estimation and Slopes Red Lace - Mandelbrot Fractal Zoom step colouring A Hidden World - Perpendicular Mandelbrot Zoom Liquid Christmas Infinity Liquid - Mandelbrot Fractal Zoom slopes: colour scheme is all linear Mandelbrot, with some added lighting (slopes) to give it a 3D feel. Life on Mars - Mandelbrot Fractal Zoom Temple of the Mandelbrot - A fractal zoom (4k 60fps) A Complex Place - Mandelbrot Fractal Zoom (8k 60fps) Square Root transfer function. Hypnotic - Mandelbrot Fractal Zoom Greyscale - Mandelbrot Fractal Zoom Panel" effect A Trip to Infinity - Mandelbrot Fractal Zoom (Depth 1.2e1077) (4k 60fps) - slopes ( angle only, shadow depth = 650, strength = 20, shadow angle = 0-240) The Endless Ocean - Mandelbrot Fractal Zoom - colour cycling, so things are moving a little. Shaded to give it a pseudo-3D feel. The angle for the lighting effect is based on the angle at which the iteration count is increasing. Such shading is cue for the brain to interpret the image as having depth. log steps Steps to Infinity - Mandelbrot Fractal Zoom (2e1289) with "angle" shading for a psuedo-3D effect. Ship of Spirals - Burning Ship Fractal Zoom A Complicated Journey - Mandelbrot Fractal Zoom angle ( an approximation of directional derivative) angle video page and video: Angle - Mandelbrot Fractal Zoom Into The Purple - Mandelbrot Fractal Zoom Effects: color cycling The Hardest Trip - Mandelbrot Fractal Zoom The Endless Ocean - Mandelbrot Fractal Zoom - colour cycling, so things are moving a little. Shaded to give it a pseudo-3D feel. The angle for the lighting effect is based on the angle at which the iteration count is increasing. Such shading is cue for the brain to interpret the image as having depth. Audio - An Audio Responsive Mandelbrot Fractal zoom color cycling synchronized with music Blending grep -nR "Blend" Abreviations ADE = analytic DE = Analytic Distance Estimation NDE = numerical DE DDE = directional DE NR = Newton-Raphson zooming SMB BLA the bilinear approximation acceleration method SA = series approximation SSA series skipping algorithm ( see mandelbrot-perturbator program ) simpler series approximation SFT = K.I. Martin's SuperFractalThing ET = Escape Time ETA Escape Time Algorithm (?) help Movie Maker 3D by Yann Le Bihan references