GLE Library: matrix_3D.gle
! This library is designed to plot 3D BAR graphs of square matrices
! ----------------------------------------------------------------------
! Global constants with typical values:
! ----------------------------------------------------------------------
! mmax (4 or 16) size of the matrix
! r (6 cm) the matrix is drawn to a 3D cube r.r.r
! alfa (25 deg) rotation of the cube in horizontal direction
! beta (30 deg) rotation of the cube in vertical direction
! ----------------------------------------------------------------------
! x0,y0 position of the left bottom corner of the cube
! xgrp, ygrp position of the perspective point of infinity
! persp_scale (3) perspective scale
! ----------------------------------------------------------------------
! z_axis_min z_axis_bottom_value
! z_axis_max z_axis_top_value
! z0 baseline for drawing 3D bars up or down
! ----------------------------------------------------------------------
!
! Used colors:
! ----------------------------------------------------------------------
! color_frame$, col_T$, col_L$, col_R$, col_BR$, col_BL$
! ----------------------------------------------------------------------
!
! Important subroutines
!
! sub project_3D2D s1 s2 s3
! Takes one point of 3D box [s1,s2,s3] and calculates its position in
! the picture [xgr,ygr]
!
! sub draw_back_frame
! Draws three back lines of the cube.
!
! sub draw_middle_frame
! Draws six additional lines of the cube.
!
! sub draw_front_frame
! Draws three front lines of the cube.
!
! sub normalize_z zvalue
! Calculates normalized z coordinate in a range (0,1)
! (zvalue - bottom_z_value)/(top_z_value - bottom_z_value)
!
! sub draw_bar_z i j zvalue
! Draws one bar, (i,j) element of the matrix with a given value (zvalue).
!
! sub draw_matrix_row k l
! Draws one row of the matrix. The subroutine reads one row of the matrix
! and displays the elements in reverse order (the last one the first).
! This condition ensures correct resulting visualization.
!
! sub draw_z_ticks h1 h2 h3
! Draws ticks with labels to z_axis: from h1, to h2, with a step h3.
! The format of z_axis labels can be set, e.g.
! formatz$ = "fix 2"
!
! sub draw_xy_ticks
! Draws ticks to x_axis and y_axis
!
! sub label_x i txt$
! Draws label txt$ to i-th x_axis tick.
!
! sub label_y i txt$
! Draws label txt$ to i-th y_axis tick.
r = 6
color_frame$ = "black"
col_T$ = "rgb(1,.8,.8)"
col_L$ = "rgb(.8,.8,1)"
col_R$ = "rgb(.8,1,.8)"
col_BR$ = "rgb(.6,.6,1)"
col_BL$ = "rgb(.6,1,.6)"
dmin = z_axis_min
dmax = z_axis_max
sa = sin(torad(alfa))
ca = cos(torad(alfa))
sb = sin(torad(beta))
cb = cos(torad(beta))
ux = todeg(atan((ca/sa)*sb))
uy = -todeg(atan((sa/ca)*sb))
x0 = 0; y0 = 0
set join round just cc
!-----------------------------------------------------------
sub project_3D2D s1 s2 s3
xgr = x0+r*(s1*ca+s2*sa)
local zp = s1*sa-s2*ca
ygr = y0+r*(s3*cb-zp*sb)
zp = s3*sb+zp*cb
! perspektiva
if (zp<persp_scale) then
local zper = persp_scale/(persp_scale-zp)
xgr = zper*xgr+(1-zper)*xgrp
ygr = zper*ygr+(1-zper)*ygrp
else
! IT IS OUT, predmety nejsou prede mnou, ale za mnou
xgr = 0
ygr = 0
end if
end sub
!-----------------------------------------------------------
sub od_do a1 a2 a3 b1 b2 b3
project_3D2D a1 a2 a3
amove xgr ygr
project_3D2D b1 b2 b3
aline xgr ygr
end sub
!-----------------------------------------------------------
sub _do b1 b2 b3
amove xgr ygr
project_3D2D b1 b2 b3
aline xgr ygr
end sub
!-----------------------------------------------------------
sub draw_back_frame
gsave
set color color_frame$
od_do 0 1 0 0 0 0
od_do 0 1 0 1 1 0
od_do 0 1 0 0 1 1
grestore
end sub
!-----------------------------------------------------------
sub draw_middle_frame
gsave
set color color_frame$
od_do 0 0 0 0 0 1
_do 0 1 1
_do 1 1 1
_do 1 1 0
_do 1 0 0
_do 0 0 0
grestore
end sub
!-----------------------------------------------------------
sub draw_front_frame
gsave
set color color_frame$
od_do 1 0 1 0 0 1
od_do 1 0 1 1 1 1
od_do 1 0 1 1 0 0
grestore
end sub
!-----------------------------------------------------------
sub draw_bar_z_zero i j
project_3D2D (i-1)/mmax (j-1)/mmax z0
x_1=xgr; y_1=ygr
project_3D2D (i)/mmax (j-1)/mmax z0
x_2=xgr; y_2=ygr
project_3D2D (i)/mmax (j)/mmax z0
x_3=xgr; y_3=ygr
project_3D2D (i-1)/mmax (j)/mmax z0
x_4=xgr; y_4=ygr
begin path fill col_T$ stroke
amove x_1 y_1
aline x_2 y_2
aline x_3 y_3
aline x_4 y_4
closepath
end path
end sub
!-----------------------------------------------------------
sub draw_bar_z_up i j z
project_3D2D (i-1)/mmax (j-1)/mmax z
x_1=xgr; y_1=ygr
project_3D2D (i)/mmax (j-1)/mmax z
x_2=xgr; y_2=ygr
project_3D2D (i)/mmax (j)/mmax z
x_3=xgr; y_3=ygr
project_3D2D (i-1)/mmax (j)/mmax z
x_4=xgr; y_4=ygr
project_3D2D (i-1)/mmax (j-1)/mmax z0
x_01=xgr; y_01=ygr
project_3D2D (i)/mmax (j-1)/mmax z0
x_02=xgr; y_02=ygr
project_3D2D (i)/mmax (j)/mmax z0
x_03=xgr; y_03=ygr
begin path fill col_T$ stroke
amove x_1 y_1
aline x_2 y_2
aline x_3 y_3
aline x_4 y_4
closepath
end path
begin path fill col_L$ stroke
amove x_1 y_1
aline x_01 y_01
aline x_02 y_02
aline x_2 y_2
closepath
end path
begin path fill col_R$ stroke
amove x_2 y_2
aline x_02 y_02
aline x_03 y_03
aline x_3 y_3
closepath
end path
end sub
!-----------------------------------------------------------
sub draw_bar_z_down i j z
project_3D2D (i-1)/mmax (j-1)/mmax z
x_1=xgr; y_1=ygr
project_3D2D (i)/mmax (j-1)/mmax z
x_2=xgr; y_2=ygr
project_3D2D (i)/mmax (j)/mmax z
x_3=xgr; y_3=ygr
project_3D2D (i-1)/mmax (j)/mmax z
x_4=xgr; y_4=ygr
project_3D2D (i-1)/mmax (j-1)/mmax z0
x_01=xgr; y_01=ygr
project_3D2D (i)/mmax (j-1)/mmax z0
x_02=xgr; y_02=ygr
project_3D2D (i)/mmax (j)/mmax z0
x_03=xgr; y_03=ygr
project_3D2D (i-1)/mmax (j)/mmax z0
x_04=xgr; y_04=ygr
begin clip
begin path clip
amove x_01 y_01
aline x_02 y_02
aline x_03 y_03
aline x_04 y_04
closepath
end path
begin path fill col_T$ stroke
amove x_1 y_1
aline x_2 y_2
aline x_3 y_3
aline x_4 y_4
closepath
end path
begin path fill col_BL$ stroke
amove x_1 y_1
aline x_01 y_01
aline x_04 y_04
aline x_4 y_4
closepath
end path
begin path fill col_BR$ stroke
amove x_4 y_4
aline x_04 y_04
aline x_03 y_03
aline x_3 y_3
closepath
end path
end clip
begin path fill col_L$ stroke
amove x_1 y_1
aline x_01 y_01
aline x_02 y_02
aline x_2 y_2
closepath
end path
begin path fill col_R$ stroke
amove x_2 y_2
aline x_02 y_02
aline x_03 y_03
aline x_3 y_3
closepath
end path
end sub
!-----------------------------------------------------------
sub normalize_z zvalue !zvalue (0 , 1)
local vys
if (zvalue<dmin) then
dmin=zvalue
else if (zvalue>dmax) then
dmax=zvalue
end if
vys=(zvalue-z_axis_min)/(z_axis_max-z_axis_min)
return vys
end sub
!-----------------------------------------------------------
sub normalize_z0 zvalue !zvalue (0 , 1)
local vys
vys=(zvalue-z_axis_min)/(z_axis_max-z_axis_min)
return vys
end sub
!-----------------------------------------------------------
sub draw_bar_z i j zvalue
z=normalize_z(zvalue)
if (z>z0) then
draw_bar_z_up i j z
else if (z<z0) then
draw_bar_z_down i j z
else
draw_bar_z_zero i j
end if
end sub
!-----------------------------------------------------------
sub draw_matrix_row k l
local h
fread vstup h
if (l<mmax) then
draw_matrix_row k l+1
end if
draw_bar_z k l h
end sub
!-----------------------------------------------------------
sub draw_z_ticks h1 h2 h3
kk=(h2-h1)/h3
for k=0 to kk
zvalue=h1+k*h3
z=normalize_z0(zvalue)
!@od_do 0 0 z -.03 -.03 z
!@project_3D2D -.07 -.07 z
! amove xgr ygr+.05
project_3D2D 0 0 z
amove xgr ygr
rline -.2 0
rmove -.35 0
if (formatz$="") then
if (abs(zvalue)<1e-5) then
write 0
else
write zvalue
end if
else
write format$(zvalue,formatz$)
end if
next k
end sub
!-----------------------------------------------------------
sub draw_xy_ticks
for k=0 to mmax-1
pom=(k+.5)/mmax
od_do pom 0 0 pom -.05 0
od_do 1 pom 0 1.05 pom 0
next k
end sub
!-----------------------------------------------------------
sub draw_xy_ticks2 po
for k=0 to mmax-1
local pom=(k+.5)/mmax
if ((k%po)=0) then
od_do pom 0 0 pom -.05 0
od_do 1 pom 0 1.05 pom 0
else
od_do pom 0 0 pom -.03 0
od_do 1 pom 0 1.03 pom 0
end if
next k
end sub
!-----------------------------------------------------------
sub label_x i txt$
project_3D2D (i-.5)/mmax -.2 0
amove xgr ygr
begin rotate ux
write txt$
end rotate
end sub
!-----------------------------------------------------------
sub label_y i txt$
project_3D2D 1.15 (i-.5)/mmax 0
amove xgr ygr
begin rotate uy
write txt$
end rotate
end sub
!-----------------------------------------------------------
sub draw_bar_graph_3d f$
draw_back_frame
fopen f$ vstup read
for k = 1 to mmax
draw_matrix_row k 1
next k
fclose vstup
draw_middle_frame
draw_front_frame
end sub
[Return to subroutines page]