Page 1 of 4
Drawing rudimentary graphics in text mode
Posted: 03 Jan 2012 23:32
by Aacini
Although graphic applications had been used for years as the "computer standard", text mode may still be used to show interesting graphics (like 25 years ago!). Note that "rudimentary" term refer to the graphics presentation, not to the graphic contents. Batch programs below use Fixed Point arithmetic operations described in
this post.
Let's start with the widely known statistical Bar graphic:
Code: Select all
@echo off
::Statistical Bar Graph drawing
::Antonio Perez Ayala - Jan/03/2012
setlocal EnableDelayedExpansion
set Set1=10 11 12 13 14 15 16 17 18 19 20 21
set Set2=24 22 20 18 16 14 16 18 20 22 24 26
set Set3=24 23 22 21 20 19 18 17 16 15 14 13
set Set4=14 16 18 20 22 24 22 20 18 16 14 12
set Set5=10 10 10 10 10 10 10 10 10 10 10 10
set SetNames=GROWING "DOWN TO UP" SHRINKING "UP TO DOWN" FLAT
set ValueNames=Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
cls
echo/
echo T H I S I S T H E T I T L E O F T H E B A R G R A P H
echo/
call :DrawBarGraph 34 Set SetNames ValueNames
goto :EOF
:DrawBarGraph BarHeight SetsVar SetsNamesVar ValueNamesVar
rem Separate and count SetsVar elements
set /A maxV=0, numJ=9999, i=1
:nextSet
set j=0
for %%v in (!%2%i%!) do (
set /A j+=1
set V%i%.!j!=%%v
if %%v gtr !maxV! set maxV=%%v
)
if %j% lss %numJ% set numJ=%j%
set /A i+=1
if defined %2%i% goto nextSet
set /A numI=i-1
rem Map elements to fit the graph
for /L %%i in (1,1,%numI%) do (
for /L %%j in (1,1,%numJ%) do (
set /A V%%i.%%j=V%%i.%%j * %1 / %maxV%
)
)
rem Show set names
set i=0
for %%c in (█ ░ ▓ ▄ ▒) do (
set /A i+=1
set C!i!=%%c
)
set /A nameWide=(80/(numI+1))/2
set nameSep=
for /L %%n in (1,1,%nameWide%) do set nameSep= !nameSep!
set /P =%nameSep%< NUL
set nameSep=%nameSep%%nameSep%
set /A nameWide*=2, i=0
for %%n in (!%3!) do (
set /A i+=1
set name=%%~n%nameSep%
for %%i in (!i!) do set /P =!C%%i! !name:~0,%nameWide%!< NUL
)
echo/
echo/
echo/
rem Get wide of left margin, bars and separators
set /A barWide=80/(numI*numJ)
if %barWide% gtr 10 set barWide=10
if %barWide% gtr 2 set /A barWide-=1
set /A nameWide=barWide*numI
set /A sepWide=(80-nameWide*numJ)/(numJ-1), leftWide=(80-nameWide*numJ-sepWide*(numJ-1))/2, nameWide+=sepWide
set leftBar=
for /L %%w in (1,1,%leftWide%) do set leftBar= !leftBar!
set sepBar=
for /L %%w in (1,1,%sepWide%) do set sepBar= !sepBar!
rem Draw the Bar Graph
for /L %%v in (%1,-1,1) do (
set /P =%leftBar%< NUL
for /L %%j in (1,1,%numJ%) do (
for /L %%i in (1,1,%numI%) do (
if !V%%i.%%j! geq %%v (
for /L %%w in (1,1,%barWide%) do set /P =!C%%i!< NUL
) else (
for /L %%w in (1,1,%barWide%) do set /P = < NUL
)
)
set /P =%sepBar%< NUL
)
echo/
)
rem Show value names
echo/
set nameSep=
for /L %%n in (1,1,%nameWide%) do set nameSep= !nameSep!
set /P =%leftBar%< NUL
set i=0
for %%n in (!%4!) do (
set /A i+=1
set name=%%~n%nameSep%
for %%i in (!i!) do set /P =!name:~0,%nameWide%!< NUL
)
echo/
exit /B
Note: the characters in this command:
for %%c in (█ ░ ▓ ▄ ▒) do ( are ASCII 219, 220, 176, 177 and 178 that are shown as block characters in the standard Code Page 850.
Results:
Code: Select all
T H I S I S T H E T I T L E O F T H E B A R G R A P H
█ GROWING ░ DOWN TO UP ▓ SHRINKING ▄ UP TO DOWN ▒ FLAT
░
░
░
░▓ ▄ ░ ░
░▓ ▓ ▄ ░ ░
░▓ ▓ ▄ ░ ░
░▓ ░▓ ▓ ▄ ▄ ▄ ░ ░ ░
░▓ ░▓ ▓ ▓ ▄ ▄ ▄ ░ ░ █░
░▓ ░▓ ░▓ ▓▄ ▓▄ ▄ ▄ ▄ ░ ░ █░ █░
░▓ ░▓ ░▓ ▓▄ ▓▄ ▄ ▄ ▄ ░ ░ █░ █░
░▓ ░▓ ░▓ ▓▄ ▓▄ ▓▄ ▄ ▄ ░ █░ █░ █░
░▓ ░▓ ░▓▄ ░▓▄ ▓▄ ▓▄ ▓▄ ░ ▄ █░ ▄ █░ █░ █░
░▓ ░▓ ░▓▄ ░▓▄ ▓▄ ▓▄ ▓▄ █░▓▄ █░ ▄ █░ █░ █░
░▓ ░▓ ░▓▄ ░▓▄ ▓▄ ▓▄ ▓▄ █░▓▄ █░ ▄ █░ █░ █░
░▓ ░▓▄ ░▓▄ ░▓▄ ░▓▄ ▓▄ █░▓▄ █░▓▄ █░▓▄ █░ ▄ █░ █░
░▓ ░▓▄ ░▓▄ ░▓▄ ░▓▄ █ ▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░ █░
░▓▄ ░▓▄ ░▓▄ ░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░
░▓▄ ░▓▄ ░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓
░▓▄ ░▓▄ ░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓
░▓▄ ░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄
░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄ █░▓▄
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
█░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒ █░▓▄▒
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
Re: Drawing rudimentary graphics in text mode
Posted: 03 Jan 2012 23:33
by Aacini
2- We pass now to a more technical matter. The following program use extensive Fixed Point arithmetic operations to graphic a complex algebraic equation: the projection of a 3D-surface on the X-Y plane.
Code: Select all
@echo off
::Floating-point graphics in text mode via integer operations
::Antonio Perez Ayala - Jan/03/2012
setlocal EnableDelayedExpansion
REM Working values: maximum screen coordinates
set /A maxX=67, maxY=40, one=100
call :IntAsFP xLeft=-2.01
call :IntAsFP yTop= 2.00
call :IntAsFP xRight= 2.01
call :IntAsFP yBottom=-2.00
set /A xStep=(xRight-xLeft)/maxX, yStep=(yBottom-yTop)/maxY
cls
echo Graphic of the projection of 3D-surface F(X,Y) = (X^^2+Y^^2)^^5 - ((X^^2-Y^^2)8XY)^^2
echo on Z=0 plane, from (-2.01,2.00) to (2.01,-2.00) coordinates.
set /A Y=yTop-yStep
for /L %%y in (1,1,%maxY%) do (
set /A Y+=yStep, X=xLeft-xStep
for /L %%x in (1,1,%maxX%) do (
set /A X+=xStep,xSqr=X*X/one, ySqr=Y*Y/one, firstTerm=firstTerm1=xSqr+ySqr, secondTerm=(xSqr-ySqr^)*X/one*Y/one*8, secondTerm=secondTerm*secondTerm/one
for /L %%p in (1,1,4) do set /A firstTerm=firstTerm*firstTerm1/one
set /A Z=firstTerm-secondTerm
if !Z! lss 0 (
set /P =*< NUL
) else (
set /P = < NUL
)
)
echo/
)
pause
cls
echo Graphic of the perimeter of previous projection.
echo The result is equivalent to equation R=2*SIN(4*THETA) in polar coordinates.
set /A Y=yTop-yStep
for /L %%y in (1,1,%maxY%) do (
set /A Y+=yStep, X=xLeft-xStep, lastZ=1
for /L %%x in (1,1,%maxX%) do (
set /A X+=xStep,xSqr=X*X/one, ySqr=Y*Y/one, firstTerm=firstTerm1=xSqr+ySqr, secondTerm=(xSqr-ySqr^)*X/one*Y/one*8, secondTerm=secondTerm*secondTerm/one
for /L %%p in (1,1,4) do set /A firstTerm=firstTerm*firstTerm1/one
set /A Z=firstTerm-secondTerm
if !Z! lss 0 (set Z=-1) else set Z=1
set /A lastZ*=Z
if !lastZ! lss 0 (
set /P =*< NUL
) else (
set /P = < NUL
)
set lastZ=!Z!
)
echo/
)
pause
goto :EOF
:IntAsFP Int=FP
set FP=%2
set %1=!FP:.=!
exit /B
Results:
Code: Select all
Graphic of the projection of 3D-surface F(X,Y) = (X^2+Y^2)^5 - ((X^2-Y^2)8XY)^2
on Z=0 plane, from (-2.01,2.00) to (2.01,-2.00) coordinates.
**** ****
******* *******
******** ********
********* *********
********* *********
********** **********
********** **********
********* *********
********** **********
********* *********
*********** ******** ******** ***********
*************** ******* ******* ***************
***************** ****** ****** *****************
****************** *** *** ******************
******************* *******************
**************** ****************
************ ************
**** ****
**** ****
************ ************
**************** ****************
******************* *******************
****************** *** *** ******************
***************** ****** ****** *****************
*************** ******* ******* ***************
*********** ******** ******** ***********
********* *********
********** **********
********* *********
********** **********
********** **********
********* *********
********* *********
******** ********
******* *******
**** ****
Press any key to continue . . .
Graphic of the perimeter of previous projection.
The result is equivalent to equation R=2*SIN(4*THETA) in polar coordinates.
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
Press any key to continue . . .
Re: Drawing rudimentary graphics in text mode
Posted: 03 Jan 2012 23:34
by Aacini
3- Had you seen fractal graphics? The Mandelbrot Set is drawn on a complex plane of Z=X+iY coordinates. At each (X0,Y0) point, Zn+1=Zn^2-Z0 (Xn+1=Xn^2-Yn^2-X0)+i(Yn+1=2*Xn*Yn-Y0) is iterated until |Z|=SQRT(X^2+Y^2) is greater than 2; the
number of iterations gives the
color of that point. If |Z| don't exceed 2 after a certain limit of iterations, point color remains black. Easy, isn't it? The Mandelbrot Set fractal graphic is customarily drawn between (-1.00,1.25) and (2.00,-1.25) coordinates; the version below show different letters instead of colors.
Code: Select all
@echo off
::Mandelbrot Set graphic in text mode
::Antonio Perez Ayala - Jan/03/2012
setlocal EnableDelayedExpansion
REM Working values: maximum screen coordinates and iteration level
set /A maxX=78, maxY=42, maxLevel=26, one=10000
call :IntAsFP xLeft=-1.0000
call :IntAsFP yTop= 1.1250
call :IntAsFP xRight= 2.0000
call :IntAsFP yBottom=-1.1250
set /A xStep=(xRight-xLeft)/maxX, yStep=(yBottom-yTop)/maxY, four=4*one
set showChars=A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
set "showChar[0]= "
set i=0
for %%c in (%showChars%) do (
set /A i+=1
set showChar[!i!]=%%c
)
cls
set /A yPos=yTop-yStep
for /L %%y in (0,1,%maxY%) do (
set /A yPos+=yStep, xPos=xLeft-xStep
for /L %%x in (0,1,%maxX%) do (
set /A xPos+=xStep, xIter=xPos, yIter=yPos, xSquare=xIter*xIter/one, ySquare=yIter*yIter/one, root=xSquare+ySquare
set level=0
for /L %%i in (1,1,%maxLevel%) do (
if !level! == 0 (
if !root! lss %four% (
set /A yIter=2*xIter*yIter/one-yPos, xIter=xSquare-ySquare-xPos, xSquare=xIter*xIter/one, ySquare=yIter*yIter/one, root=xSquare+ySquare
) else (
set level=%%i
)
rem noelse
)
)
for %%l in (!level!) do set /P =!showChar[%%l]!< NUL
)
)
echo/
)
goto :EOF
:IntAsFP Int=FP
set FP=%2
set %1=!FP:.=!
exit /B
Result:
Code: Select all
BBBBBBBBBBBBBBBBBBBCCCCCDDDDEEEFEDDDDDCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBAAAAAAAAA
BBBBBBBBBBBBBBBBCCCCCCDDDDDEFFHIFEEDDDDDGCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBAAAAAAAA
BBBBBBBBBBBBBBCCCCCCDDDDDEGHGINIFEEEDDDDDDDDCCCCCCCCCCCCCCCCCCCFEBBBBBBAAAAAAAA
BBBBBBBBBBBBBCCCCCDDDDDDEFGISSJHGFEEEDDDDDDDDDCCCCCCCCCCCCCCCCCCEDEBBBBBAAAAAAA
BBBBBBBBBBBCCCCCCDDDDDDEEFGIMYSIHGFEEEDDDDDDDDDCCCCCCCCCCCCCCCCCCDEFBBBBBAAAAAA
BBBBBBBBBBCCCCCCDDDDDEEEFHMK UQXNHFEEEEDDDDDDDDDCCCCCCCCCCCCCCCCCDFDEBBBBAAAAA
BBBBBBBBCCCCCCCDDDDEEEEFGIR KHGFFFEEEDDDDDDDDDCCCCCCCCCCCCCCCCCDEGBBBAAAAA
BBBBBBBCCCCCCCDDDEEEEFFGGI HHGGFFFFEEDDDDDDDDCCCCCCCCCCCCCCCCCCCDBBBAAAA
BBBBBBCCCCCCCDDEFJGFFGHIIJM LJIIHHHJHHFEEDDDDDDDDCCCCCCCCCCCCCCCCCCCBBAAAA
BBBBBCCCCCCCCDEFH IHHI UQ ZKKMRUJGFEEEEEDDDDDDCCCCCCCCCCCCCCCCCCBBAAA
BBBBCCCCCCCCDDEGMVQ MR Y OJGFFFEEEEEEDDDDDCCCCCCCCCCCCCCCCCBAAA
BBBBCCCCCCCCDEEFIO NJHGFFFEEEEEEEEEDDDCCCCCCCCCCCCCCCBBAA
BBBCCCCCCCCDDEEFHK MXKGFFFFEEEEEEEEEDDDCCCCCCCCCCCCCCBAA
BBBCCCCCCCCDDEFGH MIGGGFFFFFFFFFFHGEDDDDCCCCCCCCCCCAA
BBCCCCCCCCDDDEILT WJHHGGGGHKHGGHHLFFEEDDDDDDCCCCCCCBA
BBCCCCCCCCDDDFHN LJIIISJORJJVNNKGFEEEEDDDDDDDCCCCBA
BCCCCCCCCDDDDEGI QKKKN X UVY OKIGGFEEEEDDDDDDDECCCA
BCCCCCCCCDDDDEG NN RLJGGGEEEEEEDDDDDDFFCA
BCCCCCCCCDDDDEFHU R MJPHIFEEEEEDDDDDDDCA
BCCCCCCCCDDDDEFGS PMLMJHGFFFFEDDDDDDDB
BCCCCCCCCDDDDEEFGM QLIHGGFFGGJHFHEED
BCCCCCCCCDDDDEEFGHKT URROONM MJKJJG
BCCCCCCCCDDDDEEFGL ROJHHIGFGGJHFHEED
BCCCCCCCCDDDDEEGT PMLNJHGFFFFFEDDDDDDC
BCCCCCCCCDDDDEFH S MJIHJFEEEEEDDDDDDDDA
BCCCCCCCCDDDDEG NN QLJGGGEEEEEEDDDDDDDECA
BCCCCCCCCDDDDEGI PKKKQ VU PKIGGFEEEEHDDDDDDJCCCA
BBCCCCCCCCDDDFHN WLJIII KPPKJ OPKGFEEEEDDDDDDDCCCCCA
BBCCCCCCCCDDDEIMU KHHGGGHHLHGGHIKFFEEDDDDDDCCCCCCCBA
BBBCCCCCCCCDDEFHI LIHGGFFFFFFFFFFHGEDDDDCCCCCCCCCCCAA
BBBCCCCCCCCDDEFFHJ M LGFFFFEEEEEEEEEEDDCCCCCCCCCCCCCCBAA
BBBBCCCCCCCCDEEFIO NJHGFFFEEEEEEEEEDDDCCCCCCCCCCCCCCCBBAA
BBBBCCCCCCCCDDEGM R NS X OJGFFFEEEEEEDDDDDCCCCCCCCCCCCCCCCCBAAA
BBBBBCCCCCCCCDEFHPIHHI WQ XLK RUJGFEEEEEDDDDDDCCCCCCCCCCCCCCCCCCBBAAA
BBBBBBCCCCCCCDDEFIGFFGHIIJM LJIIHHIKHIFEEEDDDDDDDCCCCCCCCCCCCCCCCCCCBBAAAA
BBBBBBBCCCCCCCDDDEEEFFFGGI RIHGGFFFFEEDDDDDDDDCCCCCCCCCCCCCCCCCCCCBBBAAAA
BBBBBBBBCCCCCCCDDDDEEEEFGIQ KHGFFFEEEDDDDDDDDDCCCCCCCCCCCCCCCCCIEIBBBAAAAA
BBBBBBBBBBCCCCCCDDDDDEEEFHRKU U URHFEEEEDDDDDDDDDCCCCCCCCCCCCCCCCCDEFGBBBBAAAAA
BBBBBBBBBBBCCCCCCDDDDDDEEFGIMV IHGFEEEDDDDDDDDDECCCCCCCCCCCCCCCCCEFHBBBBBAAAAAA
BBBBBBBBBBBBBCCCCCDDDDDDEFGIOQJHGFEEEDDDDDDDDDCCCCCCCCCCCCCCCCCCEDEBBBBBAAAAAAA
BBBBBBBBBBBBBBCCCCCCDDDDDEGJHIMHFEEEDDDDDDDDCCCCCCCCCCCCCCCCCCCDGBBBBBBAAAAAAAA
BBBBBBBBBBBBBBBBCCCCCCDDDDEEFFIIFEEDDDDDECCCCCCCCCCCCCCCCCCCCCCBBBBBBBBAAAAAAAA
BBBBBBBBBBBBBBBBBBBCCCCCDDDDEEEFFDDDDDDCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBAAAAAAAAA
Re: Drawing rudimentary graphics in text mode
Posted: 05 Jan 2012 09:31
by jeb
Hi Aacini,
very impressive
But works only with XP, as Vista and Win7 have a feature in the SET/p output.
Trailing whitespaces will be removed.
I changed the Mandelbrot to real colors, looks really fine now.
Code: Select all
@echo off
@echo off
SETLOCAL EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set "DEL=%%a"
)
::Mandelbrot Set graphic in text mode
::Antonio Perez Ayala - Jan/03/2012
setlocal EnableDelayedExpansion
REM Working values: maximum screen coordinates and iteration level
set /A maxX=78, maxY=42, maxLevel=26, one=10000
call :IntAsFP xLeft=-1.0000
call :IntAsFP yTop= 1.1250
call :IntAsFP xRight= 2.0000
call :IntAsFP yBottom=-1.1250
set /A xStep=(xRight-xLeft)/maxX, yStep=(yBottom-yTop)/maxY, four=4*one
set showChars=A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
set "showChar[0]=."
set "Xcolor=01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21"
set i=0
for %%c in (%showChars%) do (
set /A i+=1
set showChar[!i!]=%%c
)
cls
set /A yPos=yTop-yStep
for /L %%y in (0,1,%maxY%) do (
set /A yPos+=yStep, xPos=xLeft-xStep
for /L %%x in (0,1,%maxX%) do (
set /A xPos+=xStep, xIter=xPos, yIter=yPos, xSquare=xIter*xIter/one, ySquare=yIter*yIter/one, root=xSquare+ySquare
set level=0
for /L %%i in (1,1,%maxLevel%) do (
if !level! == 0 (
if !root! lss %four% (
set /A yIter=2*xIter*yIter/one-yPos, xIter=xSquare-ySquare-xPos, xSquare=xIter*xIter/one, ySquare=yIter*yIter/one, root=xSquare+ySquare
) else (
set level=%%i
)
rem noelse
)
)
rem for %%l in (!level!) do set /P =!showChar[%%l]!< NUL
set /a col=level*3
call :ColorText !col! "#"
)
echo(
)
goto :EOF
:IntAsFP Int=FP
set FP=%2
set %1=!FP:.=!
exit /B
:ColorText
echo off
set color=!Xcolor:~%1,2!
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%color% /R "^$" "%~2" nul
del "%~2" > nul 2>&1
goto :eof
jeb
Re: Drawing rudimentary graphics in text mode
Posted: 05 Jan 2012 23:30
by Aacini
Jeb: that is awesome!
Mandelbrot Set color bands in the "sea" becomes narrow as we approach to the "land" (the black area). To compensate for this effect, several bands must be joined in the same color as the iteration level increases.
I wrote a very small and fast program to show text in color I called COLORMSG to differentiate it from your COLORTEXT. It is a .COM file with just 181 bytes in size, so it run much faster than other methods that do the same thing. Here it is:
³2ÿŠOÿ2íã9‹û° üó®tQã~ŠEÿ³$þÇS³ÿãën€= tsÐàÐàÐàÐàŠàGŠEÿ³<Sëq³A€/!+ÄIãN2äP¸""ò®uDãB‹÷‹Ñò®u@J:%u;GIuó+Ñt-‹Ê³|€/!³†€/![° ´*€ì!Í1²"¬´/€ì!Í1:Âu—Šâ:$u‘Fâë2À´LÍ!ëÇë¦,0Ã<Arù²ùöÚ*Âëñ<arð, ëì
Just take the previous 181 bytes and store they in a file called COLORMSG.COM; you may first create COLORMSG.TXT and then do a REN COLORMSG.TXT COLORMSG.COM. Note that file contents must be comprised of a long string 181 bytes size with no line breaks, but that have white spaces in positions 15, 39, 118 and 179. The color graphic is drawn even faster if the DOS-Window is maximized with Alt-Enter key.
This is my version of Mandelbrot Set in color:
Code: Select all
@echo off
::Mandelbrot Set graphic in text mode in COLOR
::Antonio Perez Ayala
setlocal EnableDelayedExpansion
REM Working values: maximum screen coordinates and iteration level
set /A maxX=78, maxY=42, maxLevel=26, one=10000
call :IntAsFP xLeft=-1.0000
call :IntAsFP yTop= 1.1250
call :IntAsFP xRight= 2.0000
call :IntAsFP yBottom=-1.1250
set /A xStep=(xRight-xLeft)/maxX, yStep=(yBottom-yTop)/maxY, four=4*one
set showChars=█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ ▓ ▓ ▒ ▒ ▒ ░ ░ ░ ░
set showColors=1 2 3 4 5 6 7 8 9 A B C C D D D D E E E E E E E E E
set "showChar[0]= "
set i=0
for %%c in (%showChars%) do (
set /A i+=1
set showChar[!i!]=%%c
)
set showColor[0]=0
set i=0
for %%c in (%showColors%) do (
set /A i+=1
set showColor[!i!]=%%c
)
cls
set /A yPos=yTop-yStep
for /L %%y in (0,1,%maxY%) do (
set /A yPos+=yStep, xPos=xLeft-xStep
for /L %%x in (0,1,%maxX%) do (
set /A xPos+=xStep, xIter=xPos, yIter=yPos, xSquare=xIter*xIter/one, ySquare=yIter*yIter/one, root=xSquare+ySquare
set level=0
for /L %%i in (1,1,%maxLevel%) do (
if !level! == 0 (
if !root! lss %four% (
set /A yIter=2*xIter*yIter/one-yPos, xIter=xSquare-ySquare-xPos, xSquare=xIter*xIter/one, ySquare=yIter*yIter/one, root=xSquare+ySquare
) else (
set level=%%i
)
rem noelse
)
)
for %%l in (!level!) do ColorMsg !showColor[%%l]! "!showChar[%%l]!"
)
echo/
)
goto :EOF
:IntAsFP Int=FP
set FP=%2
set %1=!FP:.=!
exit /B
You may review the result generated
here; that image took 1 minute 42 seconds with the DOS window maximized via Alt-Enter.
Antonio
Re: Drawing rudimentary graphics in text mode
Posted: 06 Jan 2012 10:31
by Squashman
This is some cool stuff. Didn't realize you could change the color like that. I always assumed it was an all or nothing.
Re: Drawing rudimentary graphics in text mode
Posted: 06 Jan 2012 20:27
by Aacini
I just realized that the definition of ColorMsg.com auxiliary program may be included in the Batch file. At beginning of the Batch file include this line:
Code: Select all
if not exist ColorMsg.com call :DefineColorMsg
And at the end:
Code: Select all
:DefineColorMsg
setlocal DisableDelayedExpansion
set ColorMsg=³2ÿŠOÿ2íã9‹û° üó®tQã~ŠEÿ³$þÇS³ÿãën€= tsÐàÐàÐàÐàŠàGŠEÿ³^<Sëq³A€/!+ÄIãN2äP¸""ò®uDãB‹÷‹Ñò®u^@J:%%u;GIuó+Ñt-‹Ê³^|€/!³†€/![° ´*€ì!Í1²"¬´/€ì!Í1:Âu—Šâ:$u‘Fâë2À´LÍ!ëÇë¦,0Ã<Arù²ùöÚ*Âëñ<arð, ëì
setlocal EnableDelayedExpansion
echo !ColorMsg!> ColorMsg.com
exit /B
This way, the Batch file may be distributed with no additional instructions on create the auxiliary programs. Interesting, isn't it?
A
VERY INTERESTING IDEA that crossed my mind is that ColorMsg variable above
contains executable code in .COM file image format; that means, it represent a MACHINE LANGUAGE MACRO
I am looking for a method to execute it!!!!!!!!!!
Re: Drawing rudimentary graphics in text mode
Posted: 07 Jan 2012 08:28
by dbenham
There are pitfalls when posting code containing non-ASCII characters (code > 128) on this site. I ran into this when I tried to post a solution for a
"Universal" date parser.
Dave Benham
Re: Drawing rudimentary graphics in text mode
Posted: 07 Jan 2012 09:55
by aGerman
I was able to copy the right characters from Aacinis code. But I should mention that the days of com files are numbered. They are 16 Bit applications and won't work on 64 Bit Systems.
Regards
aGerman
Re: Drawing rudimentary graphics in text mode
Posted: 11 Apr 2012 00:53
by Ed Dyreen
'
Too bad, with me on XP
$bs translates to a dot, not sure why, tried several codepages...
Code: Select all
@echo off &setlocal enableDelayedExpansion
for /f "delims=#" %%? in (
'"prompt #$H# &echo on &for %%? in (1) do rem"'
) do set "$BS=%%?"
echo.failed%$BS%%$BS%%$BS%%$BS%%$BS%%$BS%$bs
call :ColorText 0C "#"
call :ColorText 0B "#"
pause
exit /b 0
:ColorText
:: (
> "%~2" (echo.h%$BS%%$BS%h)
findstr /v /a:%~1 /R "^$" "%~2" nul
:: )
exit /b 0
Code: Select all
$bs
#:h. .. .h
#:h. .. .h
Druk op een toets om door te gaan. . .
Re: Drawing rudimentary graphics in text mode
Posted: 11 Apr 2012 14:00
by tonysathre
Wow this is really cool stuff. Writing out color with findstr is nice a trick.
Tony
Re: Drawing rudimentary graphics in text mode
Posted: 11 Apr 2012 14:49
by foxidrive
jeb wrote:Hi Aacini,
very impressive
But works only with XP, as Vista and Win7 have a feature in the SET/p output.
Trailing whitespaces will be removed.
I changed the Mandelbrot to real colors, looks really fine now.
This is nice work from you guys.
jeb, when I run yours the screen width seems to be around 500 characters wide. What am I doing wrong? Running XP Pro here.
I mean my console window is 80 x 35 or so but what displays looks nothing like a mandlebrot.
I added this and it still seems odd.
mode con: cols=120 lines=80
Re: Drawing rudimentary graphics in text mode
Posted: 11 Apr 2012 20:26
by Liviu
jeb wrote:I changed the Mandelbrot to real colors, looks really fine now.
Neat! Thanks for sharing.
Wasn't aware of (or paying attention to) findstr's /A option. Note to myself: get into the habit of browsing to
http://www.dostips.com/DosCommandIndex.php more often, and search for uncommon words such as "color"
foxidrive wrote:jeb, when I run yours the screen width seems to be around 500 characters wide. What am I doing wrong? Running XP Pro here.
Try pre-setting the console at the smallest allowed Lucida Console font, and a screen width of 400+.
Liviu
Re: Drawing rudimentary graphics in text mode
Posted: 12 Apr 2012 13:58
by Ed Dyreen
'
I'm pleased y'all got it working, still have no idea why the
$bs doen't work with me in jeb's solution, I don't like to use Aacini's .COM file, cause it won't stand in time without having to be rewritten. But don't let it stop you from writing witchCraft Aacini, I like the ability to choose
Re: Drawing rudimentary graphics in text mode
Posted: 12 Apr 2012 17:50
by jeb
@Ed and @foxidrive and all other XP-users
Yes it fails, as XP seems to use a different findstr.
The findstr does not print the backspace character instead it replace it with a dot.
I made a special "hotfix" for XP-only, I echo the backspace 4 times to remove the ":. ." characters.
Code: Select all
@echo off
::Mandelbrot Set graphic in text mode
::Antonio Perez Ayala - Jan/03/2012
SETLOCAL EnableDelayedExpansion
set "DisplayChar=#"
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set "DEL=%%a"
)
<nul set /p ".=%DEL%" > "DisplayChar"
setlocal EnableDelayedExpansion
REM Working values: maximum screen coordinates and iteration level
set /A maxX=78, maxY=42, maxLevel=26, one=10000
call :IntAsFP xLeft=-1.0000
call :IntAsFP yTop= 1.1250
call :IntAsFP xRight= 2.0000
call :IntAsFP yBottom=-1.1250
set /A xStep=(xRight-xLeft)/maxX, yStep=(yBottom-yTop)/maxY, four=4*one
set showChars=A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
set "showChar[0]=."
set "Xcolor=01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21"
set i=0
for %%c in (%showChars%) do (
set /A i+=1
set showChar[!i!]=%%c
)
cls
set /A yPos=yTop-yStep
for /L %%y in (0,1,%maxY%) do (
set /A yPos+=yStep, xPos=xLeft-xStep
for /L %%x in (0,1,%maxX%) do (
set /A xPos+=xStep, xIter=xPos, yIter=yPos, xSquare=xIter*xIter/one, ySquare=yIter*yIter/one, root=xSquare+ySquare
set level=0
for /L %%i in (1,1,%maxLevel%) do (
if !level! == 0 (
if !root! lss %four% (
set /A yIter=2*xIter*yIter/one-yPos, xIter=xSquare-ySquare-xPos, xSquare=xIter*xIter/one, ySquare=yIter*yIter/one, root=xSquare+ySquare
) else (
set level=%%i
)
rem noelse
)
)
rem for %%l in (!level!) do set /P =!showChar[%%l]!< NUL
set /a col=level*3
call :ColorText !col! !DisplayChar!
)
echo(
)
goto :EOF
:IntAsFP Int=FP
set FP=%2
set %1=!FP:.=!
exit /B
:ColorText
echo off
set "color=!Xcolor:~%1,2!"
findstr /v /a:%color% /R "^$" "%~2" nul
type #
type #
type #
type #
goto :eof
One of my next goals is to use multiple threads for the mandelbrot.
So on a Core-I7 it could be 8 times faster.
jeb