Page 1 of 1

3D Cube Orthographic Projection

Posted: 21 Jan 2024 15:26
by IcarusLives
Hello everyone,

I'm more than certain you guys at dostips could find ways to improve this, but I'm still happy to share :mrgreen:

References:
https://en.wikipedia.org/wiki/Orthographic_projection
https://en.wikipedia.org/wiki/Rotation_matrix


Update: Allows use of TAB key to quit, uses %esc% captured via prompt parse, instead of key, used deltaTime to demonstrate (maybe this not so good on all pc's, please let me know)

Code: Select all

@echo off & setlocal enableDelayedExpansion

if "%~1" neq "" goto :%~1

call :macro

set "points=-1" & for %%i in ( "-1 -1 -1" " 1 -1 -1" " 1  1 -1" "-1  1 -1" "-1 -1  1" " 1 -1  1" " 1  1  1" "-1  1  1") do (
	set /a "points+=1"
	for /f "tokens=1-3" %%x in ("%%~i") do (
		set /a "x[!points!]=%%~x, y[!points!]=%%~y, z[!points!]=%%~z"
	)
)

set /a "boxSize=15", "rotationSpeed=1", "wid=hei=90"
mode %wid%,%hei%

title {TAB} to QUIT

"%~F0" Controller >"%temp%\%~n0_signal.txt" | "%~F0" Engine <"%temp%\%~n0_signal.txt"
exit

:Engine
for /l %%# in () do (

	for /f "tokens=1-4 delims=:.," %%a in ("!time: =0!") do ( set /a "t1=((((1%%a-1000)*60+(1%%b-1000))*60+(1%%c-1000))*100)+(1%%d-1000)"   )
	if defined t2 ( set /a "deltaTime=(t1 - t2)"  )
	set /a "t2=t1"
	
	set "NewKey=" & set /p "NewKey="
	if /i "!newKey!" equ "quit" ( exit )
	
	set /a "angle+=rotationSpeed * deltaTime"
	
	for /l %%i in (0,1,7) do ( set /a ^
		       "px[%%i]=0", "py[%%i]=0",^
		       "x=x[%%i] * boxSize, y=y[%%i] * boxSize, z=z[%%i] * boxSize",^
		       "%rotY%", "x=ryx, y=ryy, z=ryz",^
		       "%rotX%", "x=rxx, y=rxy, z=rxz",^
		       "%rotZ%", "%projection:?=Z%",^
		       "px+=wid/2", "py+=hei/2",^
		       "px[%%i]+=px", "py[%%i]+=py"
	)

	for /l %%i in (0,1,3) do (
		set /a "i1=%%i", "i2=(%%i + 1) %% 4", "j=i1 + 1"
		for /f "tokens=1,2" %%1 in ("!i1! !i2!") do %line% !px[%%1]! !py[%%1]! !px[%%2]! !py[%%2]! !j!
		set "box=!box!!$line!"
		
		set /a "i1=%%i+4", "i2=((%%i + 1) %% 4) + 4", "j+=5"
		for /f "tokens=1,2" %%1 in ("!i1! !i2!") do %line% !px[%%1]! !py[%%1]! !px[%%2]! !py[%%2]! !j!
		set "box=!box!!$line!"
		
		set /a "i1=%%i", "i2=%%i + 4", "j+=5"
		for /f "tokens=1,2" %%1 in ("!i1! !i2!") do %line% !px[%%1]! !py[%%1]! !px[%%2]! !py[%%2]! !j!
		set "box=!box!!$line!"
	)

	echo %esc%[2J!box!
	set "box="
)

:macro

set "sin=(a=((x*31416/180)%%62832)+(((x*31416/180)%%62832)>>31&62832), b=(a-15708^a-47124)>>31,a=(-a&b)+(a&~b)+(31416&b)+(-62832&(47123-a>>31)),a-a*a/1875*a/320000+a*a/1875*a/15625*a/16000*a/2560000-a*a/1875*a/15360*a/15625*a/15625*a/16000*a/44800000) / 10000"
set "cos=(a=((15708-x*31416/180)%%62832)+(((15708-x*31416/180)%%62832)>>31&62832), b=(a-15708^a-47124)>>31,a=(-a&b)+(a&~b)+(31416&b)+(-62832&(47123-a>>31)),a-a*a/1875*a/320000+a*a/1875*a/15625*a/16000*a/2560000-a*a/1875*a/15360*a/15625*a/15625*a/16000*a/44800000) / 10000"
set "rotZ=  rZx=x*^!cos:x=angle^! + y*-^!sin:x=angle^! + z*0,     rZy=x*^!sin:x=angle^! + y*^!cos:x=angle^! + z*0,     rZz=x*0 + y*0 + z*1"
set "rotX=  rXx=x*1 + y*0 + z*0,     rXy=x*0 + y*^!cos:x=angle^! + z*-^!sin:x=angle^!,     rXz=x*0 + y*^!sin:x=angle^! + z*^!cos:x=angle^!"
set "rotY=  rYx=x*^!cos:x=angle^! + y*0 + z*^!sin:x=angle^!,     rYy=x*0 + y*1 + z*0,     rYz=x*-^!sin:x=angle^! + y*0 + z*^!cos:x=angle^!"
set "projection=  px=r?x*1 + r?y*0 + r?z*0,     py=r?x*0 + r?y*1 + r?z*0"

(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)

for /f "delims=" %%T in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x09"') do set "TAB=%%T"
set "QUITKEY=!TAB!"

for /f %%a in ('echo prompt $E^| cmd') do set "esc=%%a"
<nul set /p "=%esc%[?25l"

set line=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-5" %%1 in ("^!args^!") do (%\n%
	if "%%~5" equ "" ( set "hue=15" ) else ( set "hue=%%~5")%\n%
	set "$line=%esc%[38;5;^!hue^!m"%\n%
	set /a "xa=%%~1", "ya=%%~2", "xb=%%~3", "yb=%%~4", "dx=%%~3 - %%~1", "dy=%%~4 - %%~2"%\n%
	if ^^!dy^^! lss 0 ( set /a "dy=-dy", "stepy=-1" ) else ( set "stepy=1" )%\n%
	if ^^!dx^^! lss 0 ( set /a "dx=-dx", "stepx=-1" ) else ( set "stepx=1" )%\n%
	set /a "dx<<=1", "dy<<=1"%\n%
	if ^^!dx^^! gtr ^^!dy^^! (%\n%
		set /a "fraction=dy - (dx >> 1)"%\n%
		for /l %%x in (^^!xa^^!,^^!stepx^^!,^^!xb^^!) do (%\n%
			if ^^!fraction^^! geq 0 set /a "ya+=stepy", "fraction-=dx"%\n%
			set /a "fraction+=dy"%\n%
			set "$line=^!$line^!%esc%[^!ya^!;%%xHÛ"%\n%
		)%\n%
	) else (%\n%
		set /a "fraction=dx - (dy >> 1)"%\n%
		for /l %%y in (^^!ya^^!,^^!stepy^^!,^^!yb^^!) do (%\n%
			if ^^!fraction^^! geq 0 set /a "xa+=stepx", "fraction-=dy"%\n%
			set /a "fraction+=dx"%\n%
			set "$line=^!$line^!%esc%[%%y;^!xa^!HÛ"%\n%
		)%\n%
	)%\n%
	set "$line=^!$line^!%esc%[0m"%\n%
)) else set args=
goto :eof

:Controller
Setlocal DISABLEdelayedExpansion
	REM Environment handling allows use of ! key
	For /l %%C in () do (
		for /f "delims=" %%A in ('C:\Windows\System32\xcopy.exe /w "%~f0" "%~f0" 2^>nul') do If not Defined Key (
	      	set "key=%%A"
			Setlocal ENABLEdelayedExpansion
	      	set key=^!KEY:~-1!
			If "!key!" == "!QUITKEY!" (
				<nul Set /P "=quit"
				EXIT
			)
			Endlocal
		)
	)
exit

Re: 3D Cube Orthographic Projection

Posted: 22 Jan 2024 03:29
by jeb
Hi IcarusLives,

nice picture, but currently the code on my WIN10 only produces:

Code: Select all

Fehlender Operand
Fehlender Operand
Fehlender Operand
[2J[38;5;1m[0;1H´┐¢[0m[38;5;6m[0;1H´┐¢[0m[38;5;11m[0;1H´┐¢[0m[38;5;2m[0;1H´┐¢[0m[38;5;7m[0
;1H´┐¢[0m[38;5;12m[0;1H´┐¢[0m[38;5;3m[0;1H´┐¢[0m[38;5;8m[0;1H´┐¢[0m[38;5;13m[0;1H´┐¢[0m[38
;5;4m[0;1H´┐¢[0m[38;5;9m[0;1H´┐¢[0m[38;5;14m[0;1H´┐¢[0m
Fehlender Operand
Fehlender Operand
Fehlender Operand
Fehlender Operand
Fehlender Operand
Fehlender Operand
Fehlender Operand
Fehlender Operand
[2J[38;5;1m[0;1H´┐¢[0m[38;5;6m[0;1H´┐¢[0m[38;5;11m[0;1H´┐¢[0m[38;5;2m[0;1H´┐¢[0m[38;5;7m[0
;1H´┐¢[0m[38;5;12m[0;1H´┐¢[0m[38;5;3m[0;1H´┐¢[0m[38;5;8m[0;1H´┐¢[0m[38;5;13m[0;1H´┐¢[0m[38
;5;4m[0;1H´┐¢[0m[38;5;9m[0;1H´┐¢[0m[38;5;14m[0;1H´┐¢[0m
Fehlender Operand
Fehlender Operand
Fehlender Operand
Fehlender Operand
Fehlender Operand

Re: 3D Cube Orthographic Projection

Posted: 22 Jan 2024 04:44
by jfl
Nice work!

The problem with your post above is that the ESC characters in your source code did not make it through to the web server.
This is a common problem with ASCII control characters. In the case of the ESC character, there's an easy workaround:
First change:

Code: Select all

set "esc="
<nul set /p "=[?25l"
to:

Code: Select all

for /f %%a in ('"echo prompt $E|cmd"') do set "esc=%%a"
<nul set /p "=%esc%[?25l"
Then prepend a %esc% before each of the other four [ in the following block beginning with: set line=

One request though:
To stop the test, I had to press Control-C. But this left the terminal in an unusable state, and I eventually had to kill it.
It would be nice to add a way to cleanly stop your script (maybe by pressing the ESC key?), and restore the terminal state.

Re: 3D Cube Orthographic Projection

Posted: 22 Jan 2024 06:26
by IcarusLives
Thank you for the suggestions! I will make an update accordingly, and republish soon. Thank you for your time and appreciation!

OP EDITED: Thanks for suggestions :)

Re: 3D Cube Orthographic Projection

Posted: 06 Aug 2024 19:48
by IcarusLives
Update:

created %@box% for read/usability
angleX, angleY, and angleZ are now independent from each other
Uses DDALine instead of BresenhamLine now

This version you can change each angle by using keys QA, WS, ED,and size based on RF.

Press T to quit

Code: Select all

@echo off & setlocal enableDelayedExpansion

if "%~1" neq "" goto :%~1
del /f /q signal.txt

set /a "wid=hei=90"
mode %wid%,%hei%

call :macro

set /a "box.x=wid/2,box.y=hei/2,box.s=15,angle=0"

("%0" Controller >"signal.txt" | "%0" main <"signal.txt") & exit

:main
title T - QUIT
for /l %%# in () do (
	
	if defined key set "lastKey=!key!"
	set "key=" & set /p "key="
	
	       if /i "!key!" == "q" ( set /a "aR+=2"
	) else if /i "!key!" == "a" ( set /a "aR-=2"
	) else if /i "!key!" == "w" ( set /a "bR+=2"
	) else if /i "!key!" == "s" ( set /a "bR-=2"
	) else if /i "!key!" == "e" ( set /a "cR+=2"
	) else if /i "!key!" == "d" ( set /a "cR-=2"
	) else if /i "!key!" == "r" ( set /a "box.s+=1"
	) else if /i "!key!" == "f" ( if !box.s! gtr 3 set /a "box.s-=1"
	) else if /i "!key!" == "t" ( echo=.>"abort.txt" & exit )
	
	set /a "anglex=(anglex + aR) %% 360",^
	       "angley=(angley + bR) %% 360",^
	       "anglez=(anglez + cR) %% 360"
	
	%@box% box.x box.y box.s angleX angleY angleZ
	
	rem echo !$box!
	echo %\e%[2J!$box!%\e%[3;3H[Q,A] Angle X:!anglex!;	aR:!aR!%\e%[4;3H[W,S] Angle Y:!angley!;	bR:!bR!%\e%[5;3H[E,D] Angle Z:!anglez!;	cR:!cR!%\e%[6;3H[R,F] Size: !box.s!
)
exit

:Controller
For /l %%C in () do (
	if exist "abort.txt" (
		del /f /q "abort.txt"
		exit
	)
	for /f "delims=" %%A in ('choice /c:qawsedrft /n') do echo=%%~A
)
exit


:macro
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)

(for /f %%a in ('echo prompt $E^| cmd') do set "\e=%%a") & echo=!\e![?25l

set "sin=(a=((x*31416/180)%%62832)+(((x*31416/180)%%62832)>>31&62832), b=(a-15708^a-47124)>>31,a=(-a&b)+(a&~b)+(31416&b)+(-62832&(47123-a>>31)),a-a*a/1875*a/320000+a*a/1875*a/15625*a/16000*a/2560000-a*a/1875*a/15360*a/15625*a/15625*a/16000*a/44800000) "
set "cos=(a=((15708-x*31416/180)%%62832)+(((15708-x*31416/180)%%62832)>>31&62832), b=(a-15708^a-47124)>>31,a=(-a&b)+(a&~b)+(31416&b)+(-62832&(47123-a>>31)),a-a*a/1875*a/320000+a*a/1875*a/15625*a/16000*a/2560000-a*a/1875*a/15360*a/15625*a/15625*a/16000*a/44800000) "


rem %@line% x0 y0 x1 y1 color <rtn> $line
set @line=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-5" %%1 in ("^!args^!") do (%\n%
	if "%%~5" neq "" ( set "$line=%\e%[48;5;%%~5m" ) else set "$line=%\e%[48;5;15m"%\n%
	set /a "$x0=%%~1, $y0=%%~2, $x1=%%~3, $y1=%%~4, dx=(((%%~3-%%~1)>>31|1)*(%%~3-%%~1)), dy=-($dy=(((%%~4-%%~2)>>31|1)*(%%~4-%%~2))), err=dx+dy, dist=dx, sx=sy=-1"%\n%
	if ^^!dx^^! lss ^^!$dy^^! set dist=^^!$dy^^!%\n%
	if ^^!$x0^^! lss ^^!$x1^^! set sx=1%\n%
	if ^^!$y0^^! lss ^^!$y1^^! set sy=1%\n%
	for /l %%i in (0,1,^^!dist^^!) do (%\n%
		set "$line=^!$line^!%\e%[^!$y0^!;^!$x0^!H "%\n%
		set /a "e2=2 * err"%\n%
		if ^^!e2^^! geq ^^!dy^^! set /a "err+=dy, $x0+=sx"%\n%
		if ^^!e2^^! leq ^^!dx^^! set /a "err+=dx, $y0+=sy"%\n%
	)%\n%
	set "$line=^!$line^!%\e%[0m"%\n%
)) else set args=


:_box
rem predefine points of %@box%
set "points=0" & for %%i in ("-1 -1 -1" " 1 -1 -1" " 1  1 -1" "-1  1 -1" "-1 -1  1" " 1 -1  1" " 1  1  1" "-1  1  1") do (
	for /f "tokens=1-3" %%x in ("%%~i") do set /a "x!points!=%%~x, y!points!=%%~y, z!points!=%%~z"
	set /a "points+=1"
)
set "points="
rem in=>x y z ; out=>$a $b
set "boxFormula(x,y,z)=rx= x *  coa/10000 +  z *  sia/10000, rz= x * -sia/10000 +  z *  coa/10000, ry= y *  cob/10000 + rz * -sib/10000, $a=rx *  coc/10000 + ry * -sic/10000, $b=rx *  sic/10000 + ry *  coc/10000"
set @box=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-6" %%A in ("^!args^!") do (%\n%
	set "$box="%\n%
	set /a "coa=^!cos:x=%%~D^!, sia=^!sin:x=%%~D^!, cob=^!cos:x=%%~E^!, sib=^!sin:x=%%~E^!, coc=^!cos:x=%%~F^!, sic=^!sin:x=%%~F^!"%\n%
	for /l %%i in (0,1,7) do set /a "x=x%%i * %%~C, y=y%%i * %%~C, z=z%%i * %%~C", "%boxFormula(x,y,z)%", "px[%%i]=$a + %%~A, py[%%i]=$b + %%~B"%\n%
	for /l %%i in (0,1,3) do ( set /a "i1=%%i, i2=(%%i + 1) %% 4, j1=i1 + 1, i3=%%i+4, i4=((%%i + 1) %% 4) + 4, j2=j1 + 5, i5=%%i + 4, j3=j2 + 5"%\n%
		for /f "tokens=1-6" %%1 in ("^!i1^! ^!i2^! ^!i3^! ^!i4^! ^!i5^!") do (%\n%
			^!@line^! ^^!px[%%1]^^! ^^!py[%%1]^^! ^^!px[%%2]^^! ^^!py[%%2]^^! ^^!j1^^!%\n%
			set "$box=^!$box^!^!$line^!"%\n%
			^!@line^! ^^!px[%%3]^^! ^^!py[%%3]^^! ^^!px[%%4]^^! ^^!py[%%4]^^! ^^!j2^^!%\n%
			set "$box=^!$box^!^!$line^!"%\n%
			^!@line^! ^^!px[%%1]^^! ^^!py[%%1]^^! ^^!px[%%5]^^! ^^!py[%%5]^^! ^^!j3^^!%\n%
			set "$box=^!$box^!^!$line^!"%\n%
		)%\n%
	)%\n%
)) else set args=
set "boxFormula(x,y,z)="
goto :eof