user:mate2code/bin2svg
From Wikiversity
< User:Mate2code(Redirected from User:Lipedia/bin2svg)
Sierpinski triangle drawn with bin2svg - The red squares form one continuous area, so the path contains only one
M.bin2svg.m is a Matlab program I have written to represent binary matrices as vector graphics.
The input is the binary matrix and the output is the code of the corresponding SVG path.
Matrices created with this program are marked with {{bin2svg}} and sorted into the hidden category Created with bin2svg.
Contents |
Function bin2svg [edit]
Subfunction bin2corners [edit]
function [y] = bin2corners(x) % Turns the binary matrix in a bigger matrix with key numbers. high = size(x,1) ; long = size(x,2) ; X = [ zeros(1,long+2) ; zeros(high,1) x zeros(high,1) ; zeros(1,long+2) ] ; Y = zeros(high+1,long+1) ; for m=1:high+1 for n=1:long+1 A = X(m:m+1,n:n+1) ; if A == [ 0 0 ; 0 1 ] Y(m,n) = 1 ; elseif A == [ 0 0 ; 1 0 ] Y(m,n) = 2 ; elseif A == [ 1 0 ; 0 0 ] Y(m,n) = 3 ; elseif A == [ 0 1 ; 0 0 ] Y(m,n) = 4 ; elseif A == [ 1 1 ; 1 0 ] Y(m,n) = 5 ; elseif A == [ 1 0 ; 1 1 ] Y(m,n) = 6 ; elseif A == [ 0 1 ; 1 1 ] Y(m,n) = 7 ; elseif A == [ 1 1 ; 0 1 ] Y(m,n) = 8 ; elseif A == [ 1 0 ; 0 1 ] Y(m,n) = 13 ; elseif A == [ 0 1 ; 1 0 ] Y(m,n) = 24 ; end end end y = Y ; end
| example |
|---|
>> binmat = [ 0 0 0 1 1 1 1 0 1 0 1 0 1 1 1 0 ] ; >> cornermat = bin2corners(binmat) cornermat = 0 0 0 1 2 1 0 0 24 3 0 5 8 0 0 0 6 7 0 0 4 0 0 3 0 |
Subfunction cornerfinder [edit]
function [y] = cornerfinder(x1,x2) % Searches matrix x1 from position x2 for non zero entries. % Output is vector [m n k] where [m n] is the first position found and k the entry at this position. high = size(x1,1) ; wide = size(x1,2) ; look = x2 ; found = 0 ; while found == 0 found = x1( look(1) , look(2) ) ; if found == 0 if look(2) < wide look(2) = look(2) + 1 ; elseif look(2)==wide && look(1)<high look = [ look(1)+1 1 ] ; else look = [-1 -1] ; % reached end, signal to stop for other function break end else break end end y = [ look found ] ; end
| example |
|---|
>> mnk = cornerfinder( cornermat , [1 1] ) mnk = 1 4 1 |
Subfunction bin2svg_step [edit]
function [y] = bin2svg_step(mat,x2) % x1 is the key number matrix, x2 is the output of cornerfinder. pos = x2(1:2) ; coordinates = [ 'M' num2str(pos(2)-1) ',' num2str(pos(1)-1) ] ; entry = x2(3) ; while 1 if entry>=1 && entry<=8 mat(pos(1),pos(2)) = 0 ; elseif entry==13 && ( entrybefore==4 || entrybefore==7 ) % 13 as 1 , leave 3 mat(pos(1),pos(2)) = 3 ; entry = 1 ; elseif entry==13 && ( entrybefore==2 || entrybefore==5 ) % 13 as 3 , leave 1 mat(pos(1),pos(2)) = 1 ; entry = 3 ; elseif entry==24 && ( entrybefore==1 || entrybefore==6 ) % 24 as 2 , leave 4 mat(pos(1),pos(2)) = 4 ; entry = 2 ; elseif entry==24 && ( entrybefore==3 || entrybefore==8 ) % 24 as 4 , leave 2 mat(pos(1),pos(2)) = 2 ; entry = 4 ; end posbefore = pos ; creeper = 0 ; if entry==1 || entry==6 while creeper == 0 pos(2) = pos(2)+1 ; if pos == x2(1:2) break end creeper = mat( pos(1) , pos(2) ) ; end elseif entry==2 || entry==5 while creeper == 0 pos(1) = pos(1)+1 ; if pos == x2(1:2) break end creeper = mat( pos(1) , pos(2) ) ; end elseif entry==3 || entry==8 while creeper == 0 pos(2) = pos(2)-1 ; if pos == x2(1:2) break end creeper = mat( pos(1) , pos(2) ) ; end elseif entry==4 || entry==7 while creeper == 0 pos(1) = pos(1)-1 ; if pos == x2(1:2) break end creeper = mat( pos(1) , pos(2) ) ; end end entrybefore = entry ; entry = creeper ; if pos(1)==posbefore(1) d = [ 'h' num2str( pos(2)-posbefore(2) ) ] ; else d = [ 'v' num2str( pos(1)-posbefore(1) ) ] ; end if pos == x2(1:2) break end coordinates = [ coordinates d ] ; end Y = cell(1,2); Y{1} = mat ; Y{2} = coordinates ; y = Y ; end
| example |
|---|
>> coordinatecell = bin2svg_step( cornermat , mnk ) coordinatecell = [5x5 double] 'M3,0h1v1h-1' >> >> coordinatecell{1} ans = 0 0 0 0 0 1 0 0 2 0 0 5 8 0 0 0 6 7 0 0 4 0 0 3 0 |
Function bin2svg itself [edit]
function [y] = bin2svg(x) % Binary matrix to SVG path. A = bin2corners(x) ; startpos = [1 1] ; coordinates = repmat(' ',1,0) ; while 1 B = cornerfinder(A,startpos) ; if B == [-1 -1 0] break end startpos = B(1:2) ; C = bin2svg_step(A,B) ; A = C{1} ; coordinates = [ coordinates C{2} ] ; end y = coordinates ; end
Example:
>> binmat
binmat =
0 0 0 1
1 1 1 0
1 0 1 0
1 1 1 0
>> bin2svg(binmat)
ans =
M3,0h1v1h-1M0,1h3v3h-3M1,2v1h1v-1
In the following SVG code the result produces the image shown on the right:
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="-.5 -.5 5 5"> <path fill="#fff" d="m0,0h4v4H0"/> <!-- white background --> <path fill="#f00" d="M3,0h1v1h-1M0,1h3v3h-3M1,2v1h1v-1"/> <!-- red entries --> <g stroke="#000"> <path stroke-width="4" stroke-dasharray=".05,.95" d="M0,2h5M2,0v5"/> <!-- 0.5px black lines --> <rect stroke-width=".1" fill="none" x="0" y="0" width="4" height="4"/> <!-- 1px black square --> </g> </svg>
Derived functions for integer matrices [edit]
mat2svg [edit]
function [Code] = mat2svg(Mat,Bitlong,Gapvert,Gaphorz) % Produces the SVG code for binary strings in an SVG graphic of a matrix of integers. % Inputs: ( matrix, length of binary strings, size of vertical gaps, size of horizontal gaps ) % used functions: bin2svg, char2mat Matvert = size(Mat,1) ; Mathorz = size(Mat,2) ; Bin = zeros( Matvert + (Matvert-1)*Gapvert , Mathorz*Bitlong + (Mathorz-1)*Gaphorz ) ; for m=1:Matvert for n=1:Mathorz Bin( (m-1)*(Gapvert+1)+1 , (n-1)*(Bitlong+Gaphorz)+1 : (n-1)*(Bitlong+Gaphorz)+Bitlong ) = char2mat( dec2bin(Mat(m,n),Bitlong) ) ; end end Code = bin2svg( Bin ) ; end
mat2svg_dual [edit]
function [Code] = mat2svg_dual(Mat,Bitlong,Gap) % Produces the SVG code for binary dual matrix in an SVG graphic of a matrix of integers. % Inputs: ( matrix, length of binary strings, size of gap between matrices ) % used functions: bin2svg, char2mat Matvert = size(Mat,1) ; Mathorz = size(Mat,2) ; Binmat = zeros( Matvert , Mathorz*Bitlong + (Bitlong-1)*Gap ) ; for m=1:Matvert for n=1:Mathorz Binvect = char2mat( dec2bin(Mat(m,n),Bitlong) ) ; for k=1:Bitlong Binmat( m , (Mathorz+Gap)*(k-1)+n ) = Binvect(k) ; end end end Code = bin2svg( Binmat ) ; end