Dragon Curve using L-System

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
IcarusLives
Posts: 175
Joined: 17 Jan 2016 23:55

Dragon Curve using L-System

#1 Post by IcarusLives » 08 Jun 2018 21:18

Hello, I recently learned about L-Systems, and have created a dragon curve. There are many other visualizations that I got from http://paulbourke.net/fractals/lsys/.

Please enjoy :)

F + - [ ] are the characters
and each character does 1 thing
F : Move forward
+ : Rotate Right
- : Rotate Left
[ : PUSH , save current location
] : POP , return to saved location

This 8k+ long string are the instructions and the L-System reads the informations and does things accordingly

Image

FIXED a bug where length wasn't being read properly, resulting in a incorrect "sentenceLength"

WINDOWS 10 ONLY because of VT100 support.
Dragon Curve

Code: Select all

@echo off & setlocal enableDelayedExpansion & mode 100,100

call :turtleGraphics

set /a "turtleX=50", "turtleY=75", "turtleAngle=0"

set "axiom=FX"
set "var[1]=X"
set "var[2]=Y"
set "var[3]="
set "rule[1]=X+YF+"
set "rule[2]=-FX-Y"
set "rule[3]="
set "angle=90"
set "generations=10"



call :generations %generations%

set "axiom=!axiom:X=!"
set "axiom=!axiom:Y=!"

rem visualize L-System
call :length "!axiom!" sentenceLength
echo %sentenceLength%

for /l %%i in (0,1,!sentenceLength!) do ( set "current=!axiom:~%%i,1!"

	rem Change rules according to your L-System
	rem read the instructions, and do certain things depending on the instruction.
	if "!current!" equ "F" (
		%forward% 1
	) else if "!current!" equ "G" (
		for /l %%a in (1,1,2) do %forward_ND% 1
	) else if "!current!" equ "-" (
		%turnRight% %angle%
	) else if "!current!" equ "+" (
		%turnLeft% %angle%
	) else if "!current!" equ "[" (
		set /a "savedX=turtleX", "savedY=turtleY"
	) else if "!current!" equ "]" (
		set /a "turtleX=savedX", "turtleY=savedY"
	)
	
	
	rem display everything
	REM cls & echo=!canvas!
	<nul set /p "=!screen!" & set "screen="
)
pause > nul & exit

:generations
rem create a list of instructions generations of mutated axiom using %rule%
for /l %%a in (0,1,%~1) do (
	set "sentenceLength=0"
	call :length "!axiom!" sentenceLength
	set "nextSentence="
	for /l %%i in (0,1,!sentenceLength!) do (
		set "current=!axiom:~%%i,1!"
		if "!current!" equ "%var[1]%" (
			set "nextSentence=!nextSentence!%rule[1]%"
		) else if "!current!" equ "%var[2]%" (
			set "nextSentence=!nextSentence!%rule[2]%"
		) else if "!current!" equ "%var[3]%" (
			set "nextSentence=!nextSentence!%rule[3]%"
		) else (
			set "nextSentence=!nextSentence!!current!"
		)
	)
	set "axiom=!nextSentence!"
)
goto :eof

:length
(   
    setlocal
    set "s=%~1#"
    set "len=0"
    for %%P in (8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
      if "!s:~%%P,1!" NEQ "" ( 
      set /a "len+=%%P"
      set "s=!s:~%%P!"
      )
    )
)
( 
    endlocal
    set "%~2=%len%"
    exit /b
)
goto :eof

:turtleGraphics
	set /a "wid=100", "hei=100", "heiXwid=hei * wid"
	for /l %%a in (1,1,%heiXwid%) do set "canvas=!canvas! "
	mode con: cols=%wid% lines=%hei%

set ^"LF=^

^" Above empty line is required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
for /F %%a in ('echo prompt $E^| cmd') do set "ESC=%%a"
<nul set /p "=%esc%[?25l"

set plot=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-3" %%1 in ("^!args^!") do (%\n%
    set /a "_x=%%~1 + (%%~2 * wid)", "_y=1 + %%~1 + (%%~2 * wid)"%\n%
    for /f "tokens=1-3" %%a in ("^!_x^! ^!_y^! ^!heiXwid^!") do set "canvas=^!canvas:~0,%%a^!%%~3^!canvas:~%%b,%%c^!"%\n%
)) else set args=

set plot=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-4" %%1 in ("^!args^!") do (%\n%
	set "screen=^!screen^!!esc![%%2;%%1H!esc![38;5;%%3m%%~4!esc![0m"%\n%
)) else set args=

rem forward distance
set forward=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1" %%1 in ("^!args^!") do (%\n%
	set /a "turtleX+=(%%~1 + 1) * ^!cos(x):x=turtleAngle^!", "turtleY+=(%%~1 + 1) * ^!sin(x):x=turtleAngle^!"%\n%
	for /f "tokens=1,2" %%a in ("^!turtleX^! ^!turtleY^!") do ^!plot^! %%a %%b 255 Û%\n%
)) else set args=

rem forward_ND distance
set forward_ND=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1" %%1 in ("^!args^!") do (%\n%
	set /a "turtleX+=(%%~1 + 1) * ^!cos(x):x=turtleAngle^!", "turtleY+=(%%~1 + 1) * ^!sin(x):x=turtleAngle^!"%\n%
)) else set args=

rem turnLeft DEGREES(0-360)
set turnLeft=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1" %%1 in ("^!args^!") do (%\n%
	set /a "turtleAngle-=(%%~1)"%\n%
)) else set args=

rem turnRight DEGREES(0-360)
set turnRight=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1" %%1 in ("^!args^!") do (%\n%
	set /a "turtleAngle+=(%%~1)"%\n%
)) else set args=

rem math functions
	set "_SIN=a-a*a/1920*a/312500+a*a/1920*a/15625*a/15625*a/2560000-a*a/1875*a/15360*a/15625*a/15625*a/16000*a/44800000"
    set "SIN(x)=(a=(x * 31416 / 180)%%62832, c=(a>>31|1)*a, a-=(((c-47125)>>31)+1)*((a>>31|1)*62832)  +  (-((c-47125)>>31))*( (((c-15709)>>31)+1)*(-(a>>31|1)*31416+2*a)  ), %_SIN%) / 10000"
	set "COS(x)=(a=(15708 - x * 31416 / 180)%%62832, c=(a>>31|1)*a, a-=(((c-47125)>>31)+1)*((a>>31|1)*62832)  +  (-((c-47125)>>31))*( (((c-15709)>>31)+1)*(-(a>>31|1)*31416+2*a)  ), %_SIN%) / 10000"
    set "_SIN="
goto :eof
HILBERT CURVE
Image

Code: Select all

@echo off & setlocal enableDelayedExpansion & mode 100,100

call :turtleGraphics

set /a "turtleX=0", "turtleY=0", "turtleAngle=0"

set "axiom=X"
set "var[1]=X"
set "var[2]=Y"
set "var[3]="
set "rule[1]=-YF+XFX+FY-"
set "rule[2]=+XF-YFY-FX+"
set "rule[3]="
set "angle=90"
set "generations=4"



call :generations %generations%

set "axiom=!axiom:X=!"
set "axiom=!axiom:Y=!"

rem visualize L-System
call :length "!axiom!" sentenceLength
echo %sentenceLength%

for /l %%i in (0,1,!sentenceLength!) do ( set "current=!axiom:~%%i,1!"

	rem Change rules according to your L-System
	rem read the instructions, and do certain things depending on the instruction.
	if "!current!" equ "F" (
		for /l %%a in (1,1,2) do %forward% 1
	) else if "!current!" equ "G" (
		for /l %%a in (1,1,2) do %forward_ND% 1
	) else if "!current!" equ "-" (
		%turnRight% %angle%
	) else if "!current!" equ "+" (
		%turnLeft% %angle%
	) else if "!current!" equ "[" (
		set /a "savedX=turtleX", "savedY=turtleY"
	) else if "!current!" equ "]" (
		set /a "turtleX=savedX", "turtleY=savedY"
	) else if "!current!" equ "." (
		%turnLeft% 180
	)
	
	
	rem display everything
	REM cls & echo=!canvas!
	<nul set /p "=!screen!" & set "screen="
)
pause > nul & exit

:generations
rem create a list of instructions generations of mutated axiom using %rule%
for /l %%a in (0,1,%~1) do (
	set "sentenceLength=0"
	call :length "!axiom!" sentenceLength
	set "nextSentence="
	for /l %%i in (0,1,!sentenceLength!) do (
		set "current=!axiom:~%%i,1!"
		if "!current!" equ "%var[1]%" (
			set "nextSentence=!nextSentence!%rule[1]%"
		) else if "!current!" equ "%var[2]%" (
			set "nextSentence=!nextSentence!%rule[2]%"
		) else if "!current!" equ "%var[3]%" (
			set "nextSentence=!nextSentence!%rule[3]%"
		) else (
			set "nextSentence=!nextSentence!!current!"
		)
	)
	set "axiom=!nextSentence!"
)
goto :eof

:length
(   
    setlocal
    set "s=%~1#"
    set "len=0"
    for %%P in (8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
      if "!s:~%%P,1!" NEQ "" ( 
      set /a "len+=%%P"
      set "s=!s:~%%P!"
      )
    )
)
( 
    endlocal
    set "%~2=%len%"
    exit /b
)
goto :eof

:turtleGraphics
	set /a "wid=100", "hei=100", "heiXwid=hei * wid"
	for /l %%a in (1,1,%heiXwid%) do set "canvas=!canvas! "
	mode con: cols=%wid% lines=%hei%

set ^"LF=^

^" Above empty line is required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
for /F %%a in ('echo prompt $E^| cmd') do set "ESC=%%a"
<nul set /p "=%esc%[?25l"

set plot=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-3" %%1 in ("^!args^!") do (%\n%
    set /a "_x=%%~1 + (%%~2 * wid)", "_y=1 + %%~1 + (%%~2 * wid)"%\n%
    for /f "tokens=1-3" %%a in ("^!_x^! ^!_y^! ^!heiXwid^!") do set "canvas=^!canvas:~0,%%a^!%%~3^!canvas:~%%b,%%c^!"%\n%
)) else set args=

set plot=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-4" %%1 in ("^!args^!") do (%\n%
	set "screen=^!screen^!!esc![%%2;%%1H!esc![38;5;%%3m%%~4!esc![0m"%\n%
)) else set args=

rem forward distance
set forward=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1" %%1 in ("^!args^!") do (%\n%
	set /a "turtleX+=(%%~1 + 1) * ^!cos(x):x=turtleAngle^!", "turtleY+=(%%~1 + 1) * ^!sin(x):x=turtleAngle^!"%\n%
	for /f "tokens=1,2" %%a in ("^!turtleX^! ^!turtleY^!") do ^!plot^! %%a %%b 255 Û%\n%
)) else set args=

rem forward_ND distance
set forward_ND=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1" %%1 in ("^!args^!") do (%\n%
	set /a "turtleX+=(%%~1 + 1) * ^!cos(x):x=turtleAngle^!", "turtleY+=(%%~1 + 1) * ^!sin(x):x=turtleAngle^!"%\n%
)) else set args=

rem turnLeft DEGREES(0-360)
set turnLeft=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1" %%1 in ("^!args^!") do (%\n%
	set /a "turtleAngle-=(%%~1)"%\n%
)) else set args=

rem turnRight DEGREES(0-360)
set turnRight=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1" %%1 in ("^!args^!") do (%\n%
	set /a "turtleAngle+=(%%~1)"%\n%
)) else set args=

rem math functions
	set "_SIN=a-a*a/1920*a/312500+a*a/1920*a/15625*a/15625*a/2560000-a*a/1875*a/15360*a/15625*a/15625*a/16000*a/44800000"
    set "SIN(x)=(a=(x * 31416 / 180)%%62832, c=(a>>31|1)*a, a-=(((c-47125)>>31)+1)*((a>>31|1)*62832)  +  (-((c-47125)>>31))*( (((c-15709)>>31)+1)*(-(a>>31|1)*31416+2*a)  ), %_SIN%) / 10000"
	set "COS(x)=(a=(15708 - x * 31416 / 180)%%62832, c=(a>>31|1)*a, a-=(((c-47125)>>31)+1)*((a>>31|1)*62832)  +  (-((c-47125)>>31))*( (((c-15709)>>31)+1)*(-(a>>31|1)*31416+2*a)  ), %_SIN%) / 10000"
    set "_SIN="
goto :eof

Post Reply