% !TeX root = ./test.tex %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This is the TikZbricks package % A package to draw bricks with tikz % Maintained by samcarter % % Project repository and bug tracker: % https://github.com/samcarter/TikZbricks % % Released under the LaTeX Project Public License v1.3c or later % See https://www.latex-project.org/lppl.txt % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ProvidesPackage{tikzbricks}[2024/12/16 version v0.6 Drawing bricks with TikZ] \RequirePackage{tikz} \RequirePackage{tikz-3dplot} \RequirePackage{xkeyval} % setting a default viewpoint \tdplotsetmaincoords{70}{160} % setting default values \DeclareOptionX{color}[red]{\def\brick@default@color{#1}} \DeclareOptionX{frontcolor}[\brick@color!60]{\def\brick@default@frontcolor{#1}} \DeclareOptionX{topcolor}[\brick@color!40]{\def\brick@default@topcolor{#1}} \DeclareOptionX{sidecolor}[\brick@color]{\def\brick@default@sidecolor{#1}} \DeclareOptionX{studcolor}[\brick@color]{\def\brick@default@studcolor{#1}} \DeclareOptionX{brickheight}[1.3]{\def\brick@default@height{#1}} \DeclareOptionX{bricklength}[1.0]{\def\brick@default@length{#1}} \DeclareOptionX{bricktext}[]{\def\brick@default@facetext{#1}} \DeclareOptionX{brickwidth}[1.0]{\def\brick@default@width{#1}} \DeclareOptionX{studradius}[0.35]{\def\brick@default@radius{#1}} \DeclareOptionX{studheight}[0.3]{\def\brick@default@studheight{#1}} \DeclareOptionX{studtext}[]{\def\brick@default@text{#1}} \ExecuteOptionsX{color,frontcolor,topcolor,sidecolor,studcolor,brickheight,bricklength,bricktext,brickwidth,studradius,studheight,studtext} \ProcessOptionsX % counter to dermine the position of a brick in a wall \newcounter{brickx} \newcounter{bricky} \newcounter{brickz} % draw a standalone brick % 1: optional argument % 2: lenght % 3: width \newcommand*{\brick}[3][]{% \setcounter{brickx}{0}% \setcounter{bricky}{0}% \setcounter{brickz}{0}% \begin{scope}% \tikzset{/brick/.cd,#1}% \brick@draw{#2}{#3}% \end{scope}% } % draw a brick in a wall % 1: optional argument % 2: lenght % 3: width \newcommand*{\wallbrick}[3][]{% \begin{scope}% \tikzset{/brick/.cd,#1}% \brick@draw{#2}{#3}% \end{scope}% \addtocounter{brickx}{#2}% } % envrinoment to arange the bricks in a wall % 1: optional argument passed to the tikzpicture \newenvironment{wall}[1][]{% \setcounter{brickx}{0}% \setcounter{bricky}{0}% \setcounter{brickz}{0}% \newcommand{\newrow}{% \setcounter{brickx}{0}% \addtocounter{brickz}{1}% }% \begin{tikzpicture}[#1] }{% \end{tikzpicture}% } \tikzset{ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Pass unknown keys on to tikz % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /brick/.search also={/tikz,/pgf}, /brick/.cd, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % brick options % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% color/.code = \def\brick@color{#1}, color = \brick@default@color, frontcolor/.code = \def\brick@frontcolor{#1}, frontcolor = \brick@default@frontcolor, topcolor/.code = \def\brick@topcolor{#1}, topcolor = \brick@default@topcolor, sidecolor/.code = \def\brick@sidecolor{#1}, sidecolor = \brick@default@sidecolor, studcolor/.code = \def\brick@studcolor{#1}, studcolor = \brick@default@studcolor, brickheight/.code = \def\brick@height{#1}, brickheight = \brick@default@height, bricklength/.code = \def\brick@length{#1}, bricklength = \brick@default@length, bricktext/.code = \def\brick@facetext{#1}, bricktext = \brick@default@facetext, brickwidth/.code = \def\brick@width{#1}, brickwidth = \brick@default@width, studradius/.code = \def\brick@radius{#1}, studradius = \brick@default@radius, studheight/.code = \def\brick@studheight{#1}, studheight = \brick@default@studheight, studtext/.code = \def\brick@text{#1}, studtext = \brick@default@text, } \newcommand{\brick@draw}[2]{% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % store the current scale factor % from https://github.com/samcarter/tikzlings/issues/3#issuecomment-461373494 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pgfgettransformentries{\tmpscaleA}{\tmpscaleB}{\tmpscaleC}{\tmpscaleD}{\tmp}{\tmp}% \pgfmathsetmacro{\scalingfactor}{sqrt(abs(\tmpscaleA*\tmpscaleD-\tmpscaleB*\tmpscaleC))*sqrt(abs((\pgf@xx/1cm)*(\pgf@yy/1cm)-(\pgf@xy/1cm)*(\pgf@yx/1cm)))}% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Drawing the brick % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{scope}[tdplot_main_coords] % Drawing faces \pgfmathparse{sign(sin(\tdplotmainphi))} \let\brick@sin\pgfmathresult \pgfmathparse{sign(cos(\tdplotmainphi))} \let\brick@cos\pgfmathresult \ifnum\brick@sin<0 % Right \fill[\brick@sidecolor,thick] ( \brick@length*\value{brickx}, \brick@width*\value{bricky}, \brick@height*\value{brickz} ) -- ++(0,0,\brick@height) -- ++(0,\brick@width*#2,0) -- ++(0,0,-\brick@height) -- cycle; \else % Left \fill[\brick@sidecolor,thick] ( {\brick@length*(#1+\value{brickx})}, \brick@width*\value{bricky}, \brick@height*\value{brickz} ) -- ++(0,0,\brick@height) -- ++(0,\brick@width*#2,0) -- ++(0,0,-\brick@height) -- cycle; \fi \ifnum\brick@cos<0 % Front \fill[\brick@frontcolor,thick] ( \brick@length*\value{brickx}, {\brick@width*(#2+\value{bricky})}, \brick@height*\value{brickz} ) -- ++(\brick@length*#1,0,0) -- ++(0,0,\brick@height) -- ++(-\brick@length*#1,0,0) -- cycle; \node[align=center, transform shape, canvas is zx plane at y=0, rotate=-90] at ( \brick@length*\value{brickx} + 0.5*\brick@length*#1, {\brick@width*(#2+\value{bricky})}, \brick@height*\value{brickz} + 0.5*\brick@height ) {\brick@facetext}; \else % Back \fill[\brick@frontcolor,thick] ( \brick@length*\value{brickx}, \brick@width*\value{bricky}, \brick@height*\value{brickz} ) -- ++(\brick@length*#1,0,0) -- ++(0,0,\brick@height) -- ++(-\brick@length*#1,0,0) -- cycle; \fi % Top \fill[\brick@topcolor,thick] ( \brick@length*\value{brickx}, \brick@width*\value{bricky}, {\brick@height*(1+\value{brickz})} ) -- ++(0,\brick@width*#2,0) -- ++(\brick@length*#1,0,0) -- +(0,-\brick@width*#2,0) -- cycle; % Drawing studs \foreach \x in {1,...,#1}{ \foreach \y in {1,...,#2}{ % Bottom circle \fill[\brick@studcolor] ( {\brick@length*(\x-0.5+\value{brickx})}, {\brick@width*(\y-0.5+\value{bricky})}, {\brick@height*(1+\value{brickz})} ) circle [radius=\brick@radius]; % Rectangular stem \fill[\brick@studcolor] ( {\brick@length*(\x-0.5+\value{brickx})}, {\brick@width*(\y-0.5+\value{bricky})}, {\brick@height*(1+\value{brickz})} ) ++(canvas cs:x=-\brick@radius/0.35*10) -- ++(canvas cs:y=\brick@studheight*17.8) -- ++(canvas cs:x=\brick@radius/0.35*20) -- ++(canvas cs:y=-\brick@studheight*17.8); % Top circle with text \fill[\brick@topcolor] ( {\brick@length*(\x-0.5+\value{brickx})}, {\brick@width*(\y-0.5+\value{bricky})}, {\brick@height*(1+\value{brickz})} ) ++(canvas cs:y=\brick@studheight*17.8) circle [radius=\brick@radius] node[\brick@color,scale=\scalingfactor*0.5, font=\sffamily] {\brick@text}; } } \end{scope} }