#!/bin/bash # # Modified version of bash mandelbrot from Mecki stackoverflow.com/users/15809 # found at https://stackoverflow.com/a/63749612/1765658 # Avoiding forks and running bc as background task, reducing # execution time, from many hours to less than 10' (on my desktop) # # Modified version tested under MacOS, with bash 3.2.57(1)-release BAILOUT=16 MAX_ITERATIONS=1000 ALPHWIDTH=$(( `tput cols` / 2 )) AWIDE=$(( ALPHWIDTH -1 )) fifo=/tmp/fifo-$RANDOM$RANDOM-$$ mkfifo $fifo exec 10> >(exec bc -l >$fifo) exec 11<$fifo rm $fifo bc() { local retvar="$1" shift echo >&10 "$@" read -ru 11 -t 1 "$retvar" } echo >&10 "scale=16;bailout=$BAILOUT;alphwidth=$ALPHWIDTH.0;" function iterate { # $1 is x # $2 is y local zi=0 local zr=0 local i=0 local cr bc cr "$2 - 0.5" while true do local temp local zr2 local zi2 i=$((i + 1)) bc zr2 "($zr * $zr) - ($zi * $zi) + $cr" bc zi2 "(($zr * $zi) * 2) + $1" bc temp "(($zi * $zi) + ($zr * $zr)) > bailout" if ((temp == 1)) then return "$i" fi if ((i > MAX_ITERATIONS)) then return 0 fi zr="$zr2" zi="$zi2" done } function mandelbrot { local y for (( y = 0-AWIDE ; y < AWIDE ; y++ )) do printf "\n" local x for (( x = 0 - AWIDE ; x < AWIDE; x++)) do local xi local yi local ires bc xi "$x / alphwidth" bc yi "$y / alphwidth" iterate "$xi" "$yi" ires=$? if ((ires == 0)) then printf "*" else printf " " fi done done printf "\n" } mandelbrot