改进 PSTricks 代码以绘制抽屉柜

改进 PSTricks 代码以绘制抽屉柜

考虑以下示例。

代码

% pdflatex -shell-escape test.tex

\documentclass{article}

\usepackage{auto-pst-pdf,pstricks-add}

\begin{document}

\psset{unit=0.08cm}
\begin{pspicture}(45,150)
 \pspolygon(0,0)(1.147,8)(43.853,8)(45,0)
 \pspolygon(2.147,8)(22.5,150)(42.853,8)
 \pspolygon(3.147,8)(5.727,26)(39.273,26)(41.853,8)
 \pspolygon(5.870,27)(8.450,45)(36.550,45)(39.130,27)
 \pspolygon(8.593,46)(11.173,64)(33.827,64)(36.407,46)
 \pspolygon(11.317,65)(13.897,83)(31.103,83)(33.683,65)
 \pspolygon(14.040,84)(16.620,102)(28.38,102)(30.96,84)
 \multido{\i=17+19}{5}{\pscircle(22.5,\i){1.5}}
\end{pspicture}

\end{document}

输出

在此处输入图片描述

问题

我确实有想要的输出,但坐标是使用以下抽屉标准手动计算的:

  • 身高:150
  • 宽度:45
  • 底座高度:8
  • 抽屉高度:18
  • 两个连续抽屉之间的距离:1

我想在不手动计算坐标的情况下绘制它。我该怎么做?

答案1

\documentclass{article}
\usepackage{pstricks}\SpecialCoor

\begin{document}
\psset{unit=1mm}
\begin{pspicture}(-25,0)(25,150)
    % Parameters
    \def\h{150 }     % height 
    \def\w{45 }      % width
    \def\hb{8 }      % height of base
    \def\hd{18 }     % height of drawer
    \def\d{1 }       % vertical space between drawers
    \def\b{1 }       % horizontal space on either side of a drawer
    \def\r{25 }      % radius of handle
    \def\N{7 }       % number of drawers
    \def\a{1 }       % another parameter for the base
    \def\c{2mm}      % radius for the circle
    % The following function returns the width of horizontal lines at a given height 
\pstVerb{ /f { neg \h div 1 add \w mul \b dup add sub 0.5 mul } def 
          /hbh 0.5 1 \hb \h div add mul def }
\pspolygon(!\w 2 div neg 0)(!\w 2 div 0)(0,\h)
\psforeach{\iA}{1,2,..,\N}{%
  \pstVerb{/z \iA\space 1 sub \d \hd add mul def }
  \pspolygon(!z f neg z)(!z f z)(!z \hd add dup f exch)(!z \hd add dup f neg exch)
  \pscircle(!0 .5 \hd mul \iA\space 1 sub \hd \d add mul add ){\c}
}
\pspolygon(!hbh neg \w mul \a sub \hb neg)%   
          (!hbh \w mul \a add \hb neg)%        
          (!.5 \w mul \a add 0)(!-.5 \w mul \a sub 0)
\end{pspicture}
\end{document}

答案2

这一次,这是 PSTricks 问题的 TikZ 解决方案:

在此处输入图片描述

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[scale=.1,thick,line join=round]

% Parameters
\def\h{150}     % height 
\def\w{45}      % width
\def\hb{8}      % height of base
\def\hd{18}     % height of drawer
\def\d{1}       % vertical space between drawers
\def\b{1}       % horizontal space on either side of a drawer
\def\r{1}       % radius of handle
\def\N{7}       % number of drawers
\def\a{1}       % another parameter for the base

% The following function returns some relevant horizontal length
% (it takes a height as argument)
\pgfmathdeclarefunction{f}{1}{%
    \pgfmathparse{.5*((1-#1/\h)*\w-2*\b)}%
}

% draw the chest
\draw ({-.5*\w},0) -- ({.5*\w},0) -- (0,\h) -- cycle;

% draw the base
\draw       ({-.5*(1+\hb/\h)*\w-\a},-\hb)   
          --++({((1+\hb/\h)*\w+2*\a)},0)        
          --({.5*\w+\a},0)
          --({-.5*\w-\a},0)
          --cycle;

% draw the ... ahem .. drawers (incl. handles)
\foreach \i in {1,2,...,\N}{%
    \def\z{\the\numexpr(\i-1)*(\d+\hd)}
    \draw   ({-f(\z)},\z)    
          --({f(\z)},\z)     
          --({f(\z+\hd)},{\z+\hd})
          --({-f(\z+\hd)},{\z+\hd})
          --cycle;
    \draw (0,{.5*\hd+(\i-1)*(\hd+\d)}) circle (\r);
}

\end{tikzpicture}
\end{document}

答案3

\documentclass{article}
\usepackage[pdf]{pstricks}
\usepackage{pst-eucl}

\begin{document}
\psset{unit=0.08cm}
\newcommand\height{150 }% trailing spaces are necessary here!!
\newcommand\width{45 }
\newcommand\drawerheight{18 }
\newcommand\drawercount{5 }
\newcommand\baseheight{8 }

% The triangle of \height and \halfwidth has the angle a at the top (called point A).
% We calculate sin(a/2) and cos(a/2)
\edef\halfwidth{\width 2 div }
\edef\hypothenuse{\height \height mul \halfwidth \halfwidth mul add sqrt }
\edef\sinval{\halfwidth \hypothenuse div }
\edef\cosval{\height \hypothenuse div }

%#1 : distance from point A to bottom line of drawer
%#2 : height of trapezoid
%#3 : horizontal correction 
\newcommand\trapezoid[3]{
  \edef\ytop{#1 #2 sub }
  \edef\ybottom{#1 }
  \edef\hwtop{\ytop \cosval div \sinval mul #3 add }
  \edef\hwbottom{\ybottom \cosval div \sinval mul #3 add }
  \expandafter\pspolygon(!\hwtop -1 mul #2)(!\hwtop #2)
      (!\hwbottom 0)(!\hwbottom -1 mul 0)
}

\newcommand\drawer[1]{%
  \trapezoid{#1}{\drawerheight}{-1} \pscircle(0,9){1.5}
}

\begin{pspicture}(\width,\height)
% the base
\rput(! 0 0){\trapezoid{\height}{8}{1}}
% the cover
\edef\heightt{\number\numexpr\height - \baseheight}
\rput(! 0 \baseheight){\trapezoid{\heightt}{\heightt}{0}}
% the drawers
\edef\dhs{\number\numexpr\drawerheight+1}
\edef\start{\number\numexpr\height - (\drawercount-1)*\dhs - \baseheight}
\multido{\i=\start+\dhs}{\drawercount}{%
  \rput(! 0 \height \i\space sub){\drawer{\i}}
}
\end{pspicture}
\end{document}

答案4

只是另一个解决方案!

在此处输入图片描述

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node}
\usepackage{multido}
\usepackage[nomessages]{fp}

% constants declarator
\def\LoadConstants{}
\newcommand\const[3][3]{%
    \edef\temporary{trunc(#3}%
    \expandafter\FPeval\csname#2\expandafter\endcsname
        \expandafter{\temporary:#1)}%
        \edef\LoadConstants{\LoadConstants
            \noexpand\pstVerb{/#2 \csname#2\endcsname\space def}}%
                        \ignorespaces}


\psset{unit=1mm,linejoin=1}

\const{Width}{45}% Width
\const{Height}{150}% Height
\const{height}{18}% drawer height
\const{vgap}{1}% vertical gap between drawers
\const{hgap}{1}% horizontal gap for each drawer
\const{BaseWidth}{50}% base width
\const{BaseHeight}{5}% base height

\const{HalfWidth}{Width/2}
\const{Slope}{Height/HalfWidth}


\def\Drawer#1{%
    \pnode(0,0){O}
    \curvepnode{#1}{HalfWidth-hgap-t*height/Slope|t*height}{BR}
    \pnode[!height vgap sub dup Slope div neg exch](BR){TR}
    \nodexn{.5(O|TR)+.5(O|BR)}{C}
    \pscircle(C){3pt}
    \psline(O|BR)(BR)(TR)(O|TR)
}

\begin{document}
\const{HalfBaseWidth}{BaseWidth/2}
\begin{pspicture}(-\HalfBaseWidth,-\BaseHeight)(\HalfBaseWidth,\Height)
\LoadConstants
\multido{\i=0+1}{7}{\Drawer{\i}\psscalebox{-1 1}{\Drawer{\i}}}
\psline(-\HalfWidth,0)(0,\Height)(\HalfWidth,0)
\pspolygon(-\HalfBaseWidth,-\BaseHeight)
                    (!HalfBaseWidth neg BaseHeight Slope div add 0)
                    (!HalfBaseWidth BaseHeight Slope div sub 0)
                    (\HalfBaseWidth,-\BaseHeight)
\end{pspicture}
\end{document}

相关内容