Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

mzoom

By: dwbash on Apr 25th, 2013  |  syntax: None  |  size: 6.98 KB  |  views: 7,367  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/bin/bash
  2.  
  3. #############################################################
  4. #                                                           #
  5. # Program:      mzoom                                       #
  6. # Author:       dw                                          #
  7. # Date:         2007-07-07                                  #
  8. # Purpose:      Explore the Mandelbrot set in bash!         #
  9. # Usage:        See below                                   #
  10. # Version:      1.01.6930                                   #
  11. #                                                           #
  12. #############################################################
  13.  
  14. #### Usage: Run with no arguments, program will draw full mandelbrot set. After set is complete,
  15. #### use the arrow keys to navigate to the upper left corner of an area you want to zoom into,
  16. #### then press the "z" key once, use the right arrow key again to move to the right, you are now
  17. #### deciding how big of a "box" to draw around the area, when you are far enough to the right,
  18. #### press the "z" key one more time, this will draw a box roughly around the area to be zoomed
  19. #### into, after a brief pause, the program will zoom into the area you selected. Repeat process
  20. #### to continue zooming, use control c to exit.
  21.  
  22. #### As your level of zoom increases, you'll want to increase the number of iterations, you can
  23. #### do this by pressing the "i" key while in zoom mode, anytime before pressing the second "z",
  24. #### this will increase the max iterations by 50 each time.
  25.  
  26. #### This program uses integer math to explore the Mandelbrot set, it will not zoom in as far as
  27. #### a "real" Mandelbrot explorer, but floating point was just too slow in bash, you'll know when
  28. #### you hit the limit, I have tested it to about 2,000,000 magnification. My bash/python hybred
  29. #### version zooms much further and is over 40 times faster. :-)
  30.  
  31. #### GET CURRENT SCREEN SIZE - METHOD 1
  32. w=`tput cols`
  33. e=`tput lines`
  34.  
  35. #### DO WE HAVE A SCREEN SIZE? IF NOT, TRY METHOD 2
  36. if [ ! "$w" ]
  37. then
  38.   #### GET CURRENT SCREEN SIZE - METHOD 2
  39.   w=`stty -a | grep rows | awk -F ";" '{print$3}' | awk '{print$2}'`
  40.   e=`stty -a | grep rows | awk -F ";" '{print$2}' | awk '{print$2}'`
  41.   #### HOW ABOUT NOW?
  42.   if [ ! "$w" ]
  43.   then
  44.     clear;echo;echo "COULD NOT OBTAIN SCREEN SIZE";echo;exit
  45.   fi
  46. fi
  47.  
  48. #### SET MAX X & Y
  49. ((w = w - 1));((e = e - 1));maxy="$e";maxx="$w"
  50.  
  51. #### SETUP THE COLOR VARIABLES
  52. off="\033[0m";gry="\033[1;0m";red="\033[1;31m";grn="\033[1;32m";yel="\033[1;33m"
  53. blu="\033[1;34m";pur="\033[1;35m";aqu="\033[1;36m";wht="\033[1;37m"
  54.  
  55. #### SET THE BC PRECESION
  56. pre=20
  57.  
  58. #### SETUP THE MANDELBROT VARIABLES
  59. si=$(echo "scale=$pre;(2.5)" | bc)          ### length of side = 2.5
  60. c=$(echo "scale=$pre;(-2.00)" | bc)         ### acorner = -2
  61. k=$(echo "scale=$pre;(-1.25)" | bc)         ### bcorner = -1.25
  62. it=100                                      ### iterations = 100
  63.  
  64. #### SETUP THE COLOR ARRAYS
  65. p[1]="$gry";p[2]="$wht";p[3]="$red";p[4]="$grn";p[5]="$yel"
  66. p[6]="$blu";p[7]="$pur";p[8]="$aqu";p[9]="$wht"
  67.  
  68. nsi=$(echo "scale=$pre;(2.5)" | bc)
  69.  
  70. #### THE MAIN ROUTINE
  71. mandelbrot()
  72. {
  73. #### FILL THE COLOR ARRAY
  74.   x=1;z=0;xx=1
  75.   while ((x < it))
  76.   do
  77.     ((z++))
  78.    if ((z > 9))
  79.     then
  80.       z=1
  81.     fi
  82.     pix["$x"]="${p[$z]}""$xx"
  83.     ((x++));((xx++))
  84.     if ((xx > 9))
  85.     then
  86.       xx=1
  87.     fi
  88.   done
  89.  
  90.   #### AUTO CALCULATE ASPECT RATIO
  91.   ar=$(echo "scale=$pre;($w/$e)/2" | bc)
  92.   gr=$(echo "scale=$pre;($si/($w/$ar))" | bc)
  93.  
  94.   #### MULTIPLIER FOR INTEGER MATH IS 2^27 SO WE USE A 27 BIT SHIFT IN THE MAIN LOOP
  95.   mul=134217728;clear;m=0;n=0;pxl="M";g=`echo "$gr" | awk '{print(int($1*'"$mul"'))}'`
  96.   hr=$(echo "scale=$pre;($si/$e)" | bc);h=`echo "$hr" | awk '{print(int($1*'"$mul"'))}'`
  97.   gcr=$(echo "scale=$pre;(($gr+$c)*$mul)" | bc);gc=`echo "$gcr" | awk '{print(int($1))}'`
  98.   mhkr=$(echo "scale=$pre;(($hr+$k)*$mul)" | bc);mhk=`echo "$mhkr" | awk '{print(int($1))}'`
  99.   ngc="$gc";writexy="tput cup";((mul4 = mul << 2))
  100.  
  101.   #### PRINT ZOOM RATIO, ITERATIONS AND COORDINATES AT LOWER LEFT CORNER OF SCREEN
  102.   mag1=$(echo "scale=$pre;(2.5/$nsi)" | bc);echo -e "$wht"
  103.   mag2=`echo "$mag1" | awk '{print int($0)}'`
  104.   $writexy $((maxy - 3)) 0;echo -n "       ZOOM = $mag2"
  105.   $writexy $((maxy - 2)) 0;echo -n "    ACORNER = $c "
  106.   $writexy $((maxy - 1)) 0;echo -n "    BCORNER = $k "
  107.   $writexy $((maxy - 0)) 0;echo -n " ITERATIONS = $it "
  108.  
  109.   #### THE MAIN LOOP WITH 27 BIT SHIFT
  110.   while ((m < e))
  111.   do
  112.     x=1;tput cup $m $n
  113.     while ((x < it))
  114.     do
  115.       ((v = (a * b) >> 27));((a = (aq - bq) + ngc));((b = (v << 1) + mhk))
  116.       ((aq = (a * a) >> 27));((bq = (b * b) >> 27))
  117.       if ((aq + bq > mul4))
  118.       then
  119.         echo -en ${pix[$x]};((x = it))
  120.       fi
  121.       ((x++))
  122.     done
  123.     a=0;b=0;aq=0;bq=0;((n++));((ngc = ngc + g))
  124.     if ((n > w))
  125.     then
  126.       n=0;((m++));ngc=gc;((mhk = mhk + h))
  127.     fi
  128.   done
  129.   echo -en "$off"
  130. }
  131.  
  132. #### THE ZOOM ROUTINE
  133. zoomin()
  134. {
  135.   zoom=0;x=0;y=0;maxy="$e";maxx="$w";beenhere=0
  136.   read_keys()
  137.   {
  138.     key="";read -sn1 key
  139.     case "$key" in
  140.       A)  ((y--));if ((y < 0));then y=0;fi
  141.           ;;
  142.       B)  ((y++));if ((y > maxy));then ((y--));fi
  143.           ;;
  144.       D)  ((x--));if ((x < 0));then x=0;fi
  145.           ;;
  146.       C)  ((x++));if ((x > maxx));then ((x--));fi
  147.           ;;
  148.       i)  ((it = it + 50));tput cup $maxy 0;echo -en "$red ITERATIONS = $it $off"
  149.           ;;
  150.       z)  ((zoom++));beenhere=1
  151.           ;;
  152.     esac
  153.   }
  154.  
  155.   while ((zoom != 2))
  156.   do
  157.     if ((zoom == 1)) && ((beenhere == 1));then x1="$x";y1="$y";beenhere=0;fi
  158.     if ((zoom == 2)) && ((beenhere == 1));then x2="$x";y2="$y";beenhere=0;zoom=3;fi
  159.     if ((zoom != 2));then read_keys;fi
  160.     if ((beenhere == 0));then tput cup $y $x;echo -en "$wht#$off";fi
  161.   done
  162.  
  163.   X1="$x1";Y1="$y1";X2="$x";Y2="$y";Y1org="$Y1";X1org="$X1";X2org="$X2"
  164.  
  165.   if ((X1 >= X2));then clear;echo;echo "X2 MUST BE GREATER THAN X1";echo;exit;fi
  166.  
  167.   #### DRAW CRAPPY BOX
  168.   ((dif = X2 - X1));xx="$X1";((xxx = xx + dif));tput cup $Y1 $X1
  169.   while ((xx < xxx))
  170.   do
  171.     ((xx++));tput cup $Y1 $xx;echo -en "$wht#$off"
  172.   done
  173.  
  174.   xx="$Y1";((xxx = xx + (dif >> 1)));tput cup $Y1 $X1
  175.   while ((xx < xxx))
  176.   do
  177.     ((xx++));if ((xx > maxy)); then xxx="$maxy";fi
  178.     tput cup $xx $X1;echo -en "$wht#$off"
  179.   done
  180.  
  181.   Y2="$xx";((xx = X1));tput cup $Y2 $X1;((xxx = X1 + dif))
  182.   while ((xx < xxx))
  183.   do
  184.     ((xx++));tput cup $Y2 $xx;echo -en "$wht#$off"
  185.   done
  186.  
  187.   xx="$Y1";((xxx = xx + (dif >> 1)));((X1 = X1 + dif));tput cup $Y1 $X1
  188.   while ((xx < xxx))
  189.   do
  190.     ((xx++));if ((xx > maxy)); then xxx="$maxy";fi
  191.     tput cup $xx $X1;echo -en "$wht#$off"
  192.   done
  193.  
  194.   #### SET COORDINATES FOR ZOOMED IN AREA
  195.   nc=$(echo "scale=$pre;(($X1org*$gr)+$c)" | bc)
  196.   nk=$(echo "scale=$pre;(($Y1org*$hr)+$k)" | bc)
  197.   nsi=$(echo "scale=$pre;(($X2org-$X1org)*$gr)" | bc)
  198.   c="$nc";k="$nk";si="$nsi";ngc=0;mhk=0;gc=0;hk=0
  199.   sleep 1
  200. }
  201.  
  202. #### THE INFINITE LOOP
  203. while [ 1 ]
  204. do
  205.   mandelbrot
  206.   tput cup $maxy 0;echo -en "$grn READY TO ZOOM IN       $off"
  207.   zoomin
  208. done
  209. exit